[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251222223006.1075635-37-dhowells@redhat.com>
Date: Mon, 22 Dec 2025 22:30:01 +0000
From: David Howells <dhowells@...hat.com>
To: Steve French <sfrench@...ba.org>
Cc: David Howells <dhowells@...hat.com>,
Paulo Alcantara <pc@...guebit.org>,
Enzo Matsumiya <ematsumiya@...e.de>,
linux-cifs@...r.kernel.org,
linux-fsdevel@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 36/37] cifs: SMB1 split: connect.c
Split SMB1-specific connection management stuff to smb1ops.c and move
CIFSTCon() to cifssmb.c.
Signed-off-by: David Howells <dhowells@...hat.com>
cc: Steve French <sfrench@...ba.org>
cc: Paulo Alcantara <pc@...guebit.org>
cc: Enzo Matsumiya <ematsumiya@...e.de>
cc: linux-cifs@...r.kernel.org
cc: linux-fsdevel@...r.kernel.org
cc: linux-kernel@...r.kernel.org
---
fs/smb/client/cifsproto.h | 20 ---
fs/smb/client/cifssmb.c | 140 +++++++++++++++++++++
fs/smb/client/connect.c | 251 --------------------------------------
fs/smb/client/smb1ops.c | 107 ++++++++++++++++
fs/smb/client/smb1proto.h | 6 +
5 files changed, 253 insertions(+), 271 deletions(-)
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 49ff68f3c999..96d6b5325aa3 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -291,31 +291,11 @@ int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
int cifs_enable_signing(struct TCP_Server_Info *server,
bool mnt_sign_required);
-int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
- struct cifs_tcon *tcon, const struct nls_table *nls_codepage);
-
-
-
-
-
-
-
int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
unsigned int *num_of_nodes,
struct dfs_info3_param **target_nodes,
const struct nls_table *nls_codepage, int remap,
const char *searchName, bool is_unicode);
-void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb,
- struct smb3_fs_context *ctx);
-
-
-
-
-
-
-
-
struct cifs_ses *sesInfoAlloc(void);
void sesInfoFree(struct cifs_ses *buf_to_free);
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 8738fdbb5a59..3990a9012264 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -534,6 +534,146 @@ CIFSSMBNegotiate(const unsigned int xid,
return rc;
}
+/*
+ * Issue a TREE_CONNECT request.
+ */
+int
+CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+ const char *tree, struct cifs_tcon *tcon,
+ const struct nls_table *nls_codepage)
+{
+ struct smb_hdr *smb_buffer;
+ struct smb_hdr *smb_buffer_response;
+ TCONX_REQ *pSMB;
+ TCONX_RSP *pSMBr;
+ unsigned char *bcc_ptr;
+ int rc = 0;
+ int length, in_len;
+ __u16 bytes_left, count;
+
+ if (ses == NULL)
+ return smb_EIO(smb_eio_trace_null_pointers);
+
+ smb_buffer = cifs_buf_get();
+ if (smb_buffer == NULL)
+ return -ENOMEM;
+
+ smb_buffer_response = smb_buffer;
+
+ in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
+ NULL /*no tid */, 4 /*wct */);
+
+ smb_buffer->Mid = get_next_mid(ses->server);
+ smb_buffer->Uid = ses->Suid;
+ pSMB = (TCONX_REQ *) smb_buffer;
+ pSMBr = (TCONX_RSP *) smb_buffer_response;
+
+ pSMB->AndXCommand = 0xFF;
+ pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+ bcc_ptr = &pSMB->Password[0];
+
+ pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
+ *bcc_ptr = 0; /* password is null byte */
+ bcc_ptr++; /* skip password */
+ /* already aligned so no need to do it below */
+
+ if (ses->server->sign)
+ smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+
+ if (ses->capabilities & CAP_STATUS32)
+ smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
+
+ if (ses->capabilities & CAP_DFS)
+ smb_buffer->Flags2 |= SMBFLG2_DFS;
+
+ if (ses->capabilities & CAP_UNICODE) {
+ smb_buffer->Flags2 |= SMBFLG2_UNICODE;
+ length =
+ cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
+ 6 /* max utf8 char length in bytes */ *
+ (/* server len*/ + 256 /* share len */), nls_codepage);
+ bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
+ bcc_ptr += 2; /* skip trailing null */
+ } else { /* ASCII */
+ strcpy(bcc_ptr, tree);
+ bcc_ptr += strlen(tree) + 1;
+ }
+ strcpy(bcc_ptr, "?????");
+ bcc_ptr += strlen("?????");
+ bcc_ptr += 1;
+ count = bcc_ptr - &pSMB->Password[0];
+ in_len += count;
+ pSMB->ByteCount = cpu_to_le16(count);
+
+ rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
+ &length, 0);
+
+ /* above now done in SendReceive */
+ if (rc == 0) {
+ bool is_unicode;
+
+ tcon->tid = smb_buffer_response->Tid;
+ bcc_ptr = pByteArea(smb_buffer_response);
+ bytes_left = get_bcc(smb_buffer_response);
+ length = strnlen(bcc_ptr, bytes_left - 2);
+ if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
+ is_unicode = true;
+ else
+ is_unicode = false;
+
+
+ /* skip service field (NB: this field is always ASCII) */
+ if (length == 3) {
+ if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+ (bcc_ptr[2] == 'C')) {
+ cifs_dbg(FYI, "IPC connection\n");
+ tcon->ipc = true;
+ tcon->pipe = true;
+ }
+ } else if (length == 2) {
+ if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+ /* the most common case */
+ cifs_dbg(FYI, "disk share connection\n");
+ }
+ }
+ bcc_ptr += length + 1;
+ bytes_left -= (length + 1);
+ strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
+
+ /* mostly informational -- no need to fail on error here */
+ kfree(tcon->nativeFileSystem);
+ tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
+ bytes_left, is_unicode,
+ nls_codepage);
+
+ cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
+
+ if ((smb_buffer_response->WordCount == 3) ||
+ (smb_buffer_response->WordCount == 7))
+ /* field is in same location */
+ tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
+ else
+ tcon->Flags = 0;
+ cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
+
+ /*
+ * reset_cifs_unix_caps calls QFSInfo which requires
+ * need_reconnect to be false, but we would not need to call
+ * reset_caps if this were not a reconnect case so must check
+ * need_reconnect flag here. The caller will also clear
+ * need_reconnect when tcon was successful but needed to be
+ * cleared earlier in the case of unix extensions reconnect
+ */
+ if (tcon->need_reconnect && tcon->unix_ext) {
+ cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
+ tcon->need_reconnect = false;
+ reset_cifs_unix_caps(xid, tcon, NULL, NULL);
+ }
+ }
+ cifs_buf_release(smb_buffer);
+ return rc;
+}
+
int
CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
{
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 536edb0a8ed3..39f9e50369ea 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3462,115 +3462,6 @@ ip_connect(struct TCP_Server_Info *server)
return generic_ip_connect(server);
}
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
-{
- /*
- * If we are reconnecting then should we check to see if
- * any requested capabilities changed locally e.g. via
- * remount but we can not do much about it here
- * if they have (even if we could detect it by the following)
- * Perhaps we could add a backpointer to array of sb from tcon
- * or if we change to make all sb to same share the same
- * sb as NFS - then we only have one backpointer to sb.
- * What if we wanted to mount the server share twice once with
- * and once without posixacls or posix paths?
- */
- __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-
- if (ctx && ctx->no_linux_ext) {
- tcon->fsUnixInfo.Capability = 0;
- tcon->unix_ext = 0; /* Unix Extensions disabled */
- cifs_dbg(FYI, "Linux protocol extensions disabled\n");
- return;
- } else if (ctx)
- tcon->unix_ext = 1; /* Unix Extensions supported */
-
- if (!tcon->unix_ext) {
- cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
- return;
- }
-
- if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
- __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-
- cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
- /*
- * check for reconnect case in which we do not
- * want to change the mount behavior if we can avoid it
- */
- if (ctx == NULL) {
- /*
- * turn off POSIX ACL and PATHNAMES if not set
- * originally at mount time
- */
- if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
- cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
- if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
- cifs_dbg(VFS, "POSIXPATH support change\n");
- cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
- } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
- cifs_dbg(VFS, "possible reconnect error\n");
- cifs_dbg(VFS, "server disabled POSIX path support\n");
- }
- }
-
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
- cifs_dbg(VFS, "per-share encryption not supported yet\n");
-
- cap &= CIFS_UNIX_CAP_MASK;
- if (ctx && ctx->no_psx_acl)
- cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
- cifs_dbg(FYI, "negotiated posix acl support\n");
- if (cifs_sb)
- cifs_sb->mnt_cifs_flags |=
- CIFS_MOUNT_POSIXACL;
- }
-
- if (ctx && ctx->posix_paths == 0)
- cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
- else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
- cifs_dbg(FYI, "negotiate posix pathnames\n");
- if (cifs_sb)
- cifs_sb->mnt_cifs_flags |=
- CIFS_MOUNT_POSIX_PATHS;
- }
-
- cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
-#ifdef CONFIG_CIFS_DEBUG2
- if (cap & CIFS_UNIX_FCNTL_CAP)
- cifs_dbg(FYI, "FCNTL cap\n");
- if (cap & CIFS_UNIX_EXTATTR_CAP)
- cifs_dbg(FYI, "EXTATTR cap\n");
- if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
- cifs_dbg(FYI, "POSIX path cap\n");
- if (cap & CIFS_UNIX_XATTR_CAP)
- cifs_dbg(FYI, "XATTR cap\n");
- if (cap & CIFS_UNIX_POSIX_ACL_CAP)
- cifs_dbg(FYI, "POSIX ACL cap\n");
- if (cap & CIFS_UNIX_LARGE_READ_CAP)
- cifs_dbg(FYI, "very large read cap\n");
- if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
- cifs_dbg(FYI, "very large write cap\n");
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
- cifs_dbg(FYI, "transport encryption cap\n");
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
- cifs_dbg(FYI, "mandatory transport encryption cap\n");
-#endif /* CIFS_DEBUG2 */
- if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
- if (ctx == NULL)
- cifs_dbg(FYI, "resetting capabilities failed\n");
- else
- cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
-
- }
- }
-}
-#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
-
int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
{
struct smb3_fs_context *ctx = cifs_sb->ctx;
@@ -3984,148 +3875,6 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
}
#endif
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-/*
- * Issue a TREE_CONNECT request.
- */
-int
-CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
- const char *tree, struct cifs_tcon *tcon,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- TCONX_REQ *pSMB;
- TCONX_RSP *pSMBr;
- unsigned char *bcc_ptr;
- int rc = 0;
- int length, in_len;
- __u16 bytes_left, count;
-
- if (ses == NULL)
- return smb_EIO(smb_eio_trace_null_pointers);
-
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL)
- return -ENOMEM;
-
- smb_buffer_response = smb_buffer;
-
- in_len = header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
- NULL /*no tid */, 4 /*wct */);
-
- smb_buffer->Mid = get_next_mid(ses->server);
- smb_buffer->Uid = ses->Suid;
- pSMB = (TCONX_REQ *) smb_buffer;
- pSMBr = (TCONX_RSP *) smb_buffer_response;
-
- pSMB->AndXCommand = 0xFF;
- pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
- bcc_ptr = &pSMB->Password[0];
-
- pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
- *bcc_ptr = 0; /* password is null byte */
- bcc_ptr++; /* skip password */
- /* already aligned so no need to do it below */
-
- if (ses->server->sign)
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- if (ses->capabilities & CAP_STATUS32)
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-
- if (ses->capabilities & CAP_DFS)
- smb_buffer->Flags2 |= SMBFLG2_DFS;
-
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- length =
- cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
- 6 /* max utf8 char length in bytes */ *
- (/* server len*/ + 256 /* share len */), nls_codepage);
- bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
- bcc_ptr += 2; /* skip trailing null */
- } else { /* ASCII */
- strcpy(bcc_ptr, tree);
- bcc_ptr += strlen(tree) + 1;
- }
- strcpy(bcc_ptr, "?????");
- bcc_ptr += strlen("?????");
- bcc_ptr += 1;
- count = bcc_ptr - &pSMB->Password[0];
- in_len += count;
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, in_len, smb_buffer_response,
- &length, 0);
-
- /* above now done in SendReceive */
- if (rc == 0) {
- bool is_unicode;
-
- tcon->tid = smb_buffer_response->Tid;
- bcc_ptr = pByteArea(smb_buffer_response);
- bytes_left = get_bcc(smb_buffer_response);
- length = strnlen(bcc_ptr, bytes_left - 2);
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
- is_unicode = true;
- else
- is_unicode = false;
-
-
- /* skip service field (NB: this field is always ASCII) */
- if (length == 3) {
- if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
- (bcc_ptr[2] == 'C')) {
- cifs_dbg(FYI, "IPC connection\n");
- tcon->ipc = true;
- tcon->pipe = true;
- }
- } else if (length == 2) {
- if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
- /* the most common case */
- cifs_dbg(FYI, "disk share connection\n");
- }
- }
- bcc_ptr += length + 1;
- bytes_left -= (length + 1);
- strscpy(tcon->tree_name, tree, sizeof(tcon->tree_name));
-
- /* mostly informational -- no need to fail on error here */
- kfree(tcon->nativeFileSystem);
- tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
- bytes_left, is_unicode,
- nls_codepage);
-
- cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
-
- if ((smb_buffer_response->WordCount == 3) ||
- (smb_buffer_response->WordCount == 7))
- /* field is in same location */
- tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
- else
- tcon->Flags = 0;
- cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
-
- /*
- * reset_cifs_unix_caps calls QFSInfo which requires
- * need_reconnect to be false, but we would not need to call
- * reset_caps if this were not a reconnect case so must check
- * need_reconnect flag here. The caller will also clear
- * need_reconnect when tcon was successful but needed to be
- * cleared earlier in the case of unix extensions reconnect
- */
- if (tcon->need_reconnect && tcon->unix_ext) {
- cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
- tcon->need_reconnect = false;
- reset_cifs_unix_caps(xid, tcon, NULL, NULL);
- }
- }
- cifs_buf_release(smb_buffer);
- return rc;
-}
-#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
-
static void delayed_free(struct rcu_head *p)
{
struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
index 65d55a81b1b2..9c3b97d2a20a 100644
--- a/fs/smb/client/smb1ops.c
+++ b/fs/smb/client/smb1ops.c
@@ -18,6 +18,113 @@
#include "smberr.h"
#include "reparse.h"
+void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+{
+ /*
+ * If we are reconnecting then should we check to see if
+ * any requested capabilities changed locally e.g. via
+ * remount but we can not do much about it here
+ * if they have (even if we could detect it by the following)
+ * Perhaps we could add a backpointer to array of sb from tcon
+ * or if we change to make all sb to same share the same
+ * sb as NFS - then we only have one backpointer to sb.
+ * What if we wanted to mount the server share twice once with
+ * and once without posixacls or posix paths?
+ */
+ __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+
+ if (ctx && ctx->no_linux_ext) {
+ tcon->fsUnixInfo.Capability = 0;
+ tcon->unix_ext = 0; /* Unix Extensions disabled */
+ cifs_dbg(FYI, "Linux protocol extensions disabled\n");
+ return;
+ } else if (ctx)
+ tcon->unix_ext = 1; /* Unix Extensions supported */
+
+ if (!tcon->unix_ext) {
+ cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
+ return;
+ }
+
+ if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
+ __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+
+ cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
+ /*
+ * check for reconnect case in which we do not
+ * want to change the mount behavior if we can avoid it
+ */
+ if (ctx == NULL) {
+ /*
+ * turn off POSIX ACL and PATHNAMES if not set
+ * originally at mount time
+ */
+ if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
+ cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
+ if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+ if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+ cifs_dbg(VFS, "POSIXPATH support change\n");
+ cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
+ } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
+ cifs_dbg(VFS, "possible reconnect error\n");
+ cifs_dbg(VFS, "server disabled POSIX path support\n");
+ }
+ }
+
+ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
+ cifs_dbg(VFS, "per-share encryption not supported yet\n");
+
+ cap &= CIFS_UNIX_CAP_MASK;
+ if (ctx && ctx->no_psx_acl)
+ cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
+ else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
+ cifs_dbg(FYI, "negotiated posix acl support\n");
+ if (cifs_sb)
+ cifs_sb->mnt_cifs_flags |=
+ CIFS_MOUNT_POSIXACL;
+ }
+
+ if (ctx && ctx->posix_paths == 0)
+ cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
+ else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ cifs_dbg(FYI, "negotiate posix pathnames\n");
+ if (cifs_sb)
+ cifs_sb->mnt_cifs_flags |=
+ CIFS_MOUNT_POSIX_PATHS;
+ }
+
+ cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
+#ifdef CONFIG_CIFS_DEBUG2
+ if (cap & CIFS_UNIX_FCNTL_CAP)
+ cifs_dbg(FYI, "FCNTL cap\n");
+ if (cap & CIFS_UNIX_EXTATTR_CAP)
+ cifs_dbg(FYI, "EXTATTR cap\n");
+ if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+ cifs_dbg(FYI, "POSIX path cap\n");
+ if (cap & CIFS_UNIX_XATTR_CAP)
+ cifs_dbg(FYI, "XATTR cap\n");
+ if (cap & CIFS_UNIX_POSIX_ACL_CAP)
+ cifs_dbg(FYI, "POSIX ACL cap\n");
+ if (cap & CIFS_UNIX_LARGE_READ_CAP)
+ cifs_dbg(FYI, "very large read cap\n");
+ if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
+ cifs_dbg(FYI, "very large write cap\n");
+ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
+ cifs_dbg(FYI, "transport encryption cap\n");
+ if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
+ cifs_dbg(FYI, "mandatory transport encryption cap\n");
+#endif /* CIFS_DEBUG2 */
+ if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
+ if (ctx == NULL)
+ cifs_dbg(FYI, "resetting capabilities failed\n");
+ else
+ cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
+
+ }
+ }
+}
+
/*
* An NT cancel request header looks just like the original request except:
*
diff --git a/fs/smb/client/smb1proto.h b/fs/smb/client/smb1proto.h
index 645f3e74fcc4..5ccca02841a8 100644
--- a/fs/smb/client/smb1proto.h
+++ b/fs/smb/client/smb1proto.h
@@ -33,6 +33,8 @@ int small_smb_init_no_tc(const int smb_command, const int wct,
struct cifs_ses *ses, void **request_buf);
int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server);
+int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
+ struct cifs_tcon *tcon, const struct nls_table *nls_codepage);
int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon);
int CIFSSMBEcho(struct TCP_Server_Info *server);
int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses);
@@ -250,6 +252,10 @@ unsigned int smbCalcSize(void *buf);
extern struct smb_version_operations smb1_operations;
extern struct smb_version_values smb1_values;
+void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ struct smb3_fs_context *ctx);
+
/*
* smb1session.c
*/
Powered by blists - more mailing lists