aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/extent-tree.c12
-rw-r--r--fs/btrfs/volumes.c17
-rw-r--r--fs/btrfs/volumes.h2
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)
564static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, 568static 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
1561int btrfs_init_new_device(struct btrfs_root *root, char *device_path) 1572int 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