From: DaeMyung Kang <charsyam@gmail.com>
To: Namjae Jeon <linkinjeon@kernel.org>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
Tom Talpey <tom@talpey.com>,
ChenXiaoSong <chenxiaosong@chenxiaosong.com>,
linux-cifs@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, DaeMyung Kang <charsyam@gmail.com>
Subject: [PATCH] ksmbd: truncate files before allocating space below EOF
Date: Sun, 11 Oct 2026 20:52:39 +0900 [thread overview]
Message-ID: <20261011115239.1588419-1-charsyam@gmail.com> (raw)
set_file_allocation_info() compares the requested allocation with
stat.blocks to decide whether to fallocate or truncate. A file with
holes can have fewer allocated blocks than requested even when its EOF
is beyond the requested allocation size. In that case, ksmbd fallocates
with FALLOC_FL_KEEP_SIZE and returns success without shrinking the file.
For example, a file with one byte at offset 1 MiB has an EOF of
1 MiB + 1 but only one allocated page. Setting AllocationSize to 512 KiB
leaves the EOF and the byte unchanged, including after reopening the
file. [MS-FSA] section 2.1.5.15.1 requires EOF to be reduced when the
new allocation size is smaller than the file size.
Check EOF before comparing allocated blocks. Truncate first when the
requested allocation falls below EOF, and skip fallocate in that case.
This avoids allocating holes immediately before discarding them and
allows a shrink request to succeed when space is exhausted. Preserve
the existing behavior for allocation changes that do not shorten EOF.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Signed-off-by: DaeMyung Kang <charsyam@gmail.com>
---
fs/smb/server/smb2pdu.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 12a43efdb53f..b155a27eaeac 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -8533,23 +8533,15 @@ static int set_file_allocation_info(struct ksmbd_work *work,
alloc_blks = (alloc_size + 511) >> 9;
inode = file_inode(fp->filp);
- if (alloc_blks > stat.blocks) {
- smb_break_all_levII_oplock(work, fp, 1);
- rc = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0,
- alloc_blks * 512);
- if (rc && rc != -EOPNOTSUPP) {
- pr_err("vfs_fallocate is failed : %d\n", rc);
- return rc;
- }
- } else if (alloc_blks < stat.blocks) {
+ if (alloc_blks * 512 < i_size_read(inode) ||
+ alloc_blks < stat.blocks) {
loff_t size;
/*
- * Allocation size could be smaller than original one
- * which means allocated blocks in file should be
- * deallocated. use truncate to cut out it, but inode
- * size is also updated with truncate offset.
- * inode size is retained by backup inode size.
+ * Truncate before considering allocation when the new size is below
+ * EOF. This avoids allocating holes in a sparse file just before
+ * shrinking it. Also release excess blocks if EOF is already
+ * smaller than the requested allocation size.
*/
size = i_size_read(inode);
rc = ksmbd_vfs_truncate(work, fp, alloc_blks * 512);
@@ -8559,6 +8551,14 @@ static int set_file_allocation_info(struct ksmbd_work *work,
}
if (size < alloc_blks * 512)
i_size_write(inode, size);
+ } else if (alloc_blks > stat.blocks) {
+ smb_break_all_levII_oplock(work, fp, 1);
+ rc = vfs_fallocate(fp->filp, FALLOC_FL_KEEP_SIZE, 0,
+ alloc_blks * 512);
+ if (rc && rc != -EOPNOTSUPP) {
+ pr_err("vfs_fallocate is failed : %d\n", rc);
+ return rc;
+ }
}
fp->allocation_size = le64_to_cpu(file_alloc_info->AllocationSize);
--
2.43.0
reply other threads:[~2026-10-11 11:52 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20261011115239.1588419-1-charsyam@gmail.com \
--to=charsyam@gmail.com \
--cc=chenxiaosong@chenxiaosong.com \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=stable@vger.kernel.org \
--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
all inboxes | Powered by JetHome®