diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-04 20:22:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-04 20:22:14 -0400 |
commit | 3d0a8d10cfb4cc3d1877c29a866ee7d8a46aa2fa (patch) | |
tree | 11a85044d1472f5972ae47ce10a2f446ad981e9f /drivers/block/loop.c | |
parent | b4fdcb02f1e39c27058a885905bd0277370ba441 (diff) | |
parent | a0eda62552eba4e1f92d5354bb65c68fb6b45f87 (diff) |
Merge branch 'for-3.2/drivers' of git://git.kernel.dk/linux-block
* 'for-3.2/drivers' of git://git.kernel.dk/linux-block: (30 commits)
virtio-blk: use ida to allocate disk index
hpsa: add small delay when using PCI Power Management to reset for kump
cciss: add small delay when using PCI Power Management to reset for kump
xen/blkback: Fix two races in the handling of barrier requests.
xen/blkback: Check for proper operation.
xen/blkback: Fix the inhibition to map pages when discarding sector ranges.
xen/blkback: Report VBD_WSECT (wr_sect) properly.
xen/blkback: Support 'feature-barrier' aka old-style BARRIER requests.
xen-blkfront: plug device number leak in xlblk_init() error path
xen-blkfront: If no barrier or flush is supported, use invalid operation.
xen-blkback: use kzalloc() in favor of kmalloc()+memset()
xen-blkback: fixed indentation and comments
xen-blkfront: fix a deadlock while handling discard response
xen-blkfront: Handle discard requests.
xen-blkback: Implement discard requests ('feature-discard')
xen-blkfront: add BLKIF_OP_DISCARD and discard request struct
drivers/block/loop.c: remove unnecessary bdev argument from loop_clr_fd()
drivers/block/loop.c: emit uevent on auto release
drivers/block/cpqarray.c: use pci_dev->revision
loop: always allow userspace partitions and optionally support automatic scanning
...
Fic up trivial header file includsion conflict in drivers/block/loop.c
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r-- | drivers/block/loop.c | 111 |
1 files changed, 104 insertions, 7 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c77983ea86c8..3d806820280e 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); |
@@ -407,6 +409,29 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
407 | } | 409 | } |
408 | } | 410 | } |
409 | 411 | ||
412 | /* | ||
413 | * We use punch hole to reclaim the free space used by the | ||
414 | * image a.k.a. discard. However we do support discard if | ||
415 | * encryption is enabled, because it may give an attacker | ||
416 | * useful information. | ||
417 | */ | ||
418 | if (bio->bi_rw & REQ_DISCARD) { | ||
419 | struct file *file = lo->lo_backing_file; | ||
420 | int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; | ||
421 | |||
422 | if ((!file->f_op->fallocate) || | ||
423 | lo->lo_encrypt_key_size) { | ||
424 | ret = -EOPNOTSUPP; | ||
425 | goto out; | ||
426 | } | ||
427 | ret = file->f_op->fallocate(file, mode, pos, | ||
428 | bio->bi_size); | ||
429 | if (unlikely(ret && ret != -EINVAL && | ||
430 | ret != -EOPNOTSUPP)) | ||
431 | ret = -EIO; | ||
432 | goto out; | ||
433 | } | ||
434 | |||
410 | ret = lo_send(lo, bio, pos); | 435 | ret = lo_send(lo, bio, pos); |
411 | 436 | ||
412 | if ((bio->bi_rw & REQ_FUA) && !ret) { | 437 | if ((bio->bi_rw & REQ_FUA) && !ret) { |
@@ -622,7 +647,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, | |||
622 | goto out_putf; | 647 | goto out_putf; |
623 | 648 | ||
624 | fput(old_file); | 649 | fput(old_file); |
625 | if (max_part > 0) | 650 | if (lo->lo_flags & LO_FLAGS_PARTSCAN) |
626 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 651 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
627 | return 0; | 652 | return 0; |
628 | 653 | ||
@@ -699,16 +724,25 @@ static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf) | |||
699 | return sprintf(buf, "%s\n", autoclear ? "1" : "0"); | 724 | return sprintf(buf, "%s\n", autoclear ? "1" : "0"); |
700 | } | 725 | } |
701 | 726 | ||
727 | static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf) | ||
728 | { | ||
729 | int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN); | ||
730 | |||
731 | return sprintf(buf, "%s\n", partscan ? "1" : "0"); | ||
732 | } | ||
733 | |||
702 | LOOP_ATTR_RO(backing_file); | 734 | LOOP_ATTR_RO(backing_file); |
703 | LOOP_ATTR_RO(offset); | 735 | LOOP_ATTR_RO(offset); |
704 | LOOP_ATTR_RO(sizelimit); | 736 | LOOP_ATTR_RO(sizelimit); |
705 | LOOP_ATTR_RO(autoclear); | 737 | LOOP_ATTR_RO(autoclear); |
738 | LOOP_ATTR_RO(partscan); | ||
706 | 739 | ||
707 | static struct attribute *loop_attrs[] = { | 740 | static struct attribute *loop_attrs[] = { |
708 | &loop_attr_backing_file.attr, | 741 | &loop_attr_backing_file.attr, |
709 | &loop_attr_offset.attr, | 742 | &loop_attr_offset.attr, |
710 | &loop_attr_sizelimit.attr, | 743 | &loop_attr_sizelimit.attr, |
711 | &loop_attr_autoclear.attr, | 744 | &loop_attr_autoclear.attr, |
745 | &loop_attr_partscan.attr, | ||
712 | NULL, | 746 | NULL, |
713 | }; | 747 | }; |
714 | 748 | ||
@@ -729,6 +763,35 @@ static void loop_sysfs_exit(struct loop_device *lo) | |||
729 | &loop_attribute_group); | 763 | &loop_attribute_group); |
730 | } | 764 | } |
731 | 765 | ||
766 | static void loop_config_discard(struct loop_device *lo) | ||
767 | { | ||
768 | struct file *file = lo->lo_backing_file; | ||
769 | struct inode *inode = file->f_mapping->host; | ||
770 | struct request_queue *q = lo->lo_queue; | ||
771 | |||
772 | /* | ||
773 | * We use punch hole to reclaim the free space used by the | ||
774 | * image a.k.a. discard. However we do support discard if | ||
775 | * encryption is enabled, because it may give an attacker | ||
776 | * useful information. | ||
777 | */ | ||
778 | if ((!file->f_op->fallocate) || | ||
779 | lo->lo_encrypt_key_size) { | ||
780 | q->limits.discard_granularity = 0; | ||
781 | q->limits.discard_alignment = 0; | ||
782 | q->limits.max_discard_sectors = 0; | ||
783 | q->limits.discard_zeroes_data = 0; | ||
784 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | ||
785 | return; | ||
786 | } | ||
787 | |||
788 | q->limits.discard_granularity = inode->i_sb->s_blocksize; | ||
789 | q->limits.discard_alignment = inode->i_sb->s_blocksize; | ||
790 | q->limits.max_discard_sectors = UINT_MAX >> 9; | ||
791 | q->limits.discard_zeroes_data = 1; | ||
792 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | ||
793 | } | ||
794 | |||
732 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, | 795 | static int loop_set_fd(struct loop_device *lo, fmode_t mode, |
733 | struct block_device *bdev, unsigned int arg) | 796 | struct block_device *bdev, unsigned int arg) |
734 | { | 797 | { |
@@ -829,7 +892,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
829 | } | 892 | } |
830 | lo->lo_state = Lo_bound; | 893 | lo->lo_state = Lo_bound; |
831 | wake_up_process(lo->lo_thread); | 894 | wake_up_process(lo->lo_thread); |
832 | if (max_part > 0) | 895 | if (part_shift) |
896 | lo->lo_flags |= LO_FLAGS_PARTSCAN; | ||
897 | if (lo->lo_flags & LO_FLAGS_PARTSCAN) | ||
833 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 898 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
834 | return 0; | 899 | return 0; |
835 | 900 | ||
@@ -890,10 +955,11 @@ loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, | |||
890 | return err; | 955 | return err; |
891 | } | 956 | } |
892 | 957 | ||
893 | static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | 958 | static int loop_clr_fd(struct loop_device *lo) |
894 | { | 959 | { |
895 | struct file *filp = lo->lo_backing_file; | 960 | struct file *filp = lo->lo_backing_file; |
896 | gfp_t gfp = lo->old_gfp_mask; | 961 | gfp_t gfp = lo->old_gfp_mask; |
962 | struct block_device *bdev = lo->lo_device; | ||
897 | 963 | ||
898 | if (lo->lo_state != Lo_bound) | 964 | if (lo->lo_state != Lo_bound) |
899 | return -ENXIO; | 965 | return -ENXIO; |
@@ -922,7 +988,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
922 | lo->lo_offset = 0; | 988 | lo->lo_offset = 0; |
923 | lo->lo_sizelimit = 0; | 989 | lo->lo_sizelimit = 0; |
924 | lo->lo_encrypt_key_size = 0; | 990 | lo->lo_encrypt_key_size = 0; |
925 | lo->lo_flags = 0; | ||
926 | lo->lo_thread = NULL; | 991 | lo->lo_thread = NULL; |
927 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); | 992 | memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); |
928 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); | 993 | memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); |
@@ -940,8 +1005,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) | |||
940 | lo->lo_state = Lo_unbound; | 1005 | lo->lo_state = Lo_unbound; |
941 | /* This is safe: open() is still holding a reference. */ | 1006 | /* This is safe: open() is still holding a reference. */ |
942 | module_put(THIS_MODULE); | 1007 | module_put(THIS_MODULE); |
943 | if (max_part > 0 && bdev) | 1008 | if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev) |
944 | ioctl_by_bdev(bdev, BLKRRPART, 0); | 1009 | ioctl_by_bdev(bdev, BLKRRPART, 0); |
1010 | lo->lo_flags = 0; | ||
1011 | if (!part_shift) | ||
1012 | lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN; | ||
945 | mutex_unlock(&lo->lo_ctl_mutex); | 1013 | mutex_unlock(&lo->lo_ctl_mutex); |
946 | /* | 1014 | /* |
947 | * Need not hold lo_ctl_mutex to fput backing file. | 1015 | * Need not hold lo_ctl_mutex to fput backing file. |
@@ -995,6 +1063,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
995 | if (figure_loop_size(lo)) | 1063 | if (figure_loop_size(lo)) |
996 | return -EFBIG; | 1064 | return -EFBIG; |
997 | } | 1065 | } |
1066 | loop_config_discard(lo); | ||
998 | 1067 | ||
999 | memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); | 1068 | memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); |
1000 | memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); | 1069 | memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); |
@@ -1010,6 +1079,13 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
1010 | (info->lo_flags & LO_FLAGS_AUTOCLEAR)) | 1079 | (info->lo_flags & LO_FLAGS_AUTOCLEAR)) |
1011 | lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; | 1080 | lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; |
1012 | 1081 | ||
1082 | if ((info->lo_flags & LO_FLAGS_PARTSCAN) && | ||
1083 | !(lo->lo_flags & LO_FLAGS_PARTSCAN)) { | ||
1084 | lo->lo_flags |= LO_FLAGS_PARTSCAN; | ||
1085 | lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN; | ||
1086 | ioctl_by_bdev(lo->lo_device, BLKRRPART, 0); | ||
1087 | } | ||
1088 | |||
1013 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; | 1089 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; |
1014 | lo->lo_init[0] = info->lo_init[0]; | 1090 | lo->lo_init[0] = info->lo_init[0]; |
1015 | lo->lo_init[1] = info->lo_init[1]; | 1091 | lo->lo_init[1] = info->lo_init[1]; |
@@ -1203,7 +1279,7 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode, | |||
1203 | break; | 1279 | break; |
1204 | case LOOP_CLR_FD: | 1280 | case LOOP_CLR_FD: |
1205 | /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ | 1281 | /* loop_clr_fd would have unlocked lo_ctl_mutex on success */ |
1206 | err = loop_clr_fd(lo, bdev); | 1282 | err = loop_clr_fd(lo); |
1207 | if (!err) | 1283 | if (!err) |
1208 | goto out_unlocked; | 1284 | goto out_unlocked; |
1209 | break; | 1285 | break; |
@@ -1423,7 +1499,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) | |||
1423 | * In autoclear mode, stop the loop thread | 1499 | * In autoclear mode, stop the loop thread |
1424 | * and remove configuration after last close. | 1500 | * and remove configuration after last close. |
1425 | */ | 1501 | */ |
1426 | err = loop_clr_fd(lo, NULL); | 1502 | err = loop_clr_fd(lo); |
1427 | if (!err) | 1503 | if (!err) |
1428 | goto out_unlocked; | 1504 | goto out_unlocked; |
1429 | } else { | 1505 | } else { |
@@ -1545,6 +1621,27 @@ static int loop_add(struct loop_device **l, int i) | |||
1545 | if (!disk) | 1621 | if (!disk) |
1546 | goto out_free_queue; | 1622 | goto out_free_queue; |
1547 | 1623 | ||
1624 | /* | ||
1625 | * Disable partition scanning by default. The in-kernel partition | ||
1626 | * scanning can be requested individually per-device during its | ||
1627 | * setup. Userspace can always add and remove partitions from all | ||
1628 | * devices. The needed partition minors are allocated from the | ||
1629 | * extended minor space, the main loop device numbers will continue | ||
1630 | * to match the loop minors, regardless of the number of partitions | ||
1631 | * used. | ||
1632 | * | ||
1633 | * If max_part is given, partition scanning is globally enabled for | ||
1634 | * all loop devices. The minors for the main loop devices will be | ||
1635 | * multiples of max_part. | ||
1636 | * | ||
1637 | * Note: Global-for-all-devices, set-only-at-init, read-only module | ||
1638 | * parameteters like 'max_loop' and 'max_part' make things needlessly | ||
1639 | * complicated, are too static, inflexible and may surprise | ||
1640 | * userspace tools. Parameters like this in general should be avoided. | ||
1641 | */ | ||
1642 | if (!part_shift) | ||
1643 | disk->flags |= GENHD_FL_NO_PART_SCAN; | ||
1644 | disk->flags |= GENHD_FL_EXT_DEVT; | ||
1548 | mutex_init(&lo->lo_ctl_mutex); | 1645 | mutex_init(&lo->lo_ctl_mutex); |
1549 | lo->lo_number = i; | 1646 | lo->lo_number = i; |
1550 | lo->lo_thread = NULL; | 1647 | lo->lo_thread = NULL; |