diff options
| author | Gael Blivet <gael.blivet@gmail.com> | 2026-07-09 02:01:11 +0200 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-08-17 15:00:40 +0900 |
| commit | bfdf81c62f4f52a3626ea62db0744def6778e83f (patch) | |
| tree | 679089d39c5a1f4035deab44a8c8f8ba56c6db20 | |
| parent | 86f901803080056668cdaf23b01c8e81d2e77956 (diff) | |
| download | linux-bfdf81c62f4f52a3626ea62db0744def6778e83f.tar.gz linux-bfdf81c62f4f52a3626ea62db0744def6778e83f.zip | |
ksmbd: skip fallocate for SMB2_CREATE_ALLOCATION_SIZE on a stream handle
smb2_open() calls vfs_fallocate(fp->filp, ...) unconditionally when a
client's CREATE request includes an AllocationSize create context.
For a stream handle, fp->filp refers to the base file's data fork
(streams are xattr-backed on the same underlying file, not separate
files), so this pre-allocates storage on the base file's actual data
instead of doing anything meaningful for the stream -- fallocate has
no applicability to an xattr-backed stream at all.
Skip the fallocate call for stream handles.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Gael Blivet <gael.blivet@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 1a81391e95ef..587cc095b07b 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4097,13 +4097,22 @@ int smb2_open(struct ksmbd_work *work) ksmbd_debug(SMB, "request smb2 create allocate size : %llu\n", alloc_size); - smb_break_all_levII_oplock(work, fp, 1); - err = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, - alloc_size); - if (err < 0) - ksmbd_debug(SMB, - "vfs_fallocate is failed : %d\n", - err); + /* + * fp->filp is the base file's data fork for a stream + * handle (streams are xattr-backed on the same + * underlying file) -- fallocate has no meaning for a + * stream and would otherwise pre-allocate storage on + * the base file's data instead. + */ + if (!ksmbd_stream_fd(fp)) { + smb_break_all_levII_oplock(work, fp, 1); + err = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0, + alloc_size); + if (err < 0) + ksmbd_debug(SMB, + "vfs_fallocate is failed : %d\n", + err); + } } context = smb2_find_context_vals(req, SMB2_CREATE_QUERY_ON_DISK_ID, 4); |
