From: Filipe Manana Date: Thu, 29 Jul 2021 17:52:46 +0000 (+0100) Subject: btrfs: avoid unnecessarily logging directories that had no changes X-Git-Tag: howlett/maple/20220722_2~2473^2~5 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=8be2ba2e0e11ade6ab96d8887dbb12abbd3540f4;p=users%2Fjedix%2Flinux-maple.git 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 Signed-off-by: David Sterba --- diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 1ce7e4480256..a1aaa1b8bd5c 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5613,6 +5613,13 @@ out_unlock: static bool need_log_inode(struct btrfs_trans_handle *trans, struct btrfs_inode *inode) { + /* + * If a directory was not modified, no dentries added or removed, we can + * and should avoid logging it. + */ + if (S_ISDIR(inode->vfs_inode.i_mode) && inode->last_trans < trans->transid) + return false; + /* * If this inode does not have new/updated/deleted xattrs since the last * time it was logged and is flagged as logged in the current transaction,