diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a6eb9befdb2daa16ba372469b6aa087c2ef563a6..6d18962c99034b93d488c35909589f4ab1b5d46a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -160,6 +160,7 @@ struct mid_q_entry; struct TCP_Server_Info; struct cifsFileInfo; struct cifs_ses; +struct cifs_tcon; struct smb_version_operations { int (*send_cancel)(struct TCP_Server_Info *, void *, @@ -201,6 +202,11 @@ struct smb_version_operations { const struct nls_table *); /* close smb session */ int (*logoff)(const unsigned int, struct cifs_ses *); + /* connect to a server share */ + int (*tree_connect)(const unsigned int, struct cifs_ses *, const char *, + struct cifs_tcon *, const struct nls_table *); + /* close tree connecion */ + int (*tree_disconnect)(const unsigned int, struct cifs_tcon *); }; struct smb_version_values { diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index a17be2618473c697d7e2d82e84fd41ca271963e4..5fbd6b9a64d9b3e2e5c867c07cb2332ecef31c56 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -184,9 +184,9 @@ extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, struct nls_table *nls_info); extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses); -extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses, - const char *tree, struct cifs_tcon *tcon, - const struct nls_table *); +extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, + const char *tree, struct cifs_tcon *tcon, + const struct nls_table *); extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon, const char *searchName, const struct nls_table *nls_codepage, @@ -389,7 +389,7 @@ extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon, const loff_t start_offset, const __u64 len, struct file_lock *, const __u16 lock_type, const bool waitFlag); -extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon); +extern int CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon); extern int CIFSSMBEcho(struct TCP_Server_Info *server); extern int CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 915b8fc212e9af788d7ce28fb04b8c7647336056..98fc454827af884eb896ff6b0a9039e948066b39 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -694,7 +694,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) } int -CIFSSMBTDis(const int xid, struct cifs_tcon *tcon) +CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon) { struct smb_hdr *smb_buffer; int rc = 0; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 444243d9232b475f52c8d4fa5d6d33416370d8b6..fcf20d1b58b9898f71febe6284a099aaef3c6e50 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2542,7 +2542,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc) static void cifs_put_tcon(struct cifs_tcon *tcon) { - int xid; + unsigned int xid; struct cifs_ses *ses = tcon->ses; cFYI(1, "%s: tc_count=%d", __func__, tcon->tc_count); @@ -2556,7 +2556,8 @@ cifs_put_tcon(struct cifs_tcon *tcon) spin_unlock(&cifs_tcp_ses_lock); xid = GetXid(); - CIFSSMBTDis(xid, tcon); + if (ses->server->ops->tree_disconnect) + ses->server->ops->tree_disconnect(xid, tcon); _FreeXid(xid); cifs_fscache_release_super_cookie(tcon); @@ -2581,6 +2582,11 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) return tcon; } + if (!ses->server->ops->tree_connect) { + rc = -ENOSYS; + goto out_fail; + } + tcon = tconInfoAlloc(); if (tcon == NULL) { rc = -ENOMEM; @@ -2603,13 +2609,15 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) goto out_fail; } - /* BB Do we need to wrap session_mutex around - * this TCon call and Unix SetFS as - * we do on SessSetup and reconnect? */ + /* + * BB Do we need to wrap session_mutex around this TCon call and Unix + * SetFS as we do on SessSetup and reconnect? + */ xid = GetXid(); - rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls); + rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon, + volume_info->local_nls); FreeXid(xid); - cFYI(1, "CIFS Tcon rc = %d", rc); + cFYI(1, "Tcon rc = %d", rc); if (rc) goto out_fail; @@ -2618,10 +2626,11 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) cFYI(1, "DFS disabled (%d)", tcon->Flags); } tcon->seal = volume_info->seal; - /* we can have only one retry value for a connection - to a share so for resources mounted more than once - to the same server share the last value passed in - for the retry flag is used */ + /* + * We can have only one retry value for a connection to a share so for + * resources mounted more than once to the same server share the last + * value passed in for the retry flag is used. + */ tcon->retry = volume_info->retry; tcon->nocase = volume_info->nocase; tcon->local_lease = volume_info->local_lease; @@ -2755,37 +2764,41 @@ cifs_match_super(struct super_block *sb, void *data) } int -get_dfs_path(int xid, struct cifs_ses *pSesInfo, const char *old_path, - const struct nls_table *nls_codepage, unsigned int *pnum_referrals, - struct dfs_info3_param **preferrals, int remap) +get_dfs_path(int xid, struct cifs_ses *ses, const char *old_path, + const struct nls_table *nls_codepage, unsigned int *num_referrals, + struct dfs_info3_param **referrals, int remap) { char *temp_unc; int rc = 0; - *pnum_referrals = 0; - *preferrals = NULL; + if (!ses->server->ops->tree_connect) + return -ENOSYS; + + *num_referrals = 0; + *referrals = NULL; - if (pSesInfo->ipc_tid == 0) { + if (ses->ipc_tid == 0) { temp_unc = kmalloc(2 /* for slashes */ + - strnlen(pSesInfo->serverName, - SERVER_NAME_LEN_WITH_NULL * 2) - + 1 + 4 /* slash IPC$ */ + 2, - GFP_KERNEL); + strnlen(ses->serverName, SERVER_NAME_LEN_WITH_NULL * 2) + + 1 + 4 /* slash IPC$ */ + 2, GFP_KERNEL); if (temp_unc == NULL) return -ENOMEM; temp_unc[0] = '\\'; temp_unc[1] = '\\'; - strcpy(temp_unc + 2, pSesInfo->serverName); - strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$"); - rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); - cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid); + strcpy(temp_unc + 2, ses->serverName); + strcpy(temp_unc + 2 + strlen(ses->serverName), "\\IPC$"); + rc = ses->server->ops->tree_connect(xid, ses, temp_unc, NULL, + nls_codepage); + cFYI(1, "Tcon rc = %d ipc_tid = %d", rc, ses->ipc_tid); kfree(temp_unc); } if (rc == 0) - rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals, - pnum_referrals, nls_codepage, remap); - /* BB map targetUNCs to dfs_info3 structures, here or - in CIFSGetDFSRefer BB */ + rc = CIFSGetDFSRefer(xid, ses, old_path, referrals, + num_referrals, nls_codepage, remap); + /* + * BB - map targetUNCs to dfs_info3 structures, here or in + * CIFSGetDFSRefer. + */ return rc; } @@ -3777,7 +3790,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) * pointer may be NULL. */ int -CIFSTCon(unsigned int xid, struct cifs_ses *ses, +CIFSTCon(const unsigned int xid, struct cifs_ses *ses, const char *tree, struct cifs_tcon *tcon, const struct nls_table *nls_codepage) { diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 6b0a5d61633801c9ee713f93c17702863ea8360a..728595f096c993f1c88302ff8f1b64612f9791e7 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -432,6 +432,8 @@ struct smb_version_operations smb1_operations = { .negotiate = cifs_negotiate, .sess_setup = CIFS_SessSetup, .logoff = CIFSSMBLogoff, + .tree_connect = CIFSTCon, + .tree_disconnect = CIFSSMBTDis, }; struct smb_version_values smb1_values = {