diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 12 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 17 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 2 |
3 files changed, 29 insertions, 2 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 66bac226944e..059dfa048cc0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1782,6 +1782,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1782 | 1782 | ||
1783 | 1783 | ||
1784 | for (i = 0; i < multi->num_stripes; i++, stripe++) { | 1784 | for (i = 0; i < multi->num_stripes; i++, stripe++) { |
1785 | if (!stripe->dev->can_discard) | ||
1786 | continue; | ||
1787 | |||
1785 | ret = btrfs_issue_discard(stripe->dev->bdev, | 1788 | ret = btrfs_issue_discard(stripe->dev->bdev, |
1786 | stripe->physical, | 1789 | stripe->physical, |
1787 | stripe->length); | 1790 | stripe->length); |
@@ -1789,11 +1792,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1789 | discarded_bytes += stripe->length; | 1792 | discarded_bytes += stripe->length; |
1790 | else if (ret != -EOPNOTSUPP) | 1793 | else if (ret != -EOPNOTSUPP) |
1791 | break; | 1794 | break; |
1795 | |||
1796 | /* | ||
1797 | * Just in case we get back EOPNOTSUPP for some reason, | ||
1798 | * just ignore the return value so we don't screw up | ||
1799 | * people calling discard_extent. | ||
1800 | */ | ||
1801 | ret = 0; | ||
1792 | } | 1802 | } |
1793 | kfree(multi); | 1803 | kfree(multi); |
1794 | } | 1804 | } |
1795 | if (discarded_bytes && ret == -EOPNOTSUPP) | ||
1796 | ret = 0; | ||
1797 | 1805 | ||
1798 | if (actual_bytes) | 1806 | if (actual_bytes) |
1799 | *actual_bytes = discarded_bytes; | 1807 | *actual_bytes = discarded_bytes; |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 3c5f2fcd82c1..a595f8775c37 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -517,6 +517,9 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
517 | fs_devices->rw_devices--; | 517 | fs_devices->rw_devices--; |
518 | } | 518 | } |
519 | 519 | ||
520 | if (device->can_discard) | ||
521 | fs_devices->num_can_discard--; | ||
522 | |||
520 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); | 523 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); |
521 | BUG_ON(!new_device); | 524 | BUG_ON(!new_device); |
522 | memcpy(new_device, device, sizeof(*new_device)); | 525 | memcpy(new_device, device, sizeof(*new_device)); |
@@ -525,6 +528,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
525 | new_device->bdev = NULL; | 528 | new_device->bdev = NULL; |
526 | new_device->writeable = 0; | 529 | new_device->writeable = 0; |
527 | new_device->in_fs_metadata = 0; | 530 | new_device->in_fs_metadata = 0; |
531 | new_device->can_discard = 0; | ||
528 | list_replace_rcu(&device->dev_list, &new_device->dev_list); | 532 | list_replace_rcu(&device->dev_list, &new_device->dev_list); |
529 | 533 | ||
530 | call_rcu(&device->rcu, free_device); | 534 | call_rcu(&device->rcu, free_device); |
@@ -564,6 +568,7 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
564 | static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | 568 | static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
565 | fmode_t flags, void *holder) | 569 | fmode_t flags, void *holder) |
566 | { | 570 | { |
571 | struct request_queue *q; | ||
567 | struct block_device *bdev; | 572 | struct block_device *bdev; |
568 | struct list_head *head = &fs_devices->devices; | 573 | struct list_head *head = &fs_devices->devices; |
569 | struct btrfs_device *device; | 574 | struct btrfs_device *device; |
@@ -620,6 +625,12 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
620 | seeding = 0; | 625 | seeding = 0; |
621 | } | 626 | } |
622 | 627 | ||
628 | q = bdev_get_queue(bdev); | ||
629 | if (blk_queue_discard(q)) { | ||
630 | device->can_discard = 1; | ||
631 | fs_devices->num_can_discard++; | ||
632 | } | ||
633 | |||
623 | device->bdev = bdev; | 634 | device->bdev = bdev; |
624 | device->in_fs_metadata = 0; | 635 | device->in_fs_metadata = 0; |
625 | device->mode = flags; | 636 | device->mode = flags; |
@@ -1560,6 +1571,7 @@ error: | |||
1560 | 1571 | ||
1561 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | 1572 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
1562 | { | 1573 | { |
1574 | struct request_queue *q; | ||
1563 | struct btrfs_trans_handle *trans; | 1575 | struct btrfs_trans_handle *trans; |
1564 | struct btrfs_device *device; | 1576 | struct btrfs_device *device; |
1565 | struct block_device *bdev; | 1577 | struct block_device *bdev; |
@@ -1629,6 +1641,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1629 | 1641 | ||
1630 | lock_chunks(root); | 1642 | lock_chunks(root); |
1631 | 1643 | ||
1644 | q = bdev_get_queue(bdev); | ||
1645 | if (blk_queue_discard(q)) | ||
1646 | device->can_discard = 1; | ||
1632 | device->writeable = 1; | 1647 | device->writeable = 1; |
1633 | device->work.func = pending_bios_fn; | 1648 | device->work.func = pending_bios_fn; |
1634 | generate_random_uuid(device->uuid); | 1649 | generate_random_uuid(device->uuid); |
@@ -1664,6 +1679,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1664 | root->fs_info->fs_devices->num_devices++; | 1679 | root->fs_info->fs_devices->num_devices++; |
1665 | root->fs_info->fs_devices->open_devices++; | 1680 | root->fs_info->fs_devices->open_devices++; |
1666 | root->fs_info->fs_devices->rw_devices++; | 1681 | root->fs_info->fs_devices->rw_devices++; |
1682 | if (device->can_discard) | ||
1683 | root->fs_info->fs_devices->num_can_discard++; | ||
1667 | root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; | 1684 | root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; |
1668 | 1685 | ||
1669 | if (!blk_queue_nonrot(bdev_get_queue(bdev))) | 1686 | if (!blk_queue_nonrot(bdev_get_queue(bdev))) |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 7c12d61ae7ae..6d866db4e177 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -48,6 +48,7 @@ struct btrfs_device { | |||
48 | int writeable; | 48 | int writeable; |
49 | int in_fs_metadata; | 49 | int in_fs_metadata; |
50 | int missing; | 50 | int missing; |
51 | int can_discard; | ||
51 | 52 | ||
52 | spinlock_t io_lock; | 53 | spinlock_t io_lock; |
53 | 54 | ||
@@ -104,6 +105,7 @@ struct btrfs_fs_devices { | |||
104 | u64 rw_devices; | 105 | u64 rw_devices; |
105 | u64 missing_devices; | 106 | u64 missing_devices; |
106 | u64 total_rw_bytes; | 107 | u64 total_rw_bytes; |
108 | u64 num_can_discard; | ||
107 | struct block_device *latest_bdev; | 109 | struct block_device *latest_bdev; |
108 | 110 | ||
109 | /* all of the devices in the FS, protected by a mutex | 111 | /* all of the devices in the FS, protected by a mutex |