diff options
author | Steve French <sfrench@us.ibm.com> | 2005-08-17 15:38:22 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-08-17 15:38:22 -0400 |
commit | 1982c344f1bf08118f7c224958b30c64e162009e (patch) | |
tree | b5268e345010421ca2625b29efc981c187c4df2e /fs | |
parent | a59c658607b63ec7b6c2536597a075ee307b1b4c (diff) |
[CIFS] Ensure that cifs multiplex ids do not collide.
Signed-off-by: Steve French (sfrench@us.ibm.com)
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifspdu.h | 19 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 6 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 23 | ||||
-rw-r--r-- | fs/cifs/connect.c | 9 | ||||
-rw-r--r-- | fs/cifs/misc.c | 84 |
6 files changed, 113 insertions, 29 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index d3773e57acf9..e8287f76484f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -147,6 +147,7 @@ struct TCP_Server_Info { | |||
147 | /* (returned on Negotiate */ | 147 | /* (returned on Negotiate */ |
148 | int capabilities; /* allow selective disabling of caps by smb sess */ | 148 | int capabilities; /* allow selective disabling of caps by smb sess */ |
149 | __u16 timeZone; | 149 | __u16 timeZone; |
150 | __u16 CurrentMid; /* multiplex id - rotating counter */ | ||
150 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; | 151 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; |
151 | char workstation_RFC1001_name[16]; /* 16th byte is always zero */ | 152 | char workstation_RFC1001_name[16]; /* 16th byte is always zero */ |
152 | __u32 sequence_number; /* needed for CIFS PDU signature */ | 153 | __u32 sequence_number; /* needed for CIFS PDU signature */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 3cef57b7a34f..49cc66825309 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -1961,18 +1961,17 @@ struct data_blob { | |||
1961 | perhaps add a CreateDevice - to create Pipes and other special .inodes | 1961 | perhaps add a CreateDevice - to create Pipes and other special .inodes |
1962 | Also note POSIX open flags | 1962 | Also note POSIX open flags |
1963 | 2) Close - to return the last write time to do cache across close more safely | 1963 | 2) Close - to return the last write time to do cache across close more safely |
1964 | 3) PosixQFSInfo - to return statfs info | 1964 | 3) FindFirst return unique inode number - what about resume key, two |
1965 | 4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes) | 1965 | forms short (matches readdir) and full (enough info to cache inodes) |
1966 | 5) Mkdir - set mode | 1966 | 4) Mkdir - set mode |
1967 | 1967 | ||
1968 | And under consideration: | 1968 | And under consideration: |
1969 | 6) FindClose2 (return nanosecond timestamp ??) | 1969 | 5) FindClose2 (return nanosecond timestamp ??) |
1970 | 7) Use nanosecond timestamps throughout all time fields if | 1970 | 6) Use nanosecond timestamps throughout all time fields if |
1971 | corresponding attribute flag is set | 1971 | corresponding attribute flag is set |
1972 | 8) sendfile - handle based copy | 1972 | 7) sendfile - handle based copy |
1973 | 9) Direct i/o | 1973 | 8) Direct i/o |
1974 | 10) "POSIX ACL" support | 1974 | 9) Misc fcntls? |
1975 | 11) Misc fcntls? | ||
1976 | 1975 | ||
1977 | what about fixing 64 bit alignment | 1976 | what about fixing 64 bit alignment |
1978 | 1977 | ||
@@ -2028,7 +2027,7 @@ struct data_blob { | |||
2028 | 2027 | ||
2029 | */ | 2028 | */ |
2030 | 2029 | ||
2031 | /* xsymlink is a symlink format that can be used | 2030 | /* xsymlink is a symlink format (used by MacOS) that can be used |
2032 | to save symlink info in a regular file when | 2031 | to save symlink info in a regular file when |
2033 | mounted to operating systems that do not | 2032 | mounted to operating systems that do not |
2034 | support the cifs Unix extensions or EAs (for xattr | 2033 | support the cifs Unix extensions or EAs (for xattr |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 66eaa6b40373..b9b13e3fe79d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -61,9 +61,9 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length, | |||
61 | extern int cifs_inet_pton(int, char * source, void *dst); | 61 | extern int cifs_inet_pton(int, char * source, void *dst); |
62 | extern int map_smb_to_linux_error(struct smb_hdr *smb); | 62 | extern int map_smb_to_linux_error(struct smb_hdr *smb); |
63 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 63 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
64 | const struct cifsTconInfo *, int /* specifies length | 64 | const struct cifsTconInfo *, int /* length of |
65 | of fixed section (word count) in two byte units */ | 65 | fixed section (word count) in two byte units */); |
66 | ); | 66 | extern __u16 GetNextMid(struct TCP_Server_Info *server); |
67 | extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, | 67 | extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, |
68 | struct cifsTconInfo *); | 68 | struct cifsTconInfo *); |
69 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 69 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1b073546f5d9..930be0927de2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -330,7 +330,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
330 | (void **) &pSMB, (void **) &pSMBr); | 330 | (void **) &pSMB, (void **) &pSMBr); |
331 | if (rc) | 331 | if (rc) |
332 | return rc; | 332 | return rc; |
333 | 333 | pSMB->hdr.Mid = GetNextMid(server); | |
334 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 334 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
335 | if (extended_security) | 335 | if (extended_security) |
336 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | 336 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; |
@@ -415,15 +415,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
415 | if(server->secMode & SECMODE_SIGN_REQUIRED) | 415 | if(server->secMode & SECMODE_SIGN_REQUIRED) |
416 | cERROR(1, | 416 | cERROR(1, |
417 | ("Server requires /proc/fs/cifs/PacketSigningEnabled")); | 417 | ("Server requires /proc/fs/cifs/PacketSigningEnabled")); |
418 | server->secMode &= ~(SECMODE_SIGN_ENABLED | | 418 | server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); |
419 | SECMODE_SIGN_REQUIRED); | ||
420 | } else if(sign_CIFS_PDUs == 1) { | 419 | } else if(sign_CIFS_PDUs == 1) { |
421 | if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) | 420 | if((server->secMode & SECMODE_SIGN_REQUIRED) == 0) |
422 | server->secMode &= ~(SECMODE_SIGN_ENABLED | | 421 | server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); |
423 | SECMODE_SIGN_REQUIRED); | ||
424 | } | 422 | } |
425 | 423 | ||
426 | } | 424 | } |
425 | |||
427 | cifs_buf_release(pSMB); | 426 | cifs_buf_release(pSMB); |
428 | return rc; | 427 | return rc; |
429 | } | 428 | } |
@@ -519,6 +518,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) | |||
519 | smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ | 518 | smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ |
520 | 519 | ||
521 | if(ses->server) { | 520 | if(ses->server) { |
521 | pSMB->hdr.Mid = GetNextMid(ses->server); | ||
522 | |||
522 | if(ses->server->secMode & | 523 | if(ses->server->secMode & |
523 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 524 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
524 | pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 525 | pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
@@ -2519,11 +2520,12 @@ findFirstRetry: | |||
2519 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 2520 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
2520 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 2521 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
2521 | 2522 | ||
2522 | if (rc) {/* BB add logic to retry regular search if Unix search | 2523 | if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ |
2523 | rejected unexpectedly by server */ | ||
2524 | /* BB Add code to handle unsupported level rc */ | 2524 | /* BB Add code to handle unsupported level rc */ |
2525 | cFYI(1, ("Error in FindFirst = %d", rc)); | 2525 | cFYI(1, ("Error in FindFirst = %d", rc)); |
2526 | cifs_buf_release(pSMB); | 2526 | |
2527 | if (pSMB) | ||
2528 | cifs_buf_release(pSMB); | ||
2527 | 2529 | ||
2528 | /* BB eventually could optimize out free and realloc of buf */ | 2530 | /* BB eventually could optimize out free and realloc of buf */ |
2529 | /* for this case */ | 2531 | /* for this case */ |
@@ -2857,7 +2859,10 @@ getDFSRetry: | |||
2857 | (void **) &pSMBr); | 2859 | (void **) &pSMBr); |
2858 | if (rc) | 2860 | if (rc) |
2859 | return rc; | 2861 | return rc; |
2860 | 2862 | ||
2863 | /* server pointer checked in called function, | ||
2864 | but should never be null here anyway */ | ||
2865 | pSMB->hdr.Mid = GetNextMid(ses->server); | ||
2861 | pSMB->hdr.Tid = ses->ipc_tid; | 2866 | pSMB->hdr.Tid = ses->ipc_tid; |
2862 | pSMB->hdr.Uid = ses->Suid; | 2867 | pSMB->hdr.Uid = ses->Suid; |
2863 | if (ses->capabilities & CAP_STATUS32) { | 2868 | if (ses->capabilities & CAP_STATUS32) { |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 36f78596c81a..9e8256003f73 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1857,6 +1857,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
1857 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, | 1857 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, |
1858 | NULL /* no tCon exists yet */ , 13 /* wct */ ); | 1858 | NULL /* no tCon exists yet */ , 13 /* wct */ ); |
1859 | 1859 | ||
1860 | smb_buffer->Mid = GetNextMid(ses->server); | ||
1860 | pSMB->req_no_secext.AndXCommand = 0xFF; | 1861 | pSMB->req_no_secext.AndXCommand = 0xFF; |
1861 | pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); | 1862 | pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); |
1862 | pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); | 1863 | pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); |
@@ -2132,6 +2133,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2132 | /* send SMBsessionSetup here */ | 2133 | /* send SMBsessionSetup here */ |
2133 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, | 2134 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, |
2134 | NULL /* no tCon exists yet */ , 12 /* wct */ ); | 2135 | NULL /* no tCon exists yet */ , 12 /* wct */ ); |
2136 | |||
2137 | smb_buffer->Mid = GetNextMid(ses->server); | ||
2135 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 2138 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
2136 | pSMB->req.AndXCommand = 0xFF; | 2139 | pSMB->req.AndXCommand = 0xFF; |
2137 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); | 2140 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); |
@@ -2398,6 +2401,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2398 | /* send SMBsessionSetup here */ | 2401 | /* send SMBsessionSetup here */ |
2399 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, | 2402 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, |
2400 | NULL /* no tCon exists yet */ , 12 /* wct */ ); | 2403 | NULL /* no tCon exists yet */ , 12 /* wct */ ); |
2404 | |||
2405 | smb_buffer->Mid = GetNextMid(ses->server); | ||
2401 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 2406 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
2402 | pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); | 2407 | pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); |
2403 | 2408 | ||
@@ -2740,6 +2745,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2740 | /* send SMBsessionSetup here */ | 2745 | /* send SMBsessionSetup here */ |
2741 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, | 2746 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, |
2742 | NULL /* no tCon exists yet */ , 12 /* wct */ ); | 2747 | NULL /* no tCon exists yet */ , 12 /* wct */ ); |
2748 | |||
2749 | smb_buffer->Mid = GetNextMid(ses->server); | ||
2743 | pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); | 2750 | pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); |
2744 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 2751 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
2745 | pSMB->req.AndXCommand = 0xFF; | 2752 | pSMB->req.AndXCommand = 0xFF; |
@@ -3111,6 +3118,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3111 | 3118 | ||
3112 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, | 3119 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, |
3113 | NULL /*no tid */ , 4 /*wct */ ); | 3120 | NULL /*no tid */ , 4 /*wct */ ); |
3121 | |||
3122 | smb_buffer->Mid = GetNextMid(ses->server); | ||
3114 | smb_buffer->Uid = ses->Suid; | 3123 | smb_buffer->Uid = ses->Suid; |
3115 | pSMB = (TCONX_REQ *) smb_buffer; | 3124 | pSMB = (TCONX_REQ *) smb_buffer; |
3116 | pSMBr = (TCONX_RSP *) smb_buffer_response; | 3125 | pSMBr = (TCONX_RSP *) smb_buffer_response; |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 20ae4153f791..beeff8284169 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -34,8 +34,6 @@ extern mempool_t *cifs_sm_req_poolp; | |||
34 | extern mempool_t *cifs_req_poolp; | 34 | extern mempool_t *cifs_req_poolp; |
35 | extern struct task_struct * oplockThread; | 35 | extern struct task_struct * oplockThread; |
36 | 36 | ||
37 | static __u16 GlobalMid; /* multiplex id - rotating counter */ | ||
38 | |||
39 | /* The xid serves as a useful identifier for each incoming vfs request, | 37 | /* The xid serves as a useful identifier for each incoming vfs request, |
40 | in a similar way to the mid which is useful to track each sent smb, | 38 | in a similar way to the mid which is useful to track each sent smb, |
41 | and CurrentXid can also provide a running counter (although it | 39 | and CurrentXid can also provide a running counter (although it |
@@ -51,6 +49,8 @@ _GetXid(void) | |||
51 | GlobalTotalActiveXid++; | 49 | GlobalTotalActiveXid++; |
52 | if (GlobalTotalActiveXid > GlobalMaxActiveXid) | 50 | if (GlobalTotalActiveXid > GlobalMaxActiveXid) |
53 | GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ | 51 | GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ |
52 | if(GlobalTotalActiveXid > 65000) | ||
53 | cFYI(1,("warning: more than 65000 requests active")); | ||
54 | xid = GlobalCurrentXid++; | 54 | xid = GlobalCurrentXid++; |
55 | spin_unlock(&GlobalMid_Lock); | 55 | spin_unlock(&GlobalMid_Lock); |
56 | return xid; | 56 | return xid; |
@@ -218,6 +218,76 @@ cifs_small_buf_release(void *buf_to_free) | |||
218 | return; | 218 | return; |
219 | } | 219 | } |
220 | 220 | ||
221 | /* | ||
222 | Find a free multiplex id (SMB mid). Otherwise there could be | ||
223 | mid collisions which might cause problems, demultiplexing the | ||
224 | wrong response to this request. Multiplex ids could collide if | ||
225 | one of a series requests takes much longer than the others, or | ||
226 | if a very large number of long lived requests (byte range | ||
227 | locks or FindNotify requests) are pending. No more than | ||
228 | 64K-1 requests can be outstanding at one time. If no | ||
229 | mids are available, return zero. A future optimization | ||
230 | could make the combination of mids and uid the key we use | ||
231 | to demultiplex on (rather than mid alone). | ||
232 | In addition to the above check, the cifs demultiplex | ||
233 | code already used the command code as a secondary | ||
234 | check of the frame and if signing is negotiated the | ||
235 | response would be discarded if the mid were the same | ||
236 | but the signature was wrong. Since the mid is not put in the | ||
237 | pending queue until later (when it is about to be dispatched) | ||
238 | we do have to limit the number of outstanding requests | ||
239 | to somewhat less than 64K-1 although it is hard to imagine | ||
240 | so many threads being in the vfs at one time. | ||
241 | */ | ||
242 | __u16 GetNextMid(struct TCP_Server_Info *server) | ||
243 | { | ||
244 | __u16 mid = 0; | ||
245 | __u16 last_mid; | ||
246 | int collision; | ||
247 | |||
248 | if(server == NULL) | ||
249 | return mid; | ||
250 | |||
251 | spin_lock(&GlobalMid_Lock); | ||
252 | last_mid = server->CurrentMid; /* we do not want to loop forever */ | ||
253 | server->CurrentMid++; | ||
254 | /* This nested loop looks more expensive than it is. | ||
255 | In practice the list of pending requests is short, | ||
256 | fewer than 50, and the mids are likely to be unique | ||
257 | on the first pass through the loop unless some request | ||
258 | takes longer than the 64 thousand requests before it | ||
259 | (and it would also have to have been a request that | ||
260 | did not time out) */ | ||
261 | while(server->CurrentMid != last_mid) { | ||
262 | struct list_head *tmp; | ||
263 | struct mid_q_entry *mid_entry; | ||
264 | |||
265 | collision = 0; | ||
266 | if(server->CurrentMid == 0) | ||
267 | server->CurrentMid++; | ||
268 | |||
269 | list_for_each(tmp, &server->pending_mid_q) { | ||
270 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | ||
271 | |||
272 | if ((mid_entry->mid == server->CurrentMid) && | ||
273 | (mid_entry->midState == MID_REQUEST_SUBMITTED)) { | ||
274 | /* This mid is in use, try a different one */ | ||
275 | collision = 1; | ||
276 | break; | ||
277 | } | ||
278 | } | ||
279 | if(collision == 0) { | ||
280 | mid = server->CurrentMid; | ||
281 | break; | ||
282 | } | ||
283 | server->CurrentMid++; | ||
284 | } | ||
285 | spin_unlock(&GlobalMid_Lock); | ||
286 | return mid; | ||
287 | } | ||
288 | |||
289 | /* NB: MID can not be set if treeCon not passed in, in that | ||
290 | case it is responsbility of caller to set the mid */ | ||
221 | void | 291 | void |
222 | header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | 292 | header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , |
223 | const struct cifsTconInfo *treeCon, int word_count | 293 | const struct cifsTconInfo *treeCon, int word_count |
@@ -233,7 +303,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
233 | (2 * word_count) + sizeof (struct smb_hdr) - | 303 | (2 * word_count) + sizeof (struct smb_hdr) - |
234 | 4 /* RFC 1001 length field does not count */ + | 304 | 4 /* RFC 1001 length field does not count */ + |
235 | 2 /* for bcc field itself */ ; | 305 | 2 /* for bcc field itself */ ; |
236 | /* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */ | 306 | /* Note that this is the only network field that has to be converted |
307 | to big endian and it is done just before we send it */ | ||
237 | 308 | ||
238 | buffer->Protocol[0] = 0xFF; | 309 | buffer->Protocol[0] = 0xFF; |
239 | buffer->Protocol[1] = 'S'; | 310 | buffer->Protocol[1] = 'S'; |
@@ -245,8 +316,6 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
245 | buffer->Pid = cpu_to_le16((__u16)current->tgid); | 316 | buffer->Pid = cpu_to_le16((__u16)current->tgid); |
246 | buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16)); | 317 | buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16)); |
247 | spin_lock(&GlobalMid_Lock); | 318 | spin_lock(&GlobalMid_Lock); |
248 | GlobalMid++; | ||
249 | buffer->Mid = GlobalMid; | ||
250 | spin_unlock(&GlobalMid_Lock); | 319 | spin_unlock(&GlobalMid_Lock); |
251 | if (treeCon) { | 320 | if (treeCon) { |
252 | buffer->Tid = treeCon->tid; | 321 | buffer->Tid = treeCon->tid; |
@@ -256,8 +325,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
256 | if (treeCon->ses->capabilities & CAP_STATUS32) { | 325 | if (treeCon->ses->capabilities & CAP_STATUS32) { |
257 | buffer->Flags2 |= SMBFLG2_ERR_STATUS; | 326 | buffer->Flags2 |= SMBFLG2_ERR_STATUS; |
258 | } | 327 | } |
259 | 328 | /* Uid is not converted */ | |
260 | buffer->Uid = treeCon->ses->Suid; /* always in LE format */ | 329 | buffer->Uid = treeCon->ses->Suid; |
330 | buffer->Mid = GetNextMid(treeCon->ses->server); | ||
261 | if(multiuser_mount != 0) { | 331 | if(multiuser_mount != 0) { |
262 | /* For the multiuser case, there are few obvious technically */ | 332 | /* For the multiuser case, there are few obvious technically */ |
263 | /* possible mechanisms to match the local linux user (uid) */ | 333 | /* possible mechanisms to match the local linux user (uid) */ |