]> git.hungrycats.org Git - linux/commitdiff
Btrfs: don't attach unnecessary extents to transaction on fsync
authorFilipe Manana <fdmanana@suse.com>
Fri, 17 Apr 2015 16:08:37 +0000 (17:08 +0100)
committerZygo Blaxell <zblaxell@thirteen.furryterror.org>
Fri, 28 Aug 2015 04:12:06 +0000 (00:12 -0400)
We don't need to attach ordered extents that have completed to the current
transaction. Doing so only makes us hold memory for longer than necessary
and delaying the iput of the inode until the transaction is committed (for
each created ordered extent we do an igrab and then schedule an asynchronous
iput when the ordered extent's reference count drops to 0), preventing the
inode from being evictable until the transaction commits.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Chris Mason <clm@fb.com>
(cherry picked from commit 7558c8bc17481c1f856e009af8503ab40fec348a)
(cherry picked from commit a6ed4350c4edb474c582d560b0b4bf00f40be6b1)

fs/btrfs/ordered-data.c

index 250dc7a67a84e6ef57c0948c1850168a3ebf6fb1..1982e55bfe84c5fe203801dde042e250859f48d4 100644 (file)
@@ -509,7 +509,21 @@ void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
                wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE,
                                                   &ordered->flags));
 
-               list_add_tail(&ordered->trans_list, &trans->ordered);
+               /*
+                * If our ordered extent completed it means it updated the
+                * fs/subvol and csum trees already, so no need to make the
+                * current transaction's commit wait for it, as we end up
+                * holding memory unnecessarily and delaying the inode's iput
+                * until the transaction commit (we schedule an iput for the
+                * inode when the ordered extent's refcount drops to 0), which
+                * prevents it from being evictable until the transaction
+                * commits.
+                */
+               if (test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags))
+                       btrfs_put_ordered_extent(ordered);
+               else
+                       list_add_tail(&ordered->trans_list, &trans->ordered);
+
                spin_lock_irq(&log->log_extents_lock[index]);
        }
        spin_unlock_irq(&log->log_extents_lock[index]);