diff options
| -rw-r--r-- | fs/cifs/cifsglob.h | 4 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 1 | ||||
| -rw-r--r-- | fs/cifs/sess.c | 84 |
3 files changed, 1 insertions, 88 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index cfa14c80ef3b..9c72be6fb0df 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -547,9 +547,6 @@ struct TCP_Server_Info { | |||
| 547 | unsigned int max_rw; /* maxRw specifies the maximum */ | 547 | unsigned int max_rw; /* maxRw specifies the maximum */ |
| 548 | /* message size the server can send or receive for */ | 548 | /* message size the server can send or receive for */ |
| 549 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ | 549 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ |
| 550 | unsigned int max_vcs; /* maximum number of smb sessions, at least | ||
| 551 | those that can be specified uniquely with | ||
| 552 | vcnumbers */ | ||
| 553 | unsigned int capabilities; /* selective disabling of caps by smb sess */ | 550 | unsigned int capabilities; /* selective disabling of caps by smb sess */ |
| 554 | int timeAdj; /* Adjust for difference in server time zone in sec */ | 551 | int timeAdj; /* Adjust for difference in server time zone in sec */ |
| 555 | __u64 CurrentMid; /* multiplex id - rotating counter */ | 552 | __u64 CurrentMid; /* multiplex id - rotating counter */ |
| @@ -715,7 +712,6 @@ struct cifs_ses { | |||
| 715 | enum statusEnum status; | 712 | enum statusEnum status; |
| 716 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ | 713 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ |
| 717 | __u16 ipc_tid; /* special tid for connection to IPC share */ | 714 | __u16 ipc_tid; /* special tid for connection to IPC share */ |
| 718 | __u16 vcnum; | ||
| 719 | char *serverOS; /* name of operating system underlying server */ | 715 | char *serverOS; /* name of operating system underlying server */ |
| 720 | char *serverNOS; /* name of network operating system of server */ | 716 | char *serverNOS; /* name of network operating system of server */ |
| 721 | char *serverDomain; /* security realm of server */ | 717 | char *serverDomain; /* security realm of server */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index a3d74fea1623..4baf35949b51 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -463,7 +463,6 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) | |||
| 463 | cifs_max_pending); | 463 | cifs_max_pending); |
| 464 | set_credits(server, server->maxReq); | 464 | set_credits(server, server->maxReq); |
| 465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); | 465 | server->maxBuf = le16_to_cpu(rsp->MaxBufSize); |
| 466 | server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); | ||
| 467 | /* even though we do not use raw we might as well set this | 466 | /* even though we do not use raw we might as well set this |
| 468 | accurately, in case we ever find a need for it */ | 467 | accurately, in case we ever find a need for it */ |
| 469 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { | 468 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 5f99b7f19e78..352358de1d7e 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -32,88 +32,6 @@ | |||
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include "cifs_spnego.h" | 33 | #include "cifs_spnego.h" |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * Checks if this is the first smb session to be reconnected after | ||
| 37 | * the socket has been reestablished (so we know whether to use vc 0). | ||
| 38 | * Called while holding the cifs_tcp_ses_lock, so do not block | ||
| 39 | */ | ||
| 40 | static bool is_first_ses_reconnect(struct cifs_ses *ses) | ||
| 41 | { | ||
| 42 | struct list_head *tmp; | ||
| 43 | struct cifs_ses *tmp_ses; | ||
| 44 | |||
| 45 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 46 | tmp_ses = list_entry(tmp, struct cifs_ses, | ||
| 47 | smb_ses_list); | ||
| 48 | if (tmp_ses->need_reconnect == false) | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | /* could not find a session that was already connected, | ||
| 52 | this must be the first one we are reconnecting */ | ||
| 53 | return true; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * vc number 0 is treated specially by some servers, and should be the | ||
| 58 | * first one we request. After that we can use vcnumbers up to maxvcs, | ||
| 59 | * one for each smb session (some Windows versions set maxvcs incorrectly | ||
| 60 | * so maxvc=1 can be ignored). If we have too many vcs, we can reuse | ||
| 61 | * any vc but zero (some servers reset the connection on vcnum zero) | ||
| 62 | * | ||
| 63 | */ | ||
| 64 | static __le16 get_next_vcnum(struct cifs_ses *ses) | ||
| 65 | { | ||
| 66 | __u16 vcnum = 0; | ||
| 67 | struct list_head *tmp; | ||
| 68 | struct cifs_ses *tmp_ses; | ||
| 69 | __u16 max_vcs = ses->server->max_vcs; | ||
| 70 | __u16 i; | ||
| 71 | int free_vc_found = 0; | ||
| 72 | |||
| 73 | /* Quoting the MS-SMB specification: "Windows-based SMB servers set this | ||
| 74 | field to one but do not enforce this limit, which allows an SMB client | ||
| 75 | to establish more virtual circuits than allowed by this value ... but | ||
| 76 | other server implementations can enforce this limit." */ | ||
| 77 | if (max_vcs < 2) | ||
| 78 | max_vcs = 0xFFFF; | ||
| 79 | |||
| 80 | spin_lock(&cifs_tcp_ses_lock); | ||
| 81 | if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) | ||
| 82 | goto get_vc_num_exit; /* vcnum will be zero */ | ||
| 83 | for (i = ses->server->srv_count - 1; i < max_vcs; i++) { | ||
| 84 | if (i == 0) /* this is the only connection, use vc 0 */ | ||
| 85 | break; | ||
| 86 | |||
| 87 | free_vc_found = 1; | ||
| 88 | |||
| 89 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 90 | tmp_ses = list_entry(tmp, struct cifs_ses, | ||
| 91 | smb_ses_list); | ||
| 92 | if (tmp_ses->vcnum == i) { | ||
| 93 | free_vc_found = 0; | ||
| 94 | break; /* found duplicate, try next vcnum */ | ||
| 95 | } | ||
| 96 | } | ||
| 97 | if (free_vc_found) | ||
| 98 | break; /* we found a vcnumber that will work - use it */ | ||
| 99 | } | ||
| 100 | |||
| 101 | if (i == 0) | ||
| 102 | vcnum = 0; /* for most common case, ie if one smb session, use | ||
| 103 | vc zero. Also for case when no free vcnum, zero | ||
| 104 | is safest to send (some clients only send zero) */ | ||
| 105 | else if (free_vc_found == 0) | ||
| 106 | vcnum = 1; /* we can not reuse vc=0 safely, since some servers | ||
| 107 | reset all uids on that, but 1 is ok. */ | ||
| 108 | else | ||
| 109 | vcnum = i; | ||
| 110 | ses->vcnum = vcnum; | ||
| 111 | get_vc_num_exit: | ||
| 112 | spin_unlock(&cifs_tcp_ses_lock); | ||
| 113 | |||
| 114 | return cpu_to_le16(vcnum); | ||
| 115 | } | ||
| 116 | |||
| 117 | static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) | 35 | static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) |
| 118 | { | 36 | { |
| 119 | __u32 capabilities = 0; | 37 | __u32 capabilities = 0; |
| @@ -128,7 +46,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) | |||
| 128 | CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4, | 46 | CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4, |
| 129 | USHRT_MAX)); | 47 | USHRT_MAX)); |
| 130 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); | 48 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); |
| 131 | pSMB->req.VcNumber = get_next_vcnum(ses); | 49 | pSMB->req.VcNumber = __constant_cpu_to_le16(1); |
| 132 | 50 | ||
| 133 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ | 51 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ |
| 134 | 52 | ||
