[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250831123602.14037-24-pali@kernel.org>
Date: Sun, 31 Aug 2025 14:35:50 +0200
From: Pali Rohár <pali@...nel.org>
To: Steve French <sfrench@...ba.org>,
Paulo Alcantara <pc@...guebit.com>,
ronnie sahlberg <ronniesahlberg@...il.com>
Cc: linux-cifs@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 23/35] cifs: Fix SMBLegacyOpen() function
Function SMBLegacyOpen() contains many FIXME comments, commented code and
missing handling of different flags.
Fix the FIXME comments, add missing handling of different flags and use
named macros as constants instead of magic numbers.
This is done according to MS-CIFS spec.
Signed-off-by: Pali Rohár <pali@...nel.org>
---
fs/smb/client/cifspdu.h | 4 +++
fs/smb/client/cifssmb.c | 73 +++++++++++++++++++++++++++--------------
fs/smb/client/smb1ops.c | 4 ++-
3 files changed, 55 insertions(+), 26 deletions(-)
diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index d9cf7db0ac35..cb1f99d22dd7 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -137,6 +137,10 @@
* Flags on SMB open
*/
#define SMBOPEN_WRITE_THROUGH 0x4000
+#define SMBOPEN_DO_NOT_CACHE 0x1000
+#define SMBOPEN_RANDOM_ACCESS 0x0200
+#define SMBOPEN_SEQUENTIAL 0x0100
+#define SMBOPEN_DENY_COMPAT 0x0000
#define SMBOPEN_DENY_ALL 0x0010
#define SMBOPEN_DENY_WRITE 0x0020
#define SMBOPEN_DENY_READ 0x0030
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 2a83fbc65395..c09713ebdc7c 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -1103,32 +1103,41 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
count = 0; /* no pad */
name_len = copy_path_name(pSMB->fileName, fileName);
}
- if (*pOplock & REQ_OPLOCK)
- pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
- else if (*pOplock & REQ_BATCHOPLOCK)
+
+ if (*pOplock & REQ_BATCHOPLOCK)
pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
+ else if (*pOplock & REQ_OPLOCK)
+ pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
+
+ if (pfile_info)
+ pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
- pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
- pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
+ pSMB->Mode |= cpu_to_le16(SMBOPEN_DENY_NONE);
+
+ if (create_options & CREATE_WRITE_THROUGH)
+ pSMB->Mode |= cpu_to_le16(SMBOPEN_WRITE_THROUGH);
+
+ if (create_options & CREATE_NO_BUFFER)
+ pSMB->Mode |= cpu_to_le16(SMBOPEN_DO_NOT_CACHE);
+
+ if (create_options & CREATE_RANDOM_ACCESS)
+ pSMB->Mode |= cpu_to_le16(SMBOPEN_RANDOM_ACCESS);
+ else if (create_options & CREATE_SEQUENTIAL)
+ pSMB->Mode |= cpu_to_le16(SMBOPEN_SEQUENTIAL);
+
/* set file as system file if special file such as fifo,
* socket, char or block and server expecting SFU style and
no Unix extensions */
-
if (create_options & CREATE_OPTION_SPECIAL)
pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
- else /* BB FIXME BB */
- pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
+ else
+ pSMB->FileAttributes = cpu_to_le16(0);
if (create_options & CREATE_OPTION_READONLY)
pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
- /* BB FIXME BB */
-/* pSMB->CreateOptions = cpu_to_le32(create_options &
- CREATE_OPTIONS_MASK); */
- /* BB FIXME END BB */
-
- pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
+ pSMB->Sattr = cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_ARCHIVE);
pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
count += name_len;
inc_rfc1001_len(pSMB, count);
@@ -1139,24 +1148,38 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
if (rc) {
cifs_dbg(FYI, "Error in Open = %d\n", rc);
+ } else if (pSMBr->hdr.WordCount != 15) {
+ rc = -EIO;
} else {
- /* BB verify if wct == 15 */
-
-/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
+ if (!(pSMBr->Action & 0x8000))
+ *pOplock = OPLOCK_NONE;
+ else if (*pOplock & REQ_BATCHOPLOCK)
+ *pOplock = OPLOCK_BATCH;
+ else if (*pOplock & REQ_OPLOCK)
+ *pOplock = OPLOCK_EXCLUSIVE;
+ else
+ *pOplock = OPLOCK_NONE;
*netfid = pSMBr->Fid; /* cifs fid stays in le */
+
/* Let caller know file was created so we can set the mode. */
/* Do we care about the CreateAction in any other cases? */
- /* BB FIXME BB */
-/* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
- *pOplock |= CIFS_CREATE_ACTION; */
- /* BB FIXME END */
+ if ((pSMBr->Action & 0x0003) == 2)
+ *pOplock |= CIFS_CREATE_ACTION;
if (pfile_info) {
- pfile_info->CreationTime = 0; /* BB convert CreateTime*/
- pfile_info->LastAccessTime = 0; /* BB fixme */
- pfile_info->LastWriteTime = 0; /* BB fixme */
- pfile_info->ChangeTime = 0; /* BB fixme */
+ struct timespec64 ts;
+ __u32 time = le32_to_cpu(pSMBr->LastWriteTime);
+
+ ts.tv_nsec = 0;
+ ts.tv_sec = time;
+ pfile_info->LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
+ pfile_info->ChangeTime = pfile_info->LastWriteTime;
+ if (*pOplock & CIFS_CREATE_ACTION)
+ pfile_info->CreationTime = pfile_info->LastWriteTime;
+ else
+ pfile_info->CreationTime = 0;
+ pfile_info->LastAccessTime = 0;
pfile_info->Attributes =
cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
/* the file_info buf is endian converted by caller */
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 6e928e90d72b..73d3dc83faa6 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -853,7 +853,9 @@ static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms
oparms->disposition,
oparms->desired_access,
oparms->create_options,
- &oparms->fid->netfid, oplock, &fi,
+ &oparms->fid->netfid,
+ oplock,
+ data ? &fi : NULL,
oparms->cifs_sb->local_nls,
cifs_remap(oparms->cifs_sb));
else
--
2.20.1
Powered by blists - more mailing lists