aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2011-08-23 14:12:04 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-08-23 14:12:04 -0400
commite03c8dd14915fabc101aa495828d58598dc5af98 (patch)
tree8aba1d519848c3f7684ac5673c95f56aa6ff1d57 /drivers/block/loop.c
parente8b177cedc39b092e423b8cbc687dbf096a1de47 (diff)
loop: always allow userspace partitions and optionally support automatic scanning
Automatic partition scanning can be requested individually per loop device during its setup by setting LO_FLAGS_PARTSCAN. By default, no partition tables are scanned. Userspace can now always add and remove partitions from all loop devices, regardless if the in-kernel partition scanner is enabled or not. The needed partition minor numbers are allocated from the extended minors space, the main loop device numbers will continue to match the loop minors, regardless of the number of partitions used. # grep . /sys/class/block/loop1/loop/* /sys/block/loop1/loop/autoclear:0 /sys/block/loop1/loop/backing_file:/home/kay/data/stuff/part.img /sys/block/loop1/loop/offset:0 /sys/block/loop1/loop/partscan:1 /sys/block/loop1/loop/sizelimit:0 # ls -l /dev/loop* brw-rw---- 1 root disk 7, 0 Aug 14 20:22 /dev/loop0 brw-rw---- 1 root disk 7, 1 Aug 14 20:23 /dev/loop1 brw-rw---- 1 root disk 259, 0 Aug 14 20:23 /dev/loop1p1 brw-rw---- 1 root disk 259, 1 Aug 14 20:23 /dev/loop1p2 brw-rw---- 1 root disk 7, 99 Aug 14 20:23 /dev/loop99 brw-rw---- 1 root disk 259, 2 Aug 14 20:23 /dev/loop99p1 brw-rw---- 1 root disk 259, 3 Aug 14 20:23 /dev/loop99p2 crw------T 1 root root 10, 237 Aug 14 20:22 /dev/loop-control Cc: Karel Zak <kzak@redhat.com> Cc: Davidlohr Bueso <dave@gnu.org> Acked-By: Tejun Heo <tj@kernel.org> Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 936cac3c3126..b336433f8157 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -724,7 +724,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
724 goto out_putf; 724 goto out_putf;
725 725
726 fput(old_file); 726 fput(old_file);
727 if (max_part > 0) 727 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
728 ioctl_by_bdev(bdev, BLKRRPART, 0); 728 ioctl_by_bdev(bdev, BLKRRPART, 0);
729 return 0; 729 return 0;
730 730
@@ -808,16 +808,25 @@ static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf)
808 return sprintf(buf, "%s\n", autoclear ? "1" : "0"); 808 return sprintf(buf, "%s\n", autoclear ? "1" : "0");
809} 809}
810 810
811static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf)
812{
813 int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN);
814
815 return sprintf(buf, "%s\n", partscan ? "1" : "0");
816}
817
811LOOP_ATTR_RO(backing_file); 818LOOP_ATTR_RO(backing_file);
812LOOP_ATTR_RO(offset); 819LOOP_ATTR_RO(offset);
813LOOP_ATTR_RO(sizelimit); 820LOOP_ATTR_RO(sizelimit);
814LOOP_ATTR_RO(autoclear); 821LOOP_ATTR_RO(autoclear);
822LOOP_ATTR_RO(partscan);
815 823
816static struct attribute *loop_attrs[] = { 824static struct attribute *loop_attrs[] = {
817 &loop_attr_backing_file.attr, 825 &loop_attr_backing_file.attr,
818 &loop_attr_offset.attr, 826 &loop_attr_offset.attr,
819 &loop_attr_sizelimit.attr, 827 &loop_attr_sizelimit.attr,
820 &loop_attr_autoclear.attr, 828 &loop_attr_autoclear.attr,
829 &loop_attr_partscan.attr,
821 NULL, 830 NULL,
822}; 831};
823 832
@@ -979,7 +988,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
979 } 988 }
980 lo->lo_state = Lo_bound; 989 lo->lo_state = Lo_bound;
981 wake_up_process(lo->lo_thread); 990 wake_up_process(lo->lo_thread);
982 if (max_part > 0) 991 if (part_shift)
992 lo->lo_flags |= LO_FLAGS_PARTSCAN;
993 if (lo->lo_flags & LO_FLAGS_PARTSCAN)
983 ioctl_by_bdev(bdev, BLKRRPART, 0); 994 ioctl_by_bdev(bdev, BLKRRPART, 0);
984 return 0; 995 return 0;
985 996
@@ -1070,7 +1081,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
1070 lo->lo_offset = 0; 1081 lo->lo_offset = 0;
1071 lo->lo_sizelimit = 0; 1082 lo->lo_sizelimit = 0;
1072 lo->lo_encrypt_key_size = 0; 1083 lo->lo_encrypt_key_size = 0;
1073 lo->lo_flags = 0;
1074 lo->lo_thread = NULL; 1084 lo->lo_thread = NULL;
1075 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); 1085 memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);
1076 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); 1086 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
@@ -1088,8 +1098,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
1088 lo->lo_state = Lo_unbound; 1098 lo->lo_state = Lo_unbound;
1089 /* This is safe: open() is still holding a reference. */ 1099 /* This is safe: open() is still holding a reference. */
1090 module_put(THIS_MODULE); 1100 module_put(THIS_MODULE);
1091 if (max_part > 0 && bdev) 1101 if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
1092 ioctl_by_bdev(bdev, BLKRRPART, 0); 1102 ioctl_by_bdev(bdev, BLKRRPART, 0);
1103 lo->lo_flags = 0;
1104 if (!part_shift)
1105 lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
1093 mutex_unlock(&lo->lo_ctl_mutex); 1106 mutex_unlock(&lo->lo_ctl_mutex);
1094 /* 1107 /*
1095 * Need not hold lo_ctl_mutex to fput backing file. 1108 * Need not hold lo_ctl_mutex to fput backing file.
@@ -1159,6 +1172,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
1159 (info->lo_flags & LO_FLAGS_AUTOCLEAR)) 1172 (info->lo_flags & LO_FLAGS_AUTOCLEAR))
1160 lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; 1173 lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
1161 1174
1175 if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
1176 !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
1177 lo->lo_flags |= LO_FLAGS_PARTSCAN;
1178 lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
1179 ioctl_by_bdev(lo->lo_device, BLKRRPART, 0);
1180 }
1181
1162 lo->lo_encrypt_key_size = info->lo_encrypt_key_size; 1182 lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
1163 lo->lo_init[0] = info->lo_init[0]; 1183 lo->lo_init[0] = info->lo_init[0];
1164 lo->lo_init[1] = info->lo_init[1]; 1184 lo->lo_init[1] = info->lo_init[1];
@@ -1654,6 +1674,27 @@ static struct loop_device *loop_alloc(int i)
1654 if (!disk) 1674 if (!disk)
1655 goto out_free_queue; 1675 goto out_free_queue;
1656 1676
1677 /*
1678 * Disable partition scanning by default. The in-kernel partition
1679 * scanning can be requested individually per-device during its
1680 * setup. Userspace can always add and remove partitions from all
1681 * devices. The needed partition minors are allocated from the
1682 * extended minor space, the main loop device numbers will continue
1683 * to match the loop minors, regardless of the number of partitions
1684 * used.
1685 *
1686 * If max_part is given, partition scanning is globally enabled for
1687 * all loop devices. The minors for the main loop devices will be
1688 * multiples of max_part.
1689 *
1690 * Note: Global-for-all-devices, set-only-at-init, read-only module
1691 * parameteters like 'max_loop' and 'max_part' make things needlessly
1692 * complicated, are too static, inflexible and may surprise
1693 * userspace tools. Parameters like this in general should be avoided.
1694 */
1695 if (!part_shift)
1696 disk->flags |= GENHD_FL_NO_PART_SCAN;
1697 disk->flags |= GENHD_FL_EXT_DEVT;
1657 mutex_init(&lo->lo_ctl_mutex); 1698 mutex_init(&lo->lo_ctl_mutex);
1658 lo->lo_number = i; 1699 lo->lo_number = i;
1659 lo->lo_thread = NULL; 1700 lo->lo_thread = NULL;