* FAILED: patch "[PATCH] btrfs: don't skip remaining extrefs if dir not found during" failed to apply to 6.6-stable tree
@ 2025-08-18 10:48 gregkh
2025-08-19 0:14 ` [PATCH 6.6.y] btrfs: don't skip remaining extrefs if dir not found during log replay Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2025-08-18 10:48 UTC (permalink / raw)
To: fdmanana, boris, dsterba; +Cc: stable
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 24e066ded45b8147b79c7455ac43a5bff7b5f378
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2025081818-rimless-financial-6942@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 24e066ded45b8147b79c7455ac43a5bff7b5f378 Mon Sep 17 00:00:00 2001
From: Filipe Manana <fdmanana@suse.com>
Date: Fri, 11 Jul 2025 20:48:23 +0100
Subject: [PATCH] btrfs: don't skip remaining extrefs if dir not found during
log replay
During log replay, at add_inode_ref(), if we have an extref item that
contains multiple extrefs and one of them points to a directory that does
not exist in the subvolume tree, we are supposed to ignore it and process
the remaining extrefs encoded in the extref item, since each extref can
point to a different parent inode. However when that happens we just
return from the function and ignore the remaining extrefs.
The problem has been around since extrefs were introduced, in commit
f186373fef00 ("btrfs: extended inode refs"), but it's hard to hit in
practice because getting extref items encoding multiple extref requires
getting a hash collision when computing the offset of the extref's
key. The offset if computed like this:
key.offset = btrfs_extref_hash(dir_ino, name->name, name->len);
and btrfs_extref_hash() is just a wrapper around crc32c().
Fix this by moving to next iteration of the loop when we don't find
the parent directory that an extref points to.
Fixes: f186373fef00 ("btrfs: extended inode refs")
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index e3c77f3d092c..467b69a4ef3b 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1433,6 +1433,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
if (log_ref_ver) {
ret = extref_get_fields(eb, ref_ptr, &name,
&ref_index, &parent_objectid);
+ if (ret)
+ goto out;
/*
* parent object can change from one array
* item to another.
@@ -1449,16 +1451,23 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
* the loop when getting the first
* parent dir.
*/
- if (ret == -ENOENT)
+ if (ret == -ENOENT) {
+ /*
+ * The next extref may refer to
+ * another parent dir that
+ * exists, so continue.
+ */
ret = 0;
+ goto next;
+ }
goto out;
}
}
} else {
ret = ref_get_fields(eb, ref_ptr, &name, &ref_index);
+ if (ret)
+ goto out;
}
- if (ret)
- goto out;
ret = inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
ref_index, &name);
@@ -1492,10 +1501,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
}
/* Else, ret == 1, we already have a perfect match, we're done. */
+next:
ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + name.len;
kfree(name.name);
name.name = NULL;
- if (log_ref_ver) {
+ if (log_ref_ver && dir) {
iput(&dir->vfs_inode);
dir = NULL;
}
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 6.6.y] btrfs: don't skip remaining extrefs if dir not found during log replay
2025-08-18 10:48 FAILED: patch "[PATCH] btrfs: don't skip remaining extrefs if dir not found during" failed to apply to 6.6-stable tree gregkh
@ 2025-08-19 0:14 ` Sasha Levin
2025-08-22 8:41 ` Greg KH
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2025-08-19 0:14 UTC (permalink / raw)
To: stable; +Cc: Filipe Manana, Boris Burkov, David Sterba, Sasha Levin
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 24e066ded45b8147b79c7455ac43a5bff7b5f378 ]
During log replay, at add_inode_ref(), if we have an extref item that
contains multiple extrefs and one of them points to a directory that does
not exist in the subvolume tree, we are supposed to ignore it and process
the remaining extrefs encoded in the extref item, since each extref can
point to a different parent inode. However when that happens we just
return from the function and ignore the remaining extrefs.
The problem has been around since extrefs were introduced, in commit
f186373fef00 ("btrfs: extended inode refs"), but it's hard to hit in
practice because getting extref items encoding multiple extref requires
getting a hash collision when computing the offset of the extref's
key. The offset if computed like this:
key.offset = btrfs_extref_hash(dir_ino, name->name, name->len);
and btrfs_extref_hash() is just a wrapper around crc32c().
Fix this by moving to next iteration of the loop when we don't find
the parent directory that an extref points to.
Fixes: f186373fef00 ("btrfs: extended inode refs")
CC: stable@vger.kernel.org # 6.1+
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 | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 16434106c465..c5a6c782f4d9 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1445,6 +1445,8 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
if (log_ref_ver) {
ret = extref_get_fields(eb, ref_ptr, &name,
&ref_index, &parent_objectid);
+ if (ret)
+ goto out;
/*
* parent object can change from one array
* item to another.
@@ -1456,15 +1458,31 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
if (IS_ERR(btrfs_dir)) {
ret = PTR_ERR(btrfs_dir);
dir = NULL;
+ /*
+ * A new parent dir may have not been
+ * logged and not exist in the subvolume
+ * tree, see the comment above before
+ * the loop when getting the first
+ * parent dir.
+ */
+ if (ret == -ENOENT) {
+ /*
+ * The next extref may refer to
+ * another parent dir that
+ * exists, so continue.
+ */
+ ret = 0;
+ goto next;
+ }
goto out;
}
dir = &btrfs_dir->vfs_inode;
}
} else {
ret = ref_get_fields(eb, ref_ptr, &name, &ref_index);
+ if (ret)
+ goto out;
}
- if (ret)
- goto out;
ret = inode_in_dir(root, path, btrfs_ino(BTRFS_I(dir)),
btrfs_ino(BTRFS_I(inode)), ref_index, &name);
@@ -1500,10 +1518,11 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
}
/* Else, ret == 1, we already have a perfect match, we're done. */
+next:
ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + name.len;
kfree(name.name);
name.name = NULL;
- if (log_ref_ver) {
+ if (log_ref_ver && dir) {
iput(dir);
dir = NULL;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 6.6.y] btrfs: don't skip remaining extrefs if dir not found during log replay
2025-08-19 0:14 ` [PATCH 6.6.y] btrfs: don't skip remaining extrefs if dir not found during log replay Sasha Levin
@ 2025-08-22 8:41 ` Greg KH
0 siblings, 0 replies; 3+ messages in thread
From: Greg KH @ 2025-08-22 8:41 UTC (permalink / raw)
To: Sasha Levin; +Cc: stable, Filipe Manana, Boris Burkov, David Sterba
On Mon, Aug 18, 2025 at 08:14:51PM -0400, Sasha Levin wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> [ Upstream commit 24e066ded45b8147b79c7455ac43a5bff7b5f378 ]
>
> During log replay, at add_inode_ref(), if we have an extref item that
> contains multiple extrefs and one of them points to a directory that does
> not exist in the subvolume tree, we are supposed to ignore it and process
> the remaining extrefs encoded in the extref item, since each extref can
> point to a different parent inode. However when that happens we just
> return from the function and ignore the remaining extrefs.
>
> The problem has been around since extrefs were introduced, in commit
> f186373fef00 ("btrfs: extended inode refs"), but it's hard to hit in
> practice because getting extref items encoding multiple extref requires
> getting a hash collision when computing the offset of the extref's
> key. The offset if computed like this:
>
> key.offset = btrfs_extref_hash(dir_ino, name->name, name->len);
>
> and btrfs_extref_hash() is just a wrapper around crc32c().
>
> Fix this by moving to next iteration of the loop when we don't find
> the parent directory that an extref points to.
>
> Fixes: f186373fef00 ("btrfs: extended inode refs")
> CC: stable@vger.kernel.org # 6.1+
> 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 | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
This isn't applying to the 6.6.y queue right now:
patching file fs/btrfs/tree-log.c
Hunk #1 succeeded at 1446 (offset 1 line).
Hunk #2 FAILED at 1458.
Hunk #3 succeeded at 1512 (offset 10 lines).
1 out of 3 hunks FAILED -- rejects in file fs/btrfs/tree-log.c
Can you rebase and resend?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-22 8:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-18 10:48 FAILED: patch "[PATCH] btrfs: don't skip remaining extrefs if dir not found during" failed to apply to 6.6-stable tree gregkh
2025-08-19 0:14 ` [PATCH 6.6.y] btrfs: don't skip remaining extrefs if dir not found during log replay Sasha Levin
2025-08-22 8:41 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).