static LIST_HEAD(loop_devices);
 static DEFINE_MUTEX(loop_devices_mutex);
 
+static int max_part;
+static int part_shift;
+
 /*
  * Transfer functions
  */
                goto out_putf;
 
        fput(old_file);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 
  out_putf:
        }
        lo->lo_state = Lo_bound;
        wake_up_process(lo->lo_thread);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 
 out_clr:
        fput(filp);
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
+       if (max_part > 0)
+               ioctl_by_bdev(bdev, BLKRRPART, 0);
        return 0;
 }
 
 static int max_loop;
 module_param(max_loop, int, 0);
 MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
+module_param(max_part, int, 0);
+MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
 
        if (!lo->lo_queue)
                goto out_free_dev;
 
-       disk = lo->lo_disk = alloc_disk(1);
+       disk = lo->lo_disk = alloc_disk(1 << part_shift);
        if (!disk)
                goto out_free_queue;
 
        init_waitqueue_head(&lo->lo_event);
        spin_lock_init(&lo->lo_lock);
        disk->major             = LOOP_MAJOR;
-       disk->first_minor       = i;
+       disk->first_minor       = i << part_shift;
        disk->fops              = &lo_fops;
        disk->private_data      = lo;
        disk->queue             = lo->lo_queue;
         *     themselves and have kernel automatically instantiate actual
         *     device on-demand.
         */
-       if (max_loop > 1UL << MINORBITS)
+
+       part_shift = 0;
+       if (max_part > 0)
+               part_shift = fls(max_part);
+
+       if (max_loop > 1UL << (MINORBITS - part_shift))
                return -EINVAL;
 
        if (max_loop) {
                range = max_loop;
        } else {
                nr = 8;
-               range = 1UL << MINORBITS;
+               range = 1UL << (MINORBITS - part_shift);
        }
 
        if (register_blkdev(LOOP_MAJOR, "loop"))
        unsigned long range;
        struct loop_device *lo, *next;
 
-       range = max_loop ? max_loop :  1UL << MINORBITS;
+       range = max_loop ? max_loop :  1UL << (MINORBITS - part_shift);
 
        list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
                loop_del_one(lo);