| From b43c276ae508477a120ead98cc7781b7a17ed8b1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 3 Dec 2025 17:02:00 +0000 |
| Subject: btrfs: do not skip logging new dentries when logging a new name |
| |
| From: Filipe Manana <fdmanana@suse.com> |
| |
| [ Upstream commit 5630f7557de61264ccb4f031d4734a1a97eaed16 ] |
| |
| When we are logging a directory and the log context indicates that we |
| are logging a new name for some other file (that is or was inside that |
| directory), we skip logging the inodes for new dentries in the directory. |
| |
| This is ok most of the time, but if after the rename or link operation |
| that triggered the logging of that directory, we have an explicit fsync |
| of that directory without the directory inode being evicted and reloaded, |
| we end up never logging the inodes for the new dentries that we found |
| during the new name logging, as the next directory fsync will only process |
| dentries that were added after the last time we logged the directory (we |
| are doing an incremental directory logging). |
| |
| So make sure we always log new dentries for a directory even if we are |
| in a context of logging a new name. |
| |
| We started skipping logging inodes for new dentries as of commit |
| c48792c6ee7a ("btrfs: do not log new dentries when logging that a new name |
| exists") and it was fine back then, because when logging a directory we |
| always iterated over all the directory entries (for leaves changed in the |
| current transaction) so a subsequent fsync would always log anything that |
| was previously skipped while logging a directory when logging a new name |
| (with btrfs_log_new_name()). But later support for incrementally logging |
| a directory was added in commit dc2872247ec0 ("btrfs: keep track of the |
| last logged keys when logging a directory"), to avoid checking all dir |
| items every time we log a directory, so the check to skip dentry logging |
| added in the first commit should have been removed when the incremental |
| support for logging a directory was added. |
| |
| A test case for fstests will follow soon. |
| |
| Reported-by: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@gmail.com> |
| Link: https://lore.kernel.org/linux-btrfs/84c4e713-85d6-42b9-8dcf-0722ed26cb05@gmail.com/ |
| Fixes: dc2872247ec0 ("btrfs: keep track of the last logged keys when logging a directory") |
| Reviewed-by: Boris Burkov <boris@bur.io> |
| Signed-off-by: Filipe Manana <fdmanana@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/btrfs/tree-log.c | 8 -------- |
| 1 file changed, 8 deletions(-) |
| |
| diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c |
| index 30f3c3b849c14..f55d886debe2f 100644 |
| --- a/fs/btrfs/tree-log.c |
| +++ b/fs/btrfs/tree-log.c |
| @@ -5872,14 +5872,6 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, |
| struct btrfs_inode *curr_inode = start_inode; |
| int ret = 0; |
| |
| - /* |
| - * If we are logging a new name, as part of a link or rename operation, |
| - * don't bother logging new dentries, as we just want to log the names |
| - * of an inode and that any new parents exist. |
| - */ |
| - if (ctx->logging_new_name) |
| - return 0; |
| - |
| path = btrfs_alloc_path(); |
| if (!path) |
| return -ENOMEM; |
| -- |
| 2.51.0 |
| |