Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

CIFS: Move get_next_mid to ops struct

Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>

authored by

Pavel Shilovsky and committed by
Steve French
88257360 7f0adb53

+103 -95
+7
fs/cifs/cifsglob.h
··· 174 174 void (*add_credits)(struct TCP_Server_Info *, const unsigned int); 175 175 void (*set_credits)(struct TCP_Server_Info *, const int); 176 176 int * (*get_credits_field)(struct TCP_Server_Info *); 177 + __u64 (*get_next_mid)(struct TCP_Server_Info *); 177 178 /* data offset from read response message */ 178 179 unsigned int (*read_data_offset)(char *); 179 180 /* data length from read response message */ ··· 398 397 set_credits(struct TCP_Server_Info *server, const int val) 399 398 { 400 399 server->ops->set_credits(server, val); 400 + } 401 + 402 + static inline __u64 403 + get_next_mid(struct TCP_Server_Info *server) 404 + { 405 + return server->ops->get_next_mid(server); 401 406 } 402 407 403 408 /*
-1
fs/cifs/cifsproto.h
··· 114 114 void **request_buf); 115 115 extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses, 116 116 const struct nls_table *nls_cp); 117 - extern __u64 GetNextMid(struct TCP_Server_Info *server); 118 117 extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 119 118 extern u64 cifs_UnixTimeToNT(struct timespec); 120 119 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
+4 -4
fs/cifs/cifssmb.c
··· 268 268 return rc; 269 269 270 270 buffer = (struct smb_hdr *)*request_buf; 271 - buffer->Mid = GetNextMid(ses->server); 271 + buffer->Mid = get_next_mid(ses->server); 272 272 if (ses->capabilities & CAP_UNICODE) 273 273 buffer->Flags2 |= SMBFLG2_UNICODE; 274 274 if (ses->capabilities & CAP_STATUS32) ··· 402 402 403 403 cFYI(1, "secFlags 0x%x", secFlags); 404 404 405 - pSMB->hdr.Mid = GetNextMid(server); 405 + pSMB->hdr.Mid = get_next_mid(server); 406 406 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 407 407 408 408 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) ··· 782 782 return rc; 783 783 } 784 784 785 - pSMB->hdr.Mid = GetNextMid(ses->server); 785 + pSMB->hdr.Mid = get_next_mid(ses->server); 786 786 787 787 if (ses->server->sec_mode & 788 788 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) ··· 4762 4762 4763 4763 /* server pointer checked in called function, 4764 4764 but should never be null here anyway */ 4765 - pSMB->hdr.Mid = GetNextMid(ses->server); 4765 + pSMB->hdr.Mid = get_next_mid(ses->server); 4766 4766 pSMB->hdr.Tid = ses->ipc_tid; 4767 4767 pSMB->hdr.Uid = ses->Suid; 4768 4768 if (ses->capabilities & CAP_STATUS32)
+1 -1
fs/cifs/connect.c
··· 3940 3940 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 3941 3941 NULL /*no tid */ , 4 /*wct */ ); 3942 3942 3943 - smb_buffer->Mid = GetNextMid(ses->server); 3943 + smb_buffer->Mid = get_next_mid(ses->server); 3944 3944 smb_buffer->Uid = ses->Suid; 3945 3945 pSMB = (TCONX_REQ *) smb_buffer; 3946 3946 pSMBr = (TCONX_RSP *) smb_buffer_response;
+1 -88
fs/cifs/misc.c
··· 212 212 return; 213 213 } 214 214 215 - /* 216 - * Find a free multiplex id (SMB mid). Otherwise there could be 217 - * mid collisions which might cause problems, demultiplexing the 218 - * wrong response to this request. Multiplex ids could collide if 219 - * one of a series requests takes much longer than the others, or 220 - * if a very large number of long lived requests (byte range 221 - * locks or FindNotify requests) are pending. No more than 222 - * 64K-1 requests can be outstanding at one time. If no 223 - * mids are available, return zero. A future optimization 224 - * could make the combination of mids and uid the key we use 225 - * to demultiplex on (rather than mid alone). 226 - * In addition to the above check, the cifs demultiplex 227 - * code already used the command code as a secondary 228 - * check of the frame and if signing is negotiated the 229 - * response would be discarded if the mid were the same 230 - * but the signature was wrong. Since the mid is not put in the 231 - * pending queue until later (when it is about to be dispatched) 232 - * we do have to limit the number of outstanding requests 233 - * to somewhat less than 64K-1 although it is hard to imagine 234 - * so many threads being in the vfs at one time. 235 - */ 236 - __u64 GetNextMid(struct TCP_Server_Info *server) 237 - { 238 - __u64 mid = 0; 239 - __u16 last_mid, cur_mid; 240 - bool collision; 241 - 242 - spin_lock(&GlobalMid_Lock); 243 - 244 - /* mid is 16 bit only for CIFS/SMB */ 245 - cur_mid = (__u16)((server->CurrentMid) & 0xffff); 246 - /* we do not want to loop forever */ 247 - last_mid = cur_mid; 248 - cur_mid++; 249 - 250 - /* 251 - * This nested loop looks more expensive than it is. 252 - * In practice the list of pending requests is short, 253 - * fewer than 50, and the mids are likely to be unique 254 - * on the first pass through the loop unless some request 255 - * takes longer than the 64 thousand requests before it 256 - * (and it would also have to have been a request that 257 - * did not time out). 258 - */ 259 - while (cur_mid != last_mid) { 260 - struct mid_q_entry *mid_entry; 261 - unsigned int num_mids; 262 - 263 - collision = false; 264 - if (cur_mid == 0) 265 - cur_mid++; 266 - 267 - num_mids = 0; 268 - list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 269 - ++num_mids; 270 - if (mid_entry->mid == cur_mid && 271 - mid_entry->mid_state == MID_REQUEST_SUBMITTED) { 272 - /* This mid is in use, try a different one */ 273 - collision = true; 274 - break; 275 - } 276 - } 277 - 278 - /* 279 - * if we have more than 32k mids in the list, then something 280 - * is very wrong. Possibly a local user is trying to DoS the 281 - * box by issuing long-running calls and SIGKILL'ing them. If 282 - * we get to 2^16 mids then we're in big trouble as this 283 - * function could loop forever. 284 - * 285 - * Go ahead and assign out the mid in this situation, but force 286 - * an eventual reconnect to clean out the pending_mid_q. 287 - */ 288 - if (num_mids > 32768) 289 - server->tcpStatus = CifsNeedReconnect; 290 - 291 - if (!collision) { 292 - mid = (__u64)cur_mid; 293 - server->CurrentMid = mid; 294 - break; 295 - } 296 - cur_mid++; 297 - } 298 - spin_unlock(&GlobalMid_Lock); 299 - return mid; 300 - } 301 - 302 215 /* NB: MID can not be set if treeCon not passed in, in that 303 216 case it is responsbility of caller to set the mid */ 304 217 void ··· 247 334 248 335 /* Uid is not converted */ 249 336 buffer->Uid = treeCon->ses->Suid; 250 - buffer->Mid = GetNextMid(treeCon->ses->server); 337 + buffer->Mid = get_next_mid(treeCon->ses->server); 251 338 } 252 339 if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) 253 340 buffer->Flags2 |= SMBFLG2_DFS;
+89
fs/cifs/smb1ops.c
··· 125 125 return &server->credits; 126 126 } 127 127 128 + /* 129 + * Find a free multiplex id (SMB mid). Otherwise there could be 130 + * mid collisions which might cause problems, demultiplexing the 131 + * wrong response to this request. Multiplex ids could collide if 132 + * one of a series requests takes much longer than the others, or 133 + * if a very large number of long lived requests (byte range 134 + * locks or FindNotify requests) are pending. No more than 135 + * 64K-1 requests can be outstanding at one time. If no 136 + * mids are available, return zero. A future optimization 137 + * could make the combination of mids and uid the key we use 138 + * to demultiplex on (rather than mid alone). 139 + * In addition to the above check, the cifs demultiplex 140 + * code already used the command code as a secondary 141 + * check of the frame and if signing is negotiated the 142 + * response would be discarded if the mid were the same 143 + * but the signature was wrong. Since the mid is not put in the 144 + * pending queue until later (when it is about to be dispatched) 145 + * we do have to limit the number of outstanding requests 146 + * to somewhat less than 64K-1 although it is hard to imagine 147 + * so many threads being in the vfs at one time. 148 + */ 149 + static __u64 150 + cifs_get_next_mid(struct TCP_Server_Info *server) 151 + { 152 + __u64 mid = 0; 153 + __u16 last_mid, cur_mid; 154 + bool collision; 155 + 156 + spin_lock(&GlobalMid_Lock); 157 + 158 + /* mid is 16 bit only for CIFS/SMB */ 159 + cur_mid = (__u16)((server->CurrentMid) & 0xffff); 160 + /* we do not want to loop forever */ 161 + last_mid = cur_mid; 162 + cur_mid++; 163 + 164 + /* 165 + * This nested loop looks more expensive than it is. 166 + * In practice the list of pending requests is short, 167 + * fewer than 50, and the mids are likely to be unique 168 + * on the first pass through the loop unless some request 169 + * takes longer than the 64 thousand requests before it 170 + * (and it would also have to have been a request that 171 + * did not time out). 172 + */ 173 + while (cur_mid != last_mid) { 174 + struct mid_q_entry *mid_entry; 175 + unsigned int num_mids; 176 + 177 + collision = false; 178 + if (cur_mid == 0) 179 + cur_mid++; 180 + 181 + num_mids = 0; 182 + list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { 183 + ++num_mids; 184 + if (mid_entry->mid == cur_mid && 185 + mid_entry->mid_state == MID_REQUEST_SUBMITTED) { 186 + /* This mid is in use, try a different one */ 187 + collision = true; 188 + break; 189 + } 190 + } 191 + 192 + /* 193 + * if we have more than 32k mids in the list, then something 194 + * is very wrong. Possibly a local user is trying to DoS the 195 + * box by issuing long-running calls and SIGKILL'ing them. If 196 + * we get to 2^16 mids then we're in big trouble as this 197 + * function could loop forever. 198 + * 199 + * Go ahead and assign out the mid in this situation, but force 200 + * an eventual reconnect to clean out the pending_mid_q. 201 + */ 202 + if (num_mids > 32768) 203 + server->tcpStatus = CifsNeedReconnect; 204 + 205 + if (!collision) { 206 + mid = (__u64)cur_mid; 207 + server->CurrentMid = mid; 208 + break; 209 + } 210 + cur_mid++; 211 + } 212 + spin_unlock(&GlobalMid_Lock); 213 + return mid; 214 + } 215 + 128 216 struct smb_version_operations smb1_operations = { 129 217 .send_cancel = send_nt_cancel, 130 218 .compare_fids = cifs_compare_fids, ··· 221 133 .add_credits = cifs_add_credits, 222 134 .set_credits = cifs_set_credits, 223 135 .get_credits_field = cifs_get_credits_field, 136 + .get_next_mid = cifs_get_next_mid, 224 137 .read_data_offset = cifs_read_data_offset, 225 138 .read_data_length = cifs_read_data_length, 226 139 .map_error = map_smb_to_linux_error,
+1 -1
fs/cifs/transport.c
··· 779 779 780 780 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; 781 781 pSMB->Timeout = 0; 782 - pSMB->hdr.Mid = GetNextMid(ses->server); 782 + pSMB->hdr.Mid = get_next_mid(ses->server); 783 783 784 784 return SendReceive(xid, ses, in_buf, out_buf, 785 785 &bytes_returned, 0);