aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/loop.c49
-rw-r--r--include/linux/loop.h1
2 files changed, 46 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;
diff --git a/include/linux/loop.h b/include/linux/loop.h
index 66c194e2d9b9..4367fc507fe9 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -76,6 +76,7 @@ enum {
76 LO_FLAGS_READ_ONLY = 1, 76 LO_FLAGS_READ_ONLY = 1,
77 LO_FLAGS_USE_AOPS = 2, 77 LO_FLAGS_USE_AOPS = 2,
78 LO_FLAGS_AUTOCLEAR = 4, 78 LO_FLAGS_AUTOCLEAR = 4,
79 LO_FLAGS_PARTSCAN = 8,
79}; 80};
80 81
81#include <asm/posix_types.h> /* for __kernel_old_dev_t */ 82#include <asm/posix_types.h> /* for __kernel_old_dev_t */