summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGael Blivet <gael.blivet@gmail.com>2026-07-09 02:01:11 +0200
committerNamjae Jeon <linkinjeon@kernel.org>2026-08-17 15:00:40 +0900
commitbfdf81c62f4f52a3626ea62db0744def6778e83f (patch)
tree679089d39c5a1f4035deab44a8c8f8ba56c6db20
parent86f901803080056668cdaf23b01c8e81d2e77956 (diff)
downloadlinux-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.c23
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);