fs/ocfs2/xattr.c | 4 ++++ 1 file changed, 4 insertions(+)
why resend? I pasted incorrect ocfs2-tools test cases. (only modified the cover-letter; no code changes) ----- Linus and Andrew are busy, so I don't include them in the patch review phase. This patch continues Linus's job to fix the remaining issue in the reflink preserve path. The patch passed the following tests. from xfstests: ``` ./check -g quick -T -b -s ocfs2 -e generic/032 -e generic/076 \ -e generic/081 -e generic/266 -e generic/272 -e generic/281 \ -e generic/331 -e generic/338 -e generic/347 -e generic/361 \ -e generic/479 -e generic/480 -e generic/628 -e generic/629 \ -e generic/648 -e generic/650 ``` from ocfs2-test: ``` single_run-WIP.sh -f 1 -k /usr/local/ocfs2-test/tmp/linux-2.6.39.tar.gz -l /usr/local/ocfs2-test/log -m /mnt/ocfs2 -d /dev/vde -b 4096 -c 32768 -s pcmk -n hacluster -t inline,xattr,reflink discontig_runner.sh -f 1 -d /dev/vde -b 4096 -c 32768 -s pcmk -n hacluster /mnt/ocfs2 ``` special test: (reflink command is from ocfs2-tools) ``` ## this case will leave one entry after cleanup job ## create file cp /usr/bin/basename /mnt/ocfs2/a0 ## set OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS setfacl -m u:ocfs2test:rwx /mnt/ocfs2/a0 ## check, will output: "user:ocfs2test:rwx" getfacl /mnt/ocfs2/a0 ## set OCFS2_XATTR_INDEX_USER, don't trigger cleanup setfattr -n user.comment -v "tst-xattr" /mnt/ocfs2/a0 ## check, will output: "tst-xattr" getfattr -n user.comment /mnt/ocfs2/a0 ## set OCFS2_XATTR_INDEX_SECURITY setfattr -n security.selinux -v "unconfined_u:object_r:user_home_t:s0" /mnt/ocfs2/a0 ## reflink non-preserve reflink /mnt/ocfs2/a0 /mnt/ocfs2/ra0 ## reflink preserve reflink -p /mnt/ocfs2/a0 /mnt/ocfs2/ra0-p ## check getfacl /mnt/ocfs2/ra0 # "user:ocfs2test:rwx" non-exist getfacl /mnt/ocfs2/ra0-p getfattr -n user.comment /mnt/ocfs2/ra0 # "tst-xattr" exist getfattr -n user.comment /mnt/ocfs2/ra0-p getfattr -n security.selinux /mnt/ocfs2/ra0 # no security attr item getfattr -n security.selinux /mnt/ocfs2/ra0-p ## this case will trigger cleaning up all array entries. ## create file. then set file with OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS and ## OCFS2_XATTR_INDEX_SECURITY cp /usr/bin/basename /mnt/ocfs2/b0 setfacl -m u:ocfs2test:rwx /mnt/ocfs2/b0 setfattr -n security.selinux -v "unconfined_u:object_r:user_home_t:s0" /mnt/ocfs2/b0 ## reflink non-preserve reflink /mnt/ocfs2/b0 /mnt/ocfs2/rb0 ## reflink preserve reflink -p /mnt/ocfs2/b0 /mnt/ocfs2/rb0-p ## check getfacl /mnt/ocfs2/rb0 # "user:ocfs2test:rwx" non-exist getfacl /mnt/ocfs2/rb0-p getfattr -n security.selinux /mnt/ocfs2/rb0 # no security attr item getfattr -n security.selinux /mnt/ocfs2/rb0-p ``` Heming Zhao (1): ocfs2: fix reflink preserve cleanup issue fs/ocfs2/xattr.c | 4 ++++ 1 file changed, 4 insertions(+) -- 2.43.0
ping... On Wed, Dec 10, 2025 at 09:57:23AM +0800, Heming Zhao wrote: > why resend? > I pasted incorrect ocfs2-tools test cases. > (only modified the cover-letter; no code changes) > ----- > > Linus and Andrew are busy, so I don't include them in the patch review phase. > This patch continues Linus's job to fix the remaining issue in the reflink > preserve path. > > The patch passed the following tests. > > from xfstests: > > ``` > ./check -g quick -T -b -s ocfs2 -e generic/032 -e generic/076 \ > -e generic/081 -e generic/266 -e generic/272 -e generic/281 \ > -e generic/331 -e generic/338 -e generic/347 -e generic/361 \ > -e generic/479 -e generic/480 -e generic/628 -e generic/629 \ > -e generic/648 -e generic/650 > ``` > > > from ocfs2-test: > > ``` > single_run-WIP.sh -f 1 -k /usr/local/ocfs2-test/tmp/linux-2.6.39.tar.gz -l /usr/local/ocfs2-test/log -m /mnt/ocfs2 -d /dev/vde -b 4096 -c 32768 -s pcmk -n hacluster -t inline,xattr,reflink > > discontig_runner.sh -f 1 -d /dev/vde -b 4096 -c 32768 -s pcmk -n hacluster /mnt/ocfs2 > ``` > > special test: > (reflink command is from ocfs2-tools) > > ``` > ## this case will leave one entry after cleanup job > ## create file > cp /usr/bin/basename /mnt/ocfs2/a0 > ## set OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS > setfacl -m u:ocfs2test:rwx /mnt/ocfs2/a0 > ## check, will output: "user:ocfs2test:rwx" > getfacl /mnt/ocfs2/a0 > ## set OCFS2_XATTR_INDEX_USER, don't trigger cleanup > setfattr -n user.comment -v "tst-xattr" /mnt/ocfs2/a0 > ## check, will output: "tst-xattr" > getfattr -n user.comment /mnt/ocfs2/a0 > ## set OCFS2_XATTR_INDEX_SECURITY > setfattr -n security.selinux -v "unconfined_u:object_r:user_home_t:s0" /mnt/ocfs2/a0 > ## reflink non-preserve > reflink /mnt/ocfs2/a0 /mnt/ocfs2/ra0 > ## reflink preserve > reflink -p /mnt/ocfs2/a0 /mnt/ocfs2/ra0-p > ## check > getfacl /mnt/ocfs2/ra0 # "user:ocfs2test:rwx" non-exist > getfacl /mnt/ocfs2/ra0-p > getfattr -n user.comment /mnt/ocfs2/ra0 # "tst-xattr" exist > getfattr -n user.comment /mnt/ocfs2/ra0-p > getfattr -n security.selinux /mnt/ocfs2/ra0 # no security attr item > getfattr -n security.selinux /mnt/ocfs2/ra0-p > > > ## this case will trigger cleaning up all array entries. > ## create file. then set file with OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS and > ## OCFS2_XATTR_INDEX_SECURITY > cp /usr/bin/basename /mnt/ocfs2/b0 > setfacl -m u:ocfs2test:rwx /mnt/ocfs2/b0 > setfattr -n security.selinux -v "unconfined_u:object_r:user_home_t:s0" /mnt/ocfs2/b0 > ## reflink non-preserve > reflink /mnt/ocfs2/b0 /mnt/ocfs2/rb0 > ## reflink preserve > reflink -p /mnt/ocfs2/b0 /mnt/ocfs2/rb0-p > ## check > getfacl /mnt/ocfs2/rb0 # "user:ocfs2test:rwx" non-exist > getfacl /mnt/ocfs2/rb0-p > getfattr -n security.selinux /mnt/ocfs2/rb0 # no security attr item > getfattr -n security.selinux /mnt/ocfs2/rb0-p > ``` > > > Heming Zhao (1): > ocfs2: fix reflink preserve cleanup issue > > fs/ocfs2/xattr.c | 4 ++++ > 1 file changed, 4 insertions(+) > > -- > 2.43.0 >
On Thu, 18 Dec 2025 22:42:12 +0800 Heming Zhao <heming.zhao@suse.com> wrote:
> ping...
>
yes please ;) Some review input would be reassuring, thanks.
btw, I forgot to ask: what are the worst-case userspace-visible runtime
effects of this bug?
IOW, is a -stable backport desirable?
From: Heming Zhao <heming.zhao@suse.com>
Subject: ocfs2: fix reflink preserve cleanup issue
Date: Wed, 10 Dec 2025 09:57:24 +0800
commit c06c303832ec ("ocfs2: fix xattr array entry __counted_by error")
doesn't handle all cases and the cleanup job for preserved xattr entries
still has bug:
- the 'last' pointer should be shifted by one unit after cleanup
an array entry.
- current code logic doesn't cleanup the first entry when xh_count is 1.
Note, commit c06c303832ec is also a bug fix for 0fe9b66c65f3.
Link: https://lkml.kernel.org/r/20251210015725.8409-2-heming.zhao@suse.com
Fixes: 0fe9b66c65f3 ("ocfs2: Add preserve to reflink.")
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
fs/ocfs2/xattr.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/fs/ocfs2/xattr.c~ocfs2-fix-reflink-preserve-cleanup-issue
+++ a/fs/ocfs2/xattr.c
@@ -6395,6 +6395,10 @@ static int ocfs2_reflink_xattr_header(ha
(void *)last - (void *)xe);
memset(last, 0,
sizeof(struct ocfs2_xattr_entry));
+ last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)] - 1;
+ } else {
+ memset(xe, 0, sizeof(struct ocfs2_xattr_entry));
+ last = NULL;
}
/*
_
On Mon, Jan 19, 2026 at 03:53:53PM -0800, Andrew Morton wrote:
> On Thu, 18 Dec 2025 22:42:12 +0800 Heming Zhao <heming.zhao@suse.com> wrote:
>
> > ping...
> >
>
> yes please ;) Some review input would be reassuring, thanks.
>
> btw, I forgot to ask: what are the worst-case userspace-visible runtime
> effects of this bug?
The worst-case scenario was fixed in commit c06c303832ec ('ocfs2: fix xattr array
entry __counted_by error'). It resolved an out-of-bounds (OOB) issue that could
have caused the kernel to crash.
In patch commit log, there are two issues:
1> the 'last' pointer should be shifted by one unit after cleanup
an array entry.
2> current code logic doesn't cleanup the first entry when xh_count is 1.
The following points should be noted:
Regarding <1>: after commit c06c303832ec, the last pointer doesn't shift. The
code always clears the last array element.
Regarding <2>: Since the existing code correctly updates new_xh->xh_count, the
xattrs can still be displayed correctly (shown as empty) even if the first entry
is not cleared, as the logic relies on the count.
>
> IOW, is a -stable backport desirable?
Yes
- Heming
>
>
> From: Heming Zhao <heming.zhao@suse.com>
> Subject: ocfs2: fix reflink preserve cleanup issue
> Date: Wed, 10 Dec 2025 09:57:24 +0800
>
> commit c06c303832ec ("ocfs2: fix xattr array entry __counted_by error")
> doesn't handle all cases and the cleanup job for preserved xattr entries
> still has bug:
> - the 'last' pointer should be shifted by one unit after cleanup
> an array entry.
> - current code logic doesn't cleanup the first entry when xh_count is 1.
>
> Note, commit c06c303832ec is also a bug fix for 0fe9b66c65f3.
>
> Link: https://lkml.kernel.org/r/20251210015725.8409-2-heming.zhao@suse.com
> Fixes: 0fe9b66c65f3 ("ocfs2: Add preserve to reflink.")
> Signed-off-by: Heming Zhao <heming.zhao@suse.com>
> Cc: Mark Fasheh <mark@fasheh.com>
> Cc: Joel Becker <jlbec@evilplan.org>
> Cc: Junxiao Bi <junxiao.bi@oracle.com>
> Cc: Joseph Qi <jiangqi903@gmail.com>
> Cc: Changwei Ge <gechangwei@live.cn>
> Cc: Jun Piao <piaojun@huawei.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
>
> fs/ocfs2/xattr.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> --- a/fs/ocfs2/xattr.c~ocfs2-fix-reflink-preserve-cleanup-issue
> +++ a/fs/ocfs2/xattr.c
> @@ -6395,6 +6395,10 @@ static int ocfs2_reflink_xattr_header(ha
> (void *)last - (void *)xe);
> memset(last, 0,
> sizeof(struct ocfs2_xattr_entry));
> + last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)] - 1;
> + } else {
> + memset(xe, 0, sizeof(struct ocfs2_xattr_entry));
> + last = NULL;
> }
>
> /*
> _
>
© 2016 - 2026 Red Hat, Inc.