diff options
-rw-r--r-- | drivers/block/loop.c | 49 | ||||
-rw-r--r-- | include/linux/loop.h | 1 |
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 | ||
811 | static 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 | |||
811 | LOOP_ATTR_RO(backing_file); | 818 | LOOP_ATTR_RO(backing_file); |
812 | LOOP_ATTR_RO(offset); | 819 | LOOP_ATTR_RO(offset); |
813 | LOOP_ATTR_RO(sizelimit); | 820 | LOOP_ATTR_RO(sizelimit); |
814 | LOOP_ATTR_RO(autoclear); | 821 | LOOP_ATTR_RO(autoclear); |
822 | LOOP_ATTR_RO(partscan); | ||
815 | 823 | ||
816 | static struct attribute *loop_attrs[] = { | 824 | static 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 */ |