Skip to contentSkip to conversation

FAILED: patch "[PATCH] smb: client: distinguish real EOF from a stale remote_i_size" failed to apply to 6.18-stable tree

PATCH New [email protected] 2 participants 2 messages Oct 5 – Oct 7

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 75aa4b4d557114276bb72e19a9bce5cb27b5e4b8
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100541-badass-squint-41b0@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 75aa4b4d557114276bb72e19a9bce5cb27b5e4b8 Mon Sep 17 00:00:00 2001
From: Paulo Alcantara <[email protected]>
Date: Sun, 27 Sep 2026 18:56:55 -0300
Subject: [PATCH] smb: client: distinguish real EOF from a stale remote_i_size
on read

smb2_readv_callback() sets NETFS_SREQ_HIT_EOF whenever a short read lines up with netfs_read_remote_i_size(inode), the server's EOF as the client currently believes it. That belief can be stale: after a lease downgrade and handle reopen, the tracked remote_i_size can sit below the client's own i_size while an extending write hasn't reached the server yet. A read in that gap comes back short for a reason that has nothing to do with the file's real size, but was still marked HIT_EOF, and netfs reports a short read for it as-is.

Only treat it as real EOF when the position is also at or past the client's own i_size; otherwise mark it NETFS_SREQ_CLEAR_TAIL instead, which tells netfs the shortfall is safe to zero-fill rather than report as a short read.

This is what fsx (generic/363) sees as "short read: 0x0 bytes instead of 0x<n>" against a Windows server.

Fixes 1da29f2c39b6 ("netfs, cifs: Fix handling of short DIO read")
Cc Christian Brauner <[email protected]>
Cc Matthew Wilcox <[email protected]>
Cc Ronnie Sahlberg <[email protected]>
Cc Shyam Prasad N <[email protected]>
Cc Tom Talpey <[email protected]>
Cc Bharath SM <[email protected]>
fs/smb/client/smb2pdu.c +8 -2
index 3d7ead36d1a0..cfe3c4b4abe7 100644
@@ -4796,14 +4796,20 @@ smb2_readv_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 				     rdata->got_bytes);
 
 	if (rdata->result == -ENODATA) {
-		__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
 		rdata->result = 0;
+		if (rdata->subreq.start + rdata->subreq.transferred >= i_size_read(inode))
+			__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
+		else
+			__set_bit(NETFS_SREQ_CLEAR_TAIL, &rdata->subreq.flags);
 	} else {
 		size_t trans = rdata->subreq.transferred + rdata->got_bytes;
 		if (trans < rdata->subreq.len &&
 		    rdata->subreq.start + trans >= netfs_read_remote_i_size(inode)) {
-			__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
 			rdata->result = 0;
+			if (rdata->subreq.start + trans >= i_size_read(inode))
+				__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
+			else
+				__set_bit(NETFS_SREQ_CLEAR_TAIL, &rdata->subreq.flags);
 		}
 		if (rdata->got_bytes)
 			__set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags);
maintainer
#1 lore raw

PATCH 1/1 smb: client: distinguish real EOF from a stale remote_i_size on read

From: Paulo Alcantara <[email protected]>

[ Upstream commit 75aa4b4d557114276bb72e19a9bce5cb27b5e4b8 ]

smb2_readv_callback() sets NETFS_SREQ_HIT_EOF whenever a short read lines up with netfs_read_remote_i_size(inode), the server's EOF as the client currently believes it. That belief can be stale: after a lease downgrade and handle reopen, the tracked remote_i_size can sit below the client's own i_size while an extending write hasn't reached the server yet. A read in that gap comes back short for a reason that has nothing to do with the file's real size, but was still marked HIT_EOF, and netfs reports a short read for it as-is.

Only treat it as real EOF when the position is also at or past the client's own i_size; otherwise mark it NETFS_SREQ_CLEAR_TAIL instead, which tells netfs the shortfall is safe to zero-fill rather than report as a short read.

This is what fsx (generic/363) sees as "short read: 0x0 bytes instead of 0x<n>" against a Windows server.

Fixes 1da29f2c39b6 ("netfs, cifs: Fix handling of short DIO read")
Cc Christian Brauner <[email protected]>
Cc Matthew Wilcox <[email protected]>
Cc Ronnie Sahlberg <[email protected]>
Cc Shyam Prasad N <[email protected]>
Cc Tom Talpey <[email protected]>
Cc Bharath SM <[email protected]>
[ sashal: Changed i_size_read(inode) to i_size_read(&ictx->inode) because the local inode variable is absent. ]
---
 fs/smb/client/smb2pdu.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
fs/smb/client/smb2pdu.c +8 -2
index 14ee2ecdf362b..cb6db40c43589 100644
@@ -4706,14 +4706,20 @@ smb2_readv_callback(struct mid_q_entry *mid)
 				     rdata->got_bytes);
 
 	if (rdata->result == -ENODATA) {
-		__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
 		rdata->result = 0;
+		if (rdata->subreq.start + rdata->subreq.transferred >= i_size_read(&ictx->inode))
+			__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
+		else
+			__set_bit(NETFS_SREQ_CLEAR_TAIL, &rdata->subreq.flags);
 	} else {
 		size_t trans = rdata->subreq.transferred + rdata->got_bytes;
 		if (trans < rdata->subreq.len &&
 		    rdata->subreq.start + trans >= ictx->remote_i_size) {
-			__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
 			rdata->result = 0;
+			if (rdata->subreq.start + trans >= i_size_read(&ictx->inode))
+				__set_bit(NETFS_SREQ_HIT_EOF, &rdata->subreq.flags);
+			else
+				__set_bit(NETFS_SREQ_CLEAR_TAIL, &rdata->subreq.flags);
 		}
 		if (rdata->got_bytes)
 			__set_bit(NETFS_SREQ_MADE_PROGRESS, &rdata->subreq.flags);
Signature · 1 line
2.53.0