aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@gmail.com>2011-05-24 10:48:55 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-05-24 10:48:55 -0400
commita1c15c59feee36267c43142a41152fbf7402afb6 (patch)
tree39f6db8cd34379207c1d5666e009ec2131774111
parent78f4bb367fd147a0e7e3998ba6e47109999d8814 (diff)
loop: handle on-demand devices correctly
When finding or allocating a loop device, loop_probe() did not take partition numbers into account so that it can result to a different device. Consider following example: $ sudo modprobe loop max_part=15 $ ls -l /dev/loop* brw-rw---- 1 root disk 7, 0 2011-05-24 22:16 /dev/loop0 brw-rw---- 1 root disk 7, 16 2011-05-24 22:16 /dev/loop1 brw-rw---- 1 root disk 7, 32 2011-05-24 22:16 /dev/loop2 brw-rw---- 1 root disk 7, 48 2011-05-24 22:16 /dev/loop3 brw-rw---- 1 root disk 7, 64 2011-05-24 22:16 /dev/loop4 brw-rw---- 1 root disk 7, 80 2011-05-24 22:16 /dev/loop5 brw-rw---- 1 root disk 7, 96 2011-05-24 22:16 /dev/loop6 brw-rw---- 1 root disk 7, 112 2011-05-24 22:16 /dev/loop7 $ sudo mknod /dev/loop8 b 7 128 $ sudo losetup /dev/loop8 ~/temp/disk-with-3-parts.img $ sudo losetup -a /dev/loop128: [0805]:278201 (/home/namhyung/temp/disk-with-3-parts.img) $ ls -l /dev/loop* brw-rw---- 1 root disk 7, 0 2011-05-24 22:16 /dev/loop0 brw-rw---- 1 root disk 7, 16 2011-05-24 22:16 /dev/loop1 brw-rw---- 1 root disk 7, 2048 2011-05-24 22:18 /dev/loop128 brw-rw---- 1 root disk 7, 2049 2011-05-24 22:18 /dev/loop128p1 brw-rw---- 1 root disk 7, 2050 2011-05-24 22:18 /dev/loop128p2 brw-rw---- 1 root disk 7, 2051 2011-05-24 22:18 /dev/loop128p3 brw-rw---- 1 root disk 7, 32 2011-05-24 22:16 /dev/loop2 brw-rw---- 1 root disk 7, 48 2011-05-24 22:16 /dev/loop3 brw-rw---- 1 root disk 7, 64 2011-05-24 22:16 /dev/loop4 brw-rw---- 1 root disk 7, 80 2011-05-24 22:16 /dev/loop5 brw-rw---- 1 root disk 7, 96 2011-05-24 22:16 /dev/loop6 brw-rw---- 1 root disk 7, 112 2011-05-24 22:16 /dev/loop7 brw-r--r-- 1 root root 7, 128 2011-05-24 22:17 /dev/loop8 After this patch, /dev/loop8 - instead of /dev/loop128 - was accessed correctly. In addition, 'range' passed to blk_register_region() should include all range of dev_t that LOOP_MAJOR can address. It does not need to be limited by partition numbers unless 'max_loop' param was specified. Signed-off-by: Namhyung Kim <namhyung@gmail.com> Cc: Laurent Vivier <Laurent.Vivier@bull.net> Cc: stable@kernel.org Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--drivers/block/loop.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index cbf7052d1dd5..c59a672a3de0 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1658,7 +1658,7 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data)
1658 struct kobject *kobj; 1658 struct kobject *kobj;
1659 1659
1660 mutex_lock(&loop_devices_mutex); 1660 mutex_lock(&loop_devices_mutex);
1661 lo = loop_init_one(dev & MINORMASK); 1661 lo = loop_init_one(MINOR(dev) >> part_shift);
1662 kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM); 1662 kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM);
1663 mutex_unlock(&loop_devices_mutex); 1663 mutex_unlock(&loop_devices_mutex);
1664 1664
@@ -1699,10 +1699,10 @@ static int __init loop_init(void)
1699 1699
1700 if (max_loop) { 1700 if (max_loop) {
1701 nr = max_loop; 1701 nr = max_loop;
1702 range = max_loop; 1702 range = max_loop << part_shift;
1703 } else { 1703 } else {
1704 nr = 8; 1704 nr = 8;
1705 range = 1UL << (MINORBITS - part_shift); 1705 range = 1UL << MINORBITS;
1706 } 1706 }
1707 1707
1708 if (register_blkdev(LOOP_MAJOR, "loop")) 1708 if (register_blkdev(LOOP_MAJOR, "loop"))
@@ -1741,7 +1741,7 @@ static void __exit loop_exit(void)
1741 unsigned long range; 1741 unsigned long range;
1742 struct loop_device *lo, *next; 1742 struct loop_device *lo, *next;
1743 1743
1744 range = max_loop ? max_loop : 1UL << (MINORBITS - part_shift); 1744 range = max_loop ? max_loop << part_shift : 1UL << MINORBITS;
1745 1745
1746 list_for_each_entry_safe(lo, next, &loop_devices, lo_list) 1746 list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
1747 loop_del_one(lo); 1747 loop_del_one(lo);