summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorZe Tan <tanze@kylinos.cn>2026-08-11 14:00:46 +0800
committerPaulo Alcantara <pc@manguebit.org>2026-08-24 17:08:52 -0300
commit9437f2113b60a5a8593aa4b41b6f6632f5cabcfd (patch)
treef3feb312f78a2b193cb14fb3ec36004cb75363ee /fs
parentebdc1afb1e268de4c01814fa960286392801b604 (diff)
smb/client: preserve open info type across compound queries
contains_posix_file_info describes the metadata stored in the fi/posix_fi union. GET_REPARSE and QUERY_WSL_EA do not update that union, so clearing the flag while processing those responses can make POSIX metadata look like FILE_ALL_INFORMATION. Set the flag when CREATE or a validated query response actually populates the union, and leave it unchanged for auxiliary compound operations. This also avoids changing the type when a query fails before copying any metadata. The issue can be reproduced against a Samba server with SMB3 UNIX extensions enabled: mount -t cifs //<server>/<share> /mnt/cifs \ -o vers=3.1.1,posix,reparse=nfs,actimeo=0 mkfifo /mnt/cifs/test-fifo umount /mnt/cifs mount -t cifs //<server>/<share> /mnt/cifs \ -o vers=3.1.1,posix,reparse=nfs,actimeo=0 stat -c '%F %s' /mnt/cifs/test-fifo Before this change, stat reports "fifo 1024" although the server-side EOF is zero. After this change, it reports "fifo 0". Fixes: 9df23801c83d ("smb311: failure to open files of length 1040 when mounting with SMB3.1.1 POSIX extensions") Signed-off-by: Ze Tan <tanze@kylinos.cn> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/smb/client/smb2inode.c9
-rw-r--r--fs/smb/client/smb2pdu.c1
2 files changed, 6 insertions, 4 deletions
diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c
index d4ae8a5ad463..058b05f7a3e5 100644
--- a/fs/smb/client/smb2inode.c
+++ b/fs/smb/client/smb2inode.c
@@ -574,6 +574,7 @@ finished:
idata->fi.Attributes = create_rsp->FileAttributes;
idata->fi.AllocationSize = create_rsp->AllocationSize;
idata->fi.EndOfFile = create_rsp->EndofFile;
+ idata->contains_posix_file_info = false;
if (le32_to_cpu(idata->fi.NumberOfLinks) == 0)
idata->fi.NumberOfLinks = cpu_to_le32(1); /* dummy value */
idata->unknown_nlink = true;
@@ -597,7 +598,6 @@ finished:
switch (cmds[i]) {
case SMB2_OP_QUERY_INFO:
idata = in_iov[i].iov_base;
- idata->contains_posix_file_info = false;
if (rc == 0 && cfile && cfile->symlink_target) {
idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
if (!idata->symlink_target)
@@ -610,6 +610,8 @@ finished:
le16_to_cpu(qi_rsp->OutputBufferOffset),
le32_to_cpu(qi_rsp->OutputBufferLength),
&rsp_iov[i + 1], sizeof(idata->fi), (char *)&idata->fi);
+ if (!rc)
+ idata->contains_posix_file_info = false;
}
SMB2_query_info_free(&rqst[num_rqst++]);
if (rc)
@@ -621,7 +623,6 @@ finished:
break;
case SMB2_OP_POSIX_QUERY_INFO:
idata = in_iov[i].iov_base;
- idata->contains_posix_file_info = true;
if (rc == 0 && cfile && cfile->symlink_target) {
idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
if (!idata->symlink_target)
@@ -635,6 +636,8 @@ finished:
le32_to_cpu(qi_rsp->OutputBufferLength),
&rsp_iov[i + 1], sizeof(idata->posix_fi) /* add SIDs */,
(char *)&idata->posix_fi);
+ if (!rc)
+ idata->contains_posix_file_info = true;
}
if (rc == 0)
rc = parse_posix_sids(idata, &rsp_iov[i + 1]);
@@ -706,7 +709,6 @@ finished:
idata = in_iov[i].iov_base;
idata->reparse.io.iov = *iov;
idata->reparse.io.buftype = resp_buftype[i + 1];
- idata->contains_posix_file_info = false; /* BB VERIFY */
rbuf = reparse_buf_ptr(iov);
if (IS_ERR(rbuf)) {
rc = PTR_ERR(rbuf);
@@ -728,7 +730,6 @@ finished:
case SMB2_OP_QUERY_WSL_EA:
if (!rc) {
idata = in_iov[i].iov_base;
- idata->contains_posix_file_info = false;
qi_rsp = rsp_iov[i + 1].iov_base;
data[0] = (u8 *)qi_rsp + le16_to_cpu(qi_rsp->OutputBufferOffset);
size[0] = le32_to_cpu(qi_rsp->OutputBufferLength);
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d207591cc889..dea05aeb53a1 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -3372,6 +3372,7 @@ replay_again:
#endif /* CIFS_DEBUG2 */
if (file_info) {
+ buf->contains_posix_file_info = false;
file_info->CreationTime = rsp->CreationTime;
file_info->LastAccessTime = rsp->LastAccessTime;
file_info->LastWriteTime = rsp->LastWriteTime;