From: hehuiwen <huiwen.he@linux.dev>
To: Steve French <smfrench@gmail.com>
Cc: linkinjeon@kernel.org, pc@manguebit.org,
ronniesahlberg@gmail.com, sprasad@microsoft.com, tom@talpey.com,
bharathsm@microsoft.com, dhowells@redhat.com, metze@samba.org,
chenxiaosong@kylinos.cn, linux-cifs@vger.kernel.org,
Sergey Senozhatsky <senozhatsky@chromium.org>
Subject: Re: [PATCH v6 1/5] smb/client: refresh allocation size after duplicate extents
Date: Thu, 2 Jul 2026 23:20:30 +0800 [thread overview]
Message-ID: <da8a7d66-a97c-4d81-8e92-20a810fd2dde@linux.dev> (raw)
In-Reply-To: <CAH2r5mudB4xBQnPvuSZo5SiYkRn0UEs9YZi9rbUGBh3G3GBqZg@mail.gmail.com>
Hi Steve,
Yes, patch 1 adds one extra roundtrip after each successful
duplicate-extents request.
I think that query is needed if we want i_blocks to be correct
immediately after the server-side clone. The client only knows the byte
range that was cloned. It does not know how many blocks the server
actually allocated for that range, especially when the cloned range
contains holes.
I agree this may affect workloads that use cp/reflink heavily, but it is
still one metadata query per successful server-side clone, not extra
work in the SMB2_READ/SMB2_WRITE path. So I think the cost is acceptable
for the correctness fix.
I found that the v6 version could cause duplicate revalidation after
the AllocationSize refresh. I updated patch 1 in v7 to keep the
QueryInfo result valid in the inode cache, so a following stat does not
immediately query the same attributes again.
I also updated patch 3 based on Shashiko's comment. Small fallocate
ranges at or beyond EOF are now zero-written directly instead of first
querying
FSCTL_QUERY_ALLOCATED_RANGES.
Thanks,
Huiwen
在 2026/7/2 05:47, Steve French 写道:
> This does lead to an extra roundtrip (common operations like cp will
> use duplicate extents in some Samba and Windows server
> configurations). Any worries about performance hit?
>
> On Wed, Jul 1, 2026 at 10:22 AM Huiwen He <huiwen.he@linux.dev> wrote:
>>
>> From: Huiwen He <hehuiwen@kylinos.cn>
>>
>> FSCTL_DUPLICATE_EXTENTS_TO_FILE changes the target file extents on the
>> server, but the client does not refresh the target AllocationSize/i_blocks.
>> Callers can observe or use the wrong st_blocks value immediately after the
>> clone, before a later attribute revalidation corrects it.
>>
>> For example, create a reflinked file with a leading hole:
>>
>> xfs_io -f -c "pwrite -S 0x61 0 64k" src
>> touch dst
>> chmod 600 dst
>> xfs_io -c "reflink src 0 1m 64k" dst
>> mkswap dst
>> swapon dst
>>
>> The file still has a hole after mkswap:
>>
>> /mnt/scratch/dst:
>> [0..7]: allocated
>> [8..2047]: hole
>> [2048..2175]: allocated
>>
>> The server also reports only the allocated ranges:
>>
>> server dst size=1114112 blocks=144
>>
>> but the client reported EOF-derived blocks:
>>
>> client dst size=1114112 blocks=2176
>>
>> and swapon succeeded:
>>
>> swapon_result=success
>> /mnt/scratch/dst 1.1M 0B -1
>>
>> So EOF-derived i_blocks can let a sparse reflinked file pass the CIFS
>> swapfile hole check.
>>
>> Fix this by querying FILE_ALL_INFORMATION on the target handle after a
>> successful duplicate extents request and updating i_blocks from the
>> returned AllocationSize. If the query fails, invalidate the cached
>> inode attributes so a later getattr can refresh them.
>>
>> This also fixes the xfstests generic/370 regression introduced by the
>> i_blocks accounting change, as tested on a Samba "vfs objects = btrfs"
>> share.
>>
>> Fixes: 99cd0a6eeb6c ("smb/client: do not account EOF extension as allocation")
>> Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
>> Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
>> ---
>> fs/smb/client/smb2ops.c | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
>>
>> diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
>> index 06e9322a762a..cc8e0595e504 100644
>> --- a/fs/smb/client/smb2ops.c
>> +++ b/fs/smb/client/smb2ops.c
>> @@ -2193,10 +2193,13 @@ smb2_duplicate_extents(const unsigned int xid,
>> u64 len, u64 dest_off)
>> {
>> int rc;
>> + int qrc;
>> unsigned int ret_data_len;
>> struct inode *inode;
>> + struct smb2_file_all_info file_inf;
>> struct duplicate_extents_to_file dup_ext_buf;
>> struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
>> + u64 asize;
>>
>> /* server fileays advertise duplicate extent support with this flag */
>> if ((le32_to_cpu(tcon->fsAttrInfo.Attributes) &
>> @@ -2232,6 +2235,19 @@ smb2_duplicate_extents(const unsigned int xid,
>> if (ret_data_len > 0)
>> cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
>>
>> + if (rc == 0) {
>> + qrc = SMB2_query_info(xid, tcon, trgtfile->fid.persistent_fid,
>> + trgtfile->fid.volatile_fid, &file_inf);
>> + spin_lock(&inode->i_lock);
>> + if (qrc == 0) {
>> + asize = le64_to_cpu(file_inf.AllocationSize);
>> + inode->i_blocks = CIFS_INO_BLOCKS(asize);
>> + } else {
>> + CIFS_I(inode)->time = 0; /* force reval */
>> + }
>> + spin_unlock(&inode->i_lock);
>> + }
>> +
>> duplicate_extents_out:
>> if (rc)
>> trace_smb3_clone_err(xid, srcfile->fid.volatile_fid,
>> --
>> 2.43.0
>>
>
>
next prev parent reply other threads:[~2026-07-02 15:20 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 15:21 [PATCH v6 0/5] smb: fix fallocate and allocation accounting Huiwen He
2026-07-01 15:21 ` [PATCH v6 1/5] smb/client: refresh allocation size after duplicate extents Huiwen He
2026-07-01 21:47 ` Steve French
2026-07-02 15:20 ` hehuiwen [this message]
2026-07-01 15:21 ` [PATCH v6 2/5] smb/client: reduce fallocate zero buffer allocation Huiwen He
2026-07-01 21:44 ` Steve French
2026-07-02 1:54 ` hehuiwen
2026-07-01 15:21 ` [PATCH v6 3/5] smb/client: emulate small EOF-extending mode 0 fallocate ranges Huiwen He
2026-07-01 15:21 ` [PATCH v6 4/5] smb/client: refresh allocation after EOF-extending fallocate Huiwen He
2026-07-01 21:19 ` Steve French
2026-07-02 3:21 ` hehuiwen
2026-07-01 15:21 ` [PATCH v6 5/5] smb/server: map SET_INFO ENOSPC to disk full Huiwen He
2026-07-02 0:21 ` Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=da8a7d66-a97c-4d81-8e92-20a810fd2dde@linux.dev \
--to=huiwen.he@linux.dev \
--cc=bharathsm@microsoft.com \
--cc=chenxiaosong@kylinos.cn \
--cc=dhowells@redhat.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=metze@samba.org \
--cc=pc@manguebit.org \
--cc=ronniesahlberg@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=smfrench@gmail.com \
--cc=sprasad@microsoft.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox