diff options
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 298 |
1 files changed, 160 insertions, 138 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 4720c7ade0a..68b205a9338 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -76,6 +76,8 @@ | |||
76 | #include <linux/splice.h> | 76 | #include <linux/splice.h> |
77 | #include <linux/sysfs.h> | 77 | #include <linux/sysfs.h> |
78 | #include <linux/miscdevice.h> | 78 | #include <linux/miscdevice.h> |
79 | #include <linux/falloc.h> | ||
80 | |||
79 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
80 | 82 | ||
81 | static DEFINE_IDR(loop_index_idr); | 83 | static DEFINE_IDR(loop_index_idr); |
@@ -159,17 +161,19 @@ static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { | |||
159 | &xor_funcs | 161 | &xor_funcs |
160 | }; | 162 | }; |
161 | 163 | ||
162 | static loff_t get_loop_size(struct loop_device *lo, struct file *file) | 164 | static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file) |
163 | { | 165 | { |
164 | loff_t size, offset, loopsize; | 166 | loff_t size, loopsize; |
165 | 167 | ||
166 | /* Compute loopsize in bytes */ | 168 | /* Compute loopsize in bytes */ |
167 | size = i_size_read(file->f_mapping->host); | 169 | size = i_size_read(file->f_mapping->host); |
168 | offset = lo->lo_offset; | ||
169 | loopsize = size - offset; | 170 | loopsize = size - offset; |
170 | if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) | 171 | /* offset is beyond i_size, wierd but possible */ |
171 | loopsize = lo->lo_sizelimit; | 172 | if (loopsize < 0) |
173 | return 0; | ||
172 | 174 | ||
175 | if (sizelimit > 0 && sizelimit < loopsize) | ||
176 | loopsize = sizelimit; | ||
173 | /* | 177 | /* |
174 | * Unfortunately, if we want to do I/O on the device, | 178 | * Unfortunately, if we want to do I/O on the device, |
175 | * the number of 512-byte sectors has to fit into a sector_t. | 179 | * the number of 512-byte sectors has to fit into a sector_t. |
@@ -177,17 +181,25 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file) | |||
177 | return loopsize >> 9; | 181 | return loopsize >> 9; |
178 | } | 182 | } |
179 | 183 | ||
184 | static loff_t get_loop_size(struct loop_device *lo, struct file *file) | ||
185 | { | ||
186 | return get_size(lo->lo_offset, lo->lo_sizelimit, file); | ||
187 | } | ||
188 | |||
180 | static int | 189 | static int |
181 | figure_loop_size(struct loop_device *lo) | 190 | figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) |
182 | { | 191 | { |
183 | loff_t size = get_loop_size(lo, lo->lo_backing_file); | 192 | loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); |
184 | sector_t x = (sector_t)size; | 193 | sector_t x = (sector_t)size; |
185 | 194 | ||
186 | if (unlikely((loff_t)x != size)) | 195 | if (unlikely((loff_t)x != size)) |
187 | return -EFBIG; | 196 | return -EFBIG; |
188 | 197 | if (lo->lo_offset != offset) | |
198 | lo->lo_offset = offset; | ||
199 | if (lo->lo_sizelimit != sizelimit) | ||
200 | lo->lo_sizelimit = sizelimit; | ||
189 | set_capacity(lo->lo_disk, x); | 201 | set_capacity(lo->lo_disk, x); |
190 | return 0; | 202 | return 0; |
191 | } | 203 | } |
192 | 204 | ||
193 | static inline int | 205 | static inline int |
@@ -203,74 +215,6 @@ lo_do_transfer(struct loop_device *lo, int cmd, | |||
203 | } | 215 | } |
204 | 216 | ||
205 | /** | 217 | /** |
206 | * do_lo_send_aops - helper for writing data to a loop device | ||
207 | * | ||
208 | * This is the fast version for backing filesystems which implement the address | ||
209 | * space operations write_begin and write_end. | ||
210 | */ | ||
211 | static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, | ||
212 | loff_t pos, struct page *unused) | ||
213 | { | ||
214 | struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ | ||
215 | struct address_space *mapping = file->f_mapping; | ||
216 | pgoff_t index; | ||
217 | unsigned offset, bv_offs; | ||
218 | int len, ret; | ||
219 | |||
220 | mutex_lock(&mapping->host->i_mutex); | ||
221 | index = pos >> PAGE_CACHE_SHIFT; | ||
222 | offset = pos & ((pgoff_t)PAGE_CACHE_SIZE - 1); | ||
223 | bv_offs = bvec->bv_offset; | ||
224 | len = bvec->bv_len; | ||
225 | while (len > 0) { | ||
226 | sector_t IV; | ||
227 | unsigned size, copied; | ||
228 | int transfer_result; | ||
229 | struct page *page; | ||
230 | void *fsdata; | ||
231 | |||
232 | IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); | ||
233 | size = PAGE_CACHE_SIZE - offset; | ||
234 | if (size > len) | ||
235 | size = len; | ||
236 | |||
237 | ret = pagecache_write_begin(file, mapping, pos, size, 0, | ||
238 | &page, &fsdata); | ||
239 | if (ret) | ||
240 | goto fail; | ||
241 | |||
242 | file_update_time(file); | ||
243 | |||
244 | transfer_result = lo_do_transfer(lo, WRITE, page, offset, | ||
245 | bvec->bv_page, bv_offs, size, IV); | ||
246 | copied = size; | ||
247 | if (unlikely(transfer_result)) | ||
248 | copied = 0; | ||
249 | |||
250 | ret = pagecache_write_end(file, mapping, pos, size, copied, | ||
251 | page, fsdata); | ||
252 | if (ret < 0 || ret != copied) | ||
253 | goto fail; | ||
254 | |||
255 | if (unlikely(transfer_result)) | ||
256 | goto fail; | ||
257 | |||
258 | bv_offs += copied; | ||
259 | len -= copied; | ||
260 | offset = 0; | ||
261 | index++; | ||
262 | pos += copied; | ||
263 | } | ||
264 | ret = 0; | ||
265 | out: | ||
266 | mutex_unlock(&mapping->host->i_mutex); | ||
267 | return ret; | ||
268 | fail: | ||
269 | ret = -1; | ||
270 | goto out; | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * __do_lo_send_write - helper for writing data to a loop device | 218 | * __do_lo_send_write - helper for writing data to a loop device |
275 | * | 219 | * |
276 | * This helper just factors out common code between do_lo_send_direct_write() | 220 | * This helper just factors out common code between do_lo_send_direct_write() |
@@ -297,10 +241,8 @@ static int __do_lo_send_write(struct file *file, | |||
297 | /** | 241 | /** |
298 | * do_lo_send_direct_write - helper for writing data to a loop device | 242 | * do_lo_send_direct_write - helper for writing data to a loop device |
299 | * | 243 | * |
300 | * This is the fast, non-transforming version for backing filesystems which do | 244 | * This is the fast, non-transforming version that does not need double |
301 | * not implement the address space operations write_begin and write_end. | 245 | * buffering. |
302 | * It uses the write file operation which should be present on all writeable | ||
303 | * filesystems. | ||
304 | */ | 246 | */ |
305 | static int do_lo_send_direct_write(struct loop_device *lo, | 247 | static int do_lo_send_direct_write(struct loop_device *lo, |
306 | struct bio_vec *bvec, loff_t pos, struct page *page) | 248 | struct bio_vec *bvec, loff_t pos, struct page *page) |
@@ -316,15 +258,9 @@ static int do_lo_send_direct_write(struct loop_device *lo, | |||
316 | /** | 258 | /** |
317 | * do_lo_send_write - helper for writing data to a loop device | 259 | * do_lo_send_write - helper for writing data to a loop device |
318 | * | 260 | * |
319 | * This is the slow, transforming version for filesystems which do not | 261 | * This is the slow, transforming version that needs to double buffer the |
320 | * implement the address space operations write_begin and write_end. It | 262 | * data as it cannot do the transformations in place without having direct |
321 | * uses the write file operation which should be present on all writeable | 263 | * access to the destination pages of the backing file. |
322 | * filesystems. | ||
323 | * | ||
324 | * Using fops->write is slower than using aops->{prepare,commit}_write in the | ||
325 | * transforming case because we need to double buffer the data as we cannot do | ||
326 | * the transformations in place as we do not have direct access to the | ||
327 | * destination pages of the backing file. | ||
328 | */ | 264 | */ |
329 | static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, | 265 | static int do_lo_send_write(struct loop_device *lo, struct bio_vec *bvec, |
330 | loff_t pos, struct page *page) | 266 | loff_t pos, struct page *page) |
@@ -350,17 +286,16 @@ static int lo_send(struct loop_device *lo, struct bio *bio, loff_t pos) | |||
350 | struct page *page = NULL; | 286 | struct page *page = NULL; |
351 | int i, ret = 0; | 287 | int i, ret = 0; |
352 | 288 | ||
353 | do_lo_send = do_lo_send_aops; | 289 | if (lo->transfer != transfer_none) { |
354 | if (!(lo->lo_flags & LO_FLAGS_USE_AOPS)) { | 290 | page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); |
291 | if (unlikely(!page)) | ||
292 | goto fail; | ||
293 | kmap(page); | ||
294 | do_lo_send = do_lo_send_write; | ||
295 | } else { | ||
355 | do_lo_send = do_lo_send_direct_write; | 296 | do_lo_send = do_lo_send_direct_write; |
356 | if (lo->transfer != transfer_none) { | ||
357 | page = alloc_page(GFP_NOIO | __GFP_HIGHMEM); | ||
358 | if (unlikely(!page)) | ||
359 | goto fail; | ||
360 | kmap(page); | ||
361 | do_lo_send = do_lo_send_write; | ||
362 | } | ||
363 | } | 297 | } |
298 | |||
364 | bio_for_each_segment(bvec, bio, i) { | 299 | bio_for_each_segment(bvec, bio, i) { |
365 | ret = do_lo_send(lo, bvec, pos, page); | 300 | ret = do_lo_send(lo, bvec, pos, page); |
366 | if (ret < 0) | 301 | if (ret < 0) |
@@ -447,7 +382,8 @@ do_lo_receive(struct loop_device *lo, | |||
447 | 382 | ||
448 | if (retval < 0) | 383 | if (retval < 0) |
449 | return retval; | 384 | return retval; |
450 | 385 | if (retval != bvec->bv_len) | |
386 | return -EIO; | ||
451 | return 0; | 387 | return 0; |
452 | } | 388 | } |
453 | 389 | ||
@@ -484,6 +420,29 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
484 | } | 420 | } |
485 | } | 421 | } |
486 | 422 | ||
423 | /* | ||
424 | * We use punch hole to reclaim the free space used by the | ||
425 | * image a.k.a. discard. However we do support discard if | ||
426 | * encryption is enabled, because it may give an attacker | ||
427 | * useful information. | ||
428 | */ | ||
429 | if (bio->bi_rw & REQ_DISCARD) { | ||
430 | struct file *file = lo->lo_backing_file; | ||
431 | int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; | ||
432 | |||
433 | if ((!file->f_op->fallocate) || | ||
434 | lo->lo_encrypt_key_size) { | ||
435 | ret = -EOPNOTSUPP; | ||
436 | goto out; | ||
437 | } | ||
438 | ret = file->f_op->fallocate(file, mode, pos, | ||
439 | bio->bi_size); | ||
440 | if (unlikely(ret && ret != -EINVAL && | ||
441 | ret != -EOPNOTSUPP)) | ||
442 | ret = -EIO; | ||
443 | goto out; | ||
444 | } | ||
445 | |||
487 | ret = lo_send(lo, bio, pos); | 446 | ret = lo_send(lo, bio, pos); |
488 | 447 | ||
489 | if ((bio->bi_rw & REQ_FUA) && !ret) { | 448 | if ((bio->bi_rw & REQ_FUA) && !ret) { |
@@ -514,7 +473,7 @@ static struct bio *loop_get_bio(struct loop_device *lo) | |||
514 | return bio_list_pop(&lo->lo_bio_list); | 473 | return bio_list_pop(&lo->lo_bio_list); |
515 | } | 474 | } |
516 | 475 | ||
517 | static int loop_make_request(struct request_queue *q, struct bio *old_bio) | 476 | static void loop_make_request(struct request_queue *q, struct bio *old_bio) |
518 | { | 477 | { |
519 | struct loop_device *lo = q->queuedata; | 478 | struct loop_device *lo = q->queuedata; |
520 | int rw = bio_rw(old_bio); | 479 | int rw = bio_rw(old_bio); |
@@ -532,12 +491,11 @@ static int loop_make_request(struct request_queue *q, struct bio *old_bio) | |||
532 | loop_add_bio(lo, old_bio); | 491 | loop_add_bio(lo, old_bio); |
533 | wake_up(&lo->lo_event); | 492 | wake_up(&lo->lo_event); |
534 | spin_unlock_irq(&lo->lo_lock); | 493 | spin_unlock_irq(&lo->lo_lock); |
535 | return 0; | 494 | return; |
536 | 495 | ||
537 | out: | 496 | out: |
538 | spin_unlock_irq(&lo->lo_lock); | 497 | spin_unlock_irq(&lo->lo_lock); |
539 | bio_io_error(old_bio); | 498 | bio_io_error(old_bio); |
540 | return 0; | ||
541 | } | 499 | } |
542 | 500 | ||
543 | struct switch_request { | 501 | struct switch_request { |
@@ -700,7 +658,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, | |||
700 | goto out_putf; | 658 | goto out_putf; |
701 | 659 | ||
702 | fput(old_file); | 660 | fput(old_file); |
703 | if (max_part > 0) | 661 | if (lo->lo_flags & LO_FLAGS_PARTSCAN) |
704 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 662 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
705 | return 0; | 663 | return 0; |
706 | 664 | ||
@@ -777,16 +735,25 @@ static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf) | |||
777 | return sprintf(buf, "%s\n", autoclear ? "1" : "0"); | 735 | return sprintf(buf, "%s\n", autoclear ? "1" : "0"); |
778 | } | 736 | } |
779 | 737 | ||
738 | static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf) | ||
739 | { | ||
740 | int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN); | ||
741 | |||
742 | return sprintf(buf, "%s\n", partscan ? "1" : "0"); | ||
743 | } | ||
744 | |||
780 | LOOP_ATTR_RO(backing_file); | 745 | LOOP_ATTR_RO(backing_file); |
781 | LOOP_ATTR_RO(offset); | 746 | LOOP_ATTR_RO(offset); |
782 | LOOP_ATTR_RO(sizelimit); | 747 | LOOP_ATTR_RO(sizelimit); |
783 | LOOP_ATTR_RO(autoclear); | 748 | LOOP_ATTR_RO(autoclear); |
749 | LOOP_ATTR_RO(partscan); | ||
784 | 750 | ||
785 | static struct attribute *loop_attrs[] = { | 751 | static struct attribute *loop_attrs[] = { |
786 | &loop_attr_backing_file.attr, | 752 | &loop_attr_backing_file.attr, |
787 | &loop_attr_offset.attr, | 753 | &loop_attr_offset.attr, |
788 | &loop_attr_sizelimit.attr, | 754 | &loop_attr_sizelimit.attr, |
789 | &loop_attr_autoclear.attr, | 755 | &loop_attr_autoclear.attr, |
756 | &loop_attr_partscan.attr, | ||
790 | NULL, | 757 | NULL, |
791 | }; | 758 | }; |
792 | 759 | ||
@@ -807,6 +774,35 @@ static void loop_sysfs_exit(struct loop_device *lo) | |||
807 | &loop_attribute_group); | 774 | &loop_attribute_group); |
808 | } | 775 | } |
809 | 776 | ||
777 | static void loop_config_discard(struct loop_device *lo) | ||
778 | { | ||
779 | struct file *file = lo->lo_backing_file; | ||
780 | struct inode *inode = file->f_mapping->host; | ||
781 | struct request_queue *q = lo->lo_queue; | ||
782 | |||
783 | /* | ||
784 | * We use punch hole to reclaim the free space used by the | ||
785 | * image a.k.a. discard. However we do support discard if | ||
786 | * encryption is enabled, because it may give an attacker | ||
787 | * useful information. | ||
788 | */ | ||
789 | if ((!file->f_op->fallocate) || | ||
790 | lo->lo_encrypt_key_size) { | ||
791 | q->limits.discard_granularity = 0; | ||
792 | q->limits.discard_alignment = 0; | ||
793 | q->limits.max_discard_sectors = 0; | ||
794 | q->limits.discard_zeroes_data = 0; | ||
795 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | ||
796 | return; | ||
797 | } | ||
798 | |||
799 | q->limits.discard_granularity = inode->i_sb->s_blocksize; | ||
800 | q->limits.discard_alignment = inode->i_sb->s_blocksize; | ||
801 | q->limits.max_discard_sectors = UINT_MAX >> 9; | ||
802 | q->limits.discard_zeroes_data = 1; | ||
803 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
804 | } | ||
805 | |||
810 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, | 806 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, |
811 | struct block_device *bdev, unsigned int arg) | 807 | struct block_device *bdev, unsigned int arg) |
812 | { | 808 | { |
@@ -849,35 +845,23 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
849 | mapping = file->f_mapping; | 845 | mapping = file->f_mapping; |
850 | inode = mapping->host; | 846 | inode = mapping->host; |
851 | 847 | ||
852 | if (!(file->f_mode & FMODE_WRITE)) | ||
853 | lo_flags |= LO_FLAGS_READ_ONLY; | ||
854 | |||
855 | error = -EINVAL; | 848 | error = -EINVAL; |
856 | if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { | 849 | if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) |
857 | const struct address_space_operations *aops = mapping->a_ops; | 850 | goto out_putf; |
858 | |||
859 | if (aops->write_begin) | ||
860 | lo_flags |= LO_FLAGS_USE_AOPS; | ||
861 | if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) | ||
862 | lo_flags |= LO_FLAGS_READ_ONLY; | ||
863 | 851 | ||
864 | lo_blocksize = S_ISBLK(inode->i_mode) ? | 852 | if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || |
865 | inode->i_bdev->bd_block_size : PAGE_SIZE; | 853 | !file->f_op->write) |
854 | lo_flags |= LO_FLAGS_READ_ONLY; | ||
866 | 855 | ||
867 | error = 0; | 856 | lo_blocksize = S_ISBLK(inode->i_mode) ? |
868 | } else { | 857 | inode->i_bdev->bd_block_size : PAGE_SIZE; |
869 | goto out_putf; | ||
870 | } | ||
871 | 858 | ||
859 | error = -EFBIG; | ||
872 | size = get_loop_size(lo, file); | 860 | size = get_loop_size(lo, file); |
873 | 861 | if ((loff_t)(sector_t)size != size) | |
874 | if ((loff_t)(sector_t)size != size) { | ||
875 | error = -EFBIG; | ||
876 | goto out_putf; | 862 | goto out_putf; |
877 | } | ||
878 | 863 | ||
879 | if (!(mode & FMODE_WRITE)) | 864 | error = 0; |
880 | lo_flags |= LO_FLAGS_READ_ONLY; | ||
881 | 865 | ||
882 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); | 866 | set_device_ro(bdev, (lo_flags & LO_FLAGS_READ_ONLY) != 0); |
883 | 867 | ||
@@ -919,7 +903,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
919 | } | 903 | } |
920 | lo->lo_state = Lo_bound; | 904 | lo->lo_state = Lo_bound; |
921 | wake_up_process(lo->lo_thread); | 905 | wake_up_process(lo->lo_thread); |
922 | if (max_part > 0) | 906 | if (part_shift) |
907 | lo->lo_flags |= LO_FLAGS_PARTSCAN; | ||
908 | if (lo->lo_flags & LO_FLAGS_PARTSCAN) | ||
923 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 909 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
924 | return 0; | 910 | return 0; |
925 | 911 | ||
@@ -980,10 +966,11 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, | |||
980 | return err; | 966 | return err; |
981 | } | 967 | } |
982 | 968 | ||
983 | static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | 969 | static int loop_clr_fd(struct loop_device *lo) |
984 | { | 970 | { |
985 | struct file *filp = lo->lo_backing_file; | 971 | struct file *filp = lo->lo_backing_file; |
986 | gfp_t gfp = lo->old_gfp_mask; | 972 | gfp_t gfp = lo->old_gfp_mask; |
973 | struct block_device *bdev = lo->lo_device; | ||
987 | 974 | ||
988 | if (lo->lo_state != Lo_bound) | 975 | if (lo->lo_state != Lo_bound) |
989 | return -ENXIO; | 976 | return -ENXIO; |
@@ -1012,7 +999,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
1012 | lo->lo_offset = 0; | 999 | lo->lo_offset = 0; |
1013 | lo->lo_sizelimit = 0; | 1000 | lo->lo_sizelimit = 0; |
1014 | lo->lo_encrypt_key_size = 0; | 1001 | lo->lo_encrypt_key_size = 0; |
1015 | lo->lo_flags = 0; | ||
1016 | lo->lo_thread = NULL; | 1002 | lo->lo_thread = NULL; |
1017 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); | 1003 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
1018 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 1004 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
@@ -1030,8 +1016,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
1030 | lo->lo_state = Lo_unbound; | 1016 | lo->lo_state = Lo_unbound; |
1031 | /* This is safe: open() is still holding a reference. */ | 1017 | /* This is safe: open() is still holding a reference. */ |
1032 | module_put(THIS_MODULE); | 1018 | module_put(THIS_MODULE); |
1033 | if (max_part > 0 && bdev) | 1019 | if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) |
1034 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 1020 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
1021 | lo->lo_flags = 0; | ||
1022 | if (!part_shift) | ||
1023 | lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; | ||
1035 | mutex_unlock(&lo->lo_ctl_mutex); | 1024 | mutex_unlock(&lo->lo_ctl_mutex); |
1036 | /* | 1025 | /* |
1037 | * Need not hold lo_ctl_mutex to fput backing file. | 1026 | * Need not hold lo_ctl_mutex to fput backing file. |
@@ -1080,11 +1069,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
1080 | 1069 | ||
1081 | if (lo->lo_offset != info->lo_offset || | 1070 | if (lo->lo_offset != info->lo_offset || |
1082 | lo->lo_sizelimit != info->lo_sizelimit) { | 1071 | lo->lo_sizelimit != info->lo_sizelimit) { |
1083 | lo->lo_offset = info->lo_offset; | 1072 | if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) |
1084 | lo->lo_sizelimit = info->lo_sizelimit; | ||
1085 | if (figure_loop_size(lo)) | ||
1086 | return -EFBIG; | 1073 | return -EFBIG; |
1087 | } | 1074 | } |
1075 | loop_config_discard(lo); | ||
1088 | 1076 | ||
1089 | memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); | 1077 | memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); |
1090 | memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); | 1078 | memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); |
@@ -1100,6 +1088,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
1100 | (info->lo_flags & LO_FLAGS_AUTOCLEAR)) | 1088 | (info->lo_flags & LO_FLAGS_AUTOCLEAR)) |
1101 | lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; | 1089 | lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; |
1102 | 1090 | ||
1091 | if ((info->lo_flags & LO_FLAGS_PARTSCAN) && | ||
1092 | !(lo->lo_flags & LO_FLAGS_PARTSCAN)) { | ||
1093 | lo->lo_flags |= LO_FLAGS_PARTSCAN; | ||
1094 | lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; | ||
1095 | ioctl_by_bdev(lo->lo_device, BLKRRPART, 0); | ||
1096 | } | ||
1097 | |||
1103 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; | 1098 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; |
1104 | lo->lo_init[0] = info->lo_init[0]; | 1099 | lo->lo_init[0] = info->lo_init[0]; |
1105 | lo->lo_init[1] = info->lo_init[1]; | 1100 | lo->lo_init[1] = info->lo_init[1]; |
@@ -1260,7 +1255,7 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) | |||
1260 | err = -ENXIO; | 1255 | err = -ENXIO; |
1261 | if (unlikely(lo->lo_state != Lo_bound)) | 1256 | if (unlikely(lo->lo_state != Lo_bound)) |
1262 | goto out; | 1257 | goto out; |
1263 | err = figure_loop_size(lo); | 1258 | err = figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); |
1264 | if (unlikely(err)) | 1259 | if (unlikely(err)) |
1265 | goto out; | 1260 | goto out; |
1266 | sec = get_capacity(lo->lo_disk); | 1261 | sec = get_capacity(lo->lo_disk); |
@@ -1293,18 +1288,24 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, | |||
1293 | break; | 1288 | break; |
1294 | case LOOP_CLR_FD: | 1289 | case LOOP_CLR_FD: |
1295 | /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ | 1290 | /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ |
1296 | err = loop_clr_fd(lo, bdev); | 1291 | err = loop_clr_fd(lo); |
1297 | if (!err) | 1292 | if (!err) |
1298 | goto out_unlocked; | 1293 | goto out_unlocked; |
1299 | break; | 1294 | break; |
1300 | case LOOP_SET_STATUS: | 1295 | case LOOP_SET_STATUS: |
1301 | err = loop_set_status_old(lo, (struct loop_info __user *) arg); | 1296 | err = -EPERM; |
1297 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | ||
1298 | err = loop_set_status_old(lo, | ||
1299 | (struct loop_info __user *)arg); | ||
1302 | break; | 1300 | break; |
1303 | case LOOP_GET_STATUS: | 1301 | case LOOP_GET_STATUS: |
1304 | err = loop_get_status_old(lo, (struct loop_info __user *) arg); | 1302 | err = loop_get_status_old(lo, (struct loop_info __user *) arg); |
1305 | break; | 1303 | break; |
1306 | case LOOP_SET_STATUS64: | 1304 | case LOOP_SET_STATUS64: |
1307 | err = loop_set_status64(lo, (struct loop_info64 __user *) arg); | 1305 | err = -EPERM; |
1306 | if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN)) | ||
1307 | err = loop_set_status64(lo, | ||
1308 | (struct loop_info64 __user *) arg); | ||
1308 | break; | 1309 | break; |
1309 | case LOOP_GET_STATUS64: | 1310 | case LOOP_GET_STATUS64: |
1310 | err = loop_get_status64(lo, (struct loop_info64 __user *) arg); | 1311 | err = loop_get_status64(lo, (struct loop_info64 __user *) arg); |
@@ -1513,7 +1514,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) | |||
1513 | * In autoclear mode, stop the loop thread | 1514 | * In autoclear mode, stop the loop thread |
1514 | * and remove configuration after last close. | 1515 | * and remove configuration after last close. |
1515 | */ | 1516 | */ |
1516 | err = loop_clr_fd(lo, NULL); | 1517 | err = loop_clr_fd(lo); |
1517 | if (!err) | 1518 | if (!err) |
1518 | goto out_unlocked; | 1519 | goto out_unlocked; |
1519 | } else { | 1520 | } else { |
@@ -1635,6 +1636,27 @@ static int loop_add(struct loop_device **l, int i) | |||
1635 | if (!disk) | 1636 | if (!disk) |
1636 | goto out_free_queue; | 1637 | goto out_free_queue; |
1637 | 1638 | ||
1639 | /* | ||
1640 | * Disable partition scanning by default. The in-kernel partition | ||
1641 | * scanning can be requested individually per-device during its | ||
1642 | * setup. Userspace can always add and remove partitions from all | ||
1643 | * devices. The needed partition minors are allocated from the | ||
1644 | * extended minor space, the main loop device numbers will continue | ||
1645 | * to match the loop minors, regardless of the number of partitions | ||
1646 | * used. | ||
1647 | * | ||
1648 | * If max_part is given, partition scanning is globally enabled for | ||
1649 | * all loop devices. The minors for the main loop devices will be | ||
1650 | * multiples of max_part. | ||
1651 | * | ||
1652 | * Note: Global-for-all-devices, set-only-at-init, read-only module | ||
1653 | * parameteters like 'max_loop' and 'max_part' make things needlessly | ||
1654 | * complicated, are too static, inflexible and may surprise | ||
1655 | * userspace tools. Parameters like this in general should be avoided. | ||
1656 | */ | ||
1657 | if (!part_shift) | ||
1658 | disk->flags |= GENHD_FL_NO_PART_SCAN; | ||
1659 | disk->flags |= GENHD_FL_EXT_DEVT; | ||
1638 | mutex_init(&lo->lo_ctl_mutex); | 1660 | mutex_init(&lo->lo_ctl_mutex); |
1639 | lo->lo_number = i; | 1661 | lo->lo_number = i; |
1640 | lo->lo_thread = NULL; | 1662 | lo->lo_thread = NULL; |