btrfs: avoid unnecessarily logging directories that had no changes
authorFilipe Manana <fdmanana@suse.com>
Thu, 29 Jul 2021 17:52:46 +0000 (18:52 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Aug 2021 11:19:15 +0000 (13:19 +0200)
commit8be2ba2e0e11ade6ab96d8887dbb12abbd3540f4
tree02581cd7320cd6f7dfced8d94d50d0f3723759e3
parent5b9b26f5d0b88b74001dcfe4ab8a8f2f4e744112
btrfs: avoid unnecessarily logging directories that had no changes

There are several cases where when logging an inode we need to log its
parent directories or logging subdirectories when logging a directory.

There are cases however where we end up logging a directory even if it was
not changed in the current transaction, no dentries added or removed since
the last transaction. While this is harmless from a functional point of
view, it is a waste time as it brings no advantage.

One example where this is triggered is the following:

  $ mkfs.btrfs -f /dev/sdc
  $ mount /dev/sdc /mnt

  $ mkdir /mnt/A
  $ mkdir /mnt/B
  $ mkdir /mnt/C

  $ touch /mnt/A/foo
  $ ln /mnt/A/foo /mnt/B/bar
  $ ln /mnt/A/foo /mnt/C/baz

  $ sync

  $ rm -f /mnt/A/foo
  $ xfs_io -c "fsync" /mnt/B/bar

This last fsync ends up logging directories A, B and C, however we only
need to log directory A, as B and C were not changed since the last
transaction commit.

So fix this by changing need_log_inode(), to return false in case the
given inode is a directory and has a ->last_trans value smaller than the
current transaction's ID.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/tree-log.c