]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
btrfs: Don't discard unwritten extents
authorNikolay Borisov <nborisov@suse.com>
Thu, 21 Nov 2019 12:03:29 +0000 (14:03 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 20 Jan 2020 15:40:50 +0000 (16:40 +0100)
All callers of btrfs_free_reserved_extent (respectively
__btrfs_free_reserved_extent with in set to 0) pass in extents which
have only been reserved but not yet written to. Namely,

* in cow_file_range that function is called only if create_io_em fails
  or btrfs_add_ordered_extent fail, both of which happen _before_ any IO
  is submitted to the newly reserved range

* in submit_compressed_extents the code flow is similar -
  out_free_reserve can be called only before
  btrfs_submit_compressed_write which is where any writes to the range
  could occur

* btrfs_new_extent_direct also calls btrfs_free_reserved_extent only
  if extent_map fails, before any IO is issued

* __btrfs_prealloc_file_range also calls btrfs_free_reserved_extent
  in case insertion of the metadata fails

* btrfs_alloc_tree_block again can only be called in case in-memory
  operations fail, before any IO is submitted

* btrfs_finish_ordered_io - this is the only caller where discarding
  the extent could have a material effect, since it can be called for
  an extent which was partially written.

With this change the submission of discards is optimised since discards
are now not being created for extents which are known to not have been
touched on disk.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c
fs/btrfs/inode.c

index 274318e9114eee4cdd95108d6fb309c16fdd4678..3495710c72b82a2a3780afd0b31709db05b859b4 100644 (file)
@@ -4182,8 +4182,6 @@ static int __btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info,
        if (pin)
                pin_down_extent(cache, start, len, 1);
        else {
-               if (btrfs_test_opt(fs_info, DISCARD))
-                       ret = btrfs_discard_extent(fs_info, start, len, NULL);
                btrfs_add_free_space(cache, start, len);
                btrfs_free_reserved_bytes(cache, len, delalloc);
                trace_btrfs_reserved_extent_free(fs_info, start, len);
index c70baafb2a3920ced47005c3d60b11c07c89af88..c1cee6a01c35a828606281251df7879da4a3dc3d 100644 (file)
@@ -3250,10 +3250,19 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
                if ((ret || !logical_len) &&
                    clear_reserved_extent &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) &&
-                   !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags))
+                   !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
+                       /*
+                        * Discard the range before returning it back to the
+                        * free space pool
+                        */
+                       if (ret && btrfs_test_opt(fs_info, DISCARD))
+                               btrfs_discard_extent(fs_info,
+                                               ordered_extent->start,
+                                               ordered_extent->disk_len, NULL);
                        btrfs_free_reserved_extent(fs_info,
                                                   ordered_extent->start,
                                                   ordered_extent->disk_len, 1);
+               }
        }