aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c818
1 files changed, 477 insertions, 341 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d9566bf8f917..95c2ea67edfb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -48,6 +48,7 @@
48#include "nterr.h" 48#include "nterr.h"
49#include "rfc1002pdu.h" 49#include "rfc1002pdu.h"
50#include "cn_cifs.h" 50#include "cn_cifs.h"
51#include "fscache.h"
51 52
52#define CIFS_PORT 445 53#define CIFS_PORT 445
53#define RFC1001_PORT 139 54#define RFC1001_PORT 139
@@ -66,6 +67,7 @@ struct smb_vol {
66 char *iocharset; /* local code page for mapping to and from Unicode */ 67 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */ 68 char source_rfc1001_name[16]; /* netbios name of client */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ 69 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
70 uid_t cred_uid;
69 uid_t linux_uid; 71 uid_t linux_uid;
70 gid_t linux_gid; 72 gid_t linux_gid;
71 mode_t file_mode; 73 mode_t file_mode;
@@ -97,11 +99,13 @@ struct smb_vol {
97 bool noblocksnd:1; 99 bool noblocksnd:1;
98 bool noautotune:1; 100 bool noautotune:1;
99 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
102 bool fsc:1; /* enable fscache */
100 unsigned int rsize; 103 unsigned int rsize;
101 unsigned int wsize; 104 unsigned int wsize;
102 bool sockopt_tcp_nodelay:1; 105 bool sockopt_tcp_nodelay:1;
103 unsigned short int port; 106 unsigned short int port;
104 char *prepath; 107 char *prepath;
108 struct nls_table *local_nls;
105}; 109};
106 110
107static int ipv4_connect(struct TCP_Server_Info *server); 111static int ipv4_connect(struct TCP_Server_Info *server);
@@ -135,7 +139,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
135 spin_unlock(&GlobalMid_Lock); 139 spin_unlock(&GlobalMid_Lock);
136 server->maxBuf = 0; 140 server->maxBuf = 0;
137 141
138 cFYI(1, ("Reconnecting tcp session")); 142 cFYI(1, "Reconnecting tcp session");
139 143
140 /* before reconnecting the tcp session, mark the smb session (uid) 144 /* before reconnecting the tcp session, mark the smb session (uid)
141 and the tid bad so they are not used until reconnected */ 145 and the tid bad so they are not used until reconnected */
@@ -153,12 +157,12 @@ cifs_reconnect(struct TCP_Server_Info *server)
153 /* do not want to be sending data on a socket we are freeing */ 157 /* do not want to be sending data on a socket we are freeing */
154 mutex_lock(&server->srv_mutex); 158 mutex_lock(&server->srv_mutex);
155 if (server->ssocket) { 159 if (server->ssocket) {
156 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state, 160 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
157 server->ssocket->flags)); 161 server->ssocket->flags);
158 kernel_sock_shutdown(server->ssocket, SHUT_WR); 162 kernel_sock_shutdown(server->ssocket, SHUT_WR);
159 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx", 163 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
160 server->ssocket->state, 164 server->ssocket->state,
161 server->ssocket->flags)); 165 server->ssocket->flags);
162 sock_release(server->ssocket); 166 sock_release(server->ssocket);
163 server->ssocket = NULL; 167 server->ssocket = NULL;
164 } 168 }
@@ -187,7 +191,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
187 else 191 else
188 rc = ipv4_connect(server); 192 rc = ipv4_connect(server);
189 if (rc) { 193 if (rc) {
190 cFYI(1, ("reconnect error %d", rc)); 194 cFYI(1, "reconnect error %d", rc);
191 msleep(3000); 195 msleep(3000);
192 } else { 196 } else {
193 atomic_inc(&tcpSesReconnectCount); 197 atomic_inc(&tcpSesReconnectCount);
@@ -223,7 +227,7 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
223 /* check for plausible wct, bcc and t2 data and parm sizes */ 227 /* check for plausible wct, bcc and t2 data and parm sizes */
224 /* check for parm and data offset going beyond end of smb */ 228 /* check for parm and data offset going beyond end of smb */
225 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */ 229 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
226 cFYI(1, ("invalid transact2 word count")); 230 cFYI(1, "invalid transact2 word count");
227 return -EINVAL; 231 return -EINVAL;
228 } 232 }
229 233
@@ -237,15 +241,15 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
237 if (remaining == 0) 241 if (remaining == 0)
238 return 0; 242 return 0;
239 else if (remaining < 0) { 243 else if (remaining < 0) {
240 cFYI(1, ("total data %d smaller than data in frame %d", 244 cFYI(1, "total data %d smaller than data in frame %d",
241 total_data_size, data_in_this_rsp)); 245 total_data_size, data_in_this_rsp);
242 return -EINVAL; 246 return -EINVAL;
243 } else { 247 } else {
244 cFYI(1, ("missing %d bytes from transact2, check next response", 248 cFYI(1, "missing %d bytes from transact2, check next response",
245 remaining)); 249 remaining);
246 if (total_data_size > maxBufSize) { 250 if (total_data_size > maxBufSize) {
247 cERROR(1, ("TotalDataSize %d is over maximum buffer %d", 251 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
248 total_data_size, maxBufSize)); 252 total_data_size, maxBufSize);
249 return -EINVAL; 253 return -EINVAL;
250 } 254 }
251 return remaining; 255 return remaining;
@@ -267,7 +271,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
267 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount); 271 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
268 272
269 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) { 273 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
270 cFYI(1, ("total data size of primary and secondary t2 differ")); 274 cFYI(1, "total data size of primary and secondary t2 differ");
271 } 275 }
272 276
273 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount); 277 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
@@ -282,7 +286,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
282 286
283 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount); 287 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
284 if (remaining < total_in_buf2) { 288 if (remaining < total_in_buf2) {
285 cFYI(1, ("transact2 2nd response contains too much data")); 289 cFYI(1, "transact2 2nd response contains too much data");
286 } 290 }
287 291
288 /* find end of first SMB data area */ 292 /* find end of first SMB data area */
@@ -311,7 +315,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
311 pTargetSMB->smb_buf_length = byte_count; 315 pTargetSMB->smb_buf_length = byte_count;
312 316
313 if (remaining == total_in_buf2) { 317 if (remaining == total_in_buf2) {
314 cFYI(1, ("found the last secondary response")); 318 cFYI(1, "found the last secondary response");
315 return 0; /* we are done */ 319 return 0; /* we are done */
316 } else /* more responses to go */ 320 } else /* more responses to go */
317 return 1; 321 return 1;
@@ -339,7 +343,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
339 int reconnect; 343 int reconnect;
340 344
341 current->flags |= PF_MEMALLOC; 345 current->flags |= PF_MEMALLOC;
342 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); 346 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
343 347
344 length = atomic_inc_return(&tcpSesAllocCount); 348 length = atomic_inc_return(&tcpSesAllocCount);
345 if (length > 1) 349 if (length > 1)
@@ -353,7 +357,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
353 if (bigbuf == NULL) { 357 if (bigbuf == NULL) {
354 bigbuf = cifs_buf_get(); 358 bigbuf = cifs_buf_get();
355 if (!bigbuf) { 359 if (!bigbuf) {
356 cERROR(1, ("No memory for large SMB response")); 360 cERROR(1, "No memory for large SMB response");
357 msleep(3000); 361 msleep(3000);
358 /* retry will check if exiting */ 362 /* retry will check if exiting */
359 continue; 363 continue;
@@ -366,7 +370,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
366 if (smallbuf == NULL) { 370 if (smallbuf == NULL) {
367 smallbuf = cifs_small_buf_get(); 371 smallbuf = cifs_small_buf_get();
368 if (!smallbuf) { 372 if (!smallbuf) {
369 cERROR(1, ("No memory for SMB response")); 373 cERROR(1, "No memory for SMB response");
370 msleep(1000); 374 msleep(1000);
371 /* retry will check if exiting */ 375 /* retry will check if exiting */
372 continue; 376 continue;
@@ -391,9 +395,9 @@ incomplete_rcv:
391 if (server->tcpStatus == CifsExiting) { 395 if (server->tcpStatus == CifsExiting) {
392 break; 396 break;
393 } else if (server->tcpStatus == CifsNeedReconnect) { 397 } else if (server->tcpStatus == CifsNeedReconnect) {
394 cFYI(1, ("Reconnect after server stopped responding")); 398 cFYI(1, "Reconnect after server stopped responding");
395 cifs_reconnect(server); 399 cifs_reconnect(server);
396 cFYI(1, ("call to reconnect done")); 400 cFYI(1, "call to reconnect done");
397 csocket = server->ssocket; 401 csocket = server->ssocket;
398 continue; 402 continue;
399 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { 403 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
@@ -411,7 +415,7 @@ incomplete_rcv:
411 continue; 415 continue;
412 } else if (length <= 0) { 416 } else if (length <= 0) {
413 if (server->tcpStatus == CifsNew) { 417 if (server->tcpStatus == CifsNew) {
414 cFYI(1, ("tcp session abend after SMBnegprot")); 418 cFYI(1, "tcp session abend after SMBnegprot");
415 /* some servers kill the TCP session rather than 419 /* some servers kill the TCP session rather than
416 returning an SMB negprot error, in which 420 returning an SMB negprot error, in which
417 case reconnecting here is not going to help, 421 case reconnecting here is not going to help,
@@ -419,18 +423,18 @@ incomplete_rcv:
419 break; 423 break;
420 } 424 }
421 if (!try_to_freeze() && (length == -EINTR)) { 425 if (!try_to_freeze() && (length == -EINTR)) {
422 cFYI(1, ("cifsd thread killed")); 426 cFYI(1, "cifsd thread killed");
423 break; 427 break;
424 } 428 }
425 cFYI(1, ("Reconnect after unexpected peek error %d", 429 cFYI(1, "Reconnect after unexpected peek error %d",
426 length)); 430 length);
427 cifs_reconnect(server); 431 cifs_reconnect(server);
428 csocket = server->ssocket; 432 csocket = server->ssocket;
429 wake_up(&server->response_q); 433 wake_up(&server->response_q);
430 continue; 434 continue;
431 } else if (length < pdu_length) { 435 } else if (length < pdu_length) {
432 cFYI(1, ("requested %d bytes but only got %d bytes", 436 cFYI(1, "requested %d bytes but only got %d bytes",
433 pdu_length, length)); 437 pdu_length, length);
434 pdu_length -= length; 438 pdu_length -= length;
435 msleep(1); 439 msleep(1);
436 goto incomplete_rcv; 440 goto incomplete_rcv;
@@ -450,18 +454,18 @@ incomplete_rcv:
450 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length); 454 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
451 smb_buffer->smb_buf_length = pdu_length; 455 smb_buffer->smb_buf_length = pdu_length;
452 456
453 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4)); 457 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
454 458
455 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) { 459 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
456 continue; 460 continue;
457 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 461 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
458 cFYI(1, ("Good RFC 1002 session rsp")); 462 cFYI(1, "Good RFC 1002 session rsp");
459 continue; 463 continue;
460 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 464 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
461 /* we get this from Windows 98 instead of 465 /* we get this from Windows 98 instead of
462 an error on SMB negprot response */ 466 an error on SMB negprot response */
463 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)", 467 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
464 pdu_length)); 468 pdu_length);
465 if (server->tcpStatus == CifsNew) { 469 if (server->tcpStatus == CifsNew) {
466 /* if nack on negprot (rather than 470 /* if nack on negprot (rather than
467 ret of smb negprot error) reconnecting 471 ret of smb negprot error) reconnecting
@@ -484,7 +488,7 @@ incomplete_rcv:
484 continue; 488 continue;
485 } 489 }
486 } else if (temp != (char) 0) { 490 } else if (temp != (char) 0) {
487 cERROR(1, ("Unknown RFC 1002 frame")); 491 cERROR(1, "Unknown RFC 1002 frame");
488 cifs_dump_mem(" Received Data: ", (char *)smb_buffer, 492 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
489 length); 493 length);
490 cifs_reconnect(server); 494 cifs_reconnect(server);
@@ -495,8 +499,8 @@ incomplete_rcv:
495 /* else we have an SMB response */ 499 /* else we have an SMB response */
496 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || 500 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
497 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) { 501 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
498 cERROR(1, ("Invalid size SMB length %d pdu_length %d", 502 cERROR(1, "Invalid size SMB length %d pdu_length %d",
499 length, pdu_length+4)); 503 length, pdu_length+4);
500 cifs_reconnect(server); 504 cifs_reconnect(server);
501 csocket = server->ssocket; 505 csocket = server->ssocket;
502 wake_up(&server->response_q); 506 wake_up(&server->response_q);
@@ -539,8 +543,8 @@ incomplete_rcv:
539 length = 0; 543 length = 0;
540 continue; 544 continue;
541 } else if (length <= 0) { 545 } else if (length <= 0) {
542 cERROR(1, ("Received no data, expecting %d", 546 cERROR(1, "Received no data, expecting %d",
543 pdu_length - total_read)); 547 pdu_length - total_read);
544 cifs_reconnect(server); 548 cifs_reconnect(server);
545 csocket = server->ssocket; 549 csocket = server->ssocket;
546 reconnect = 1; 550 reconnect = 1;
@@ -588,7 +592,7 @@ incomplete_rcv:
588 } 592 }
589 } else { 593 } else {
590 if (!isLargeBuf) { 594 if (!isLargeBuf) {
591 cERROR(1,("1st trans2 resp needs bigbuf")); 595 cERROR(1, "1st trans2 resp needs bigbuf");
592 /* BB maybe we can fix this up, switch 596 /* BB maybe we can fix this up, switch
593 to already allocated large buffer? */ 597 to already allocated large buffer? */
594 } else { 598 } else {
@@ -630,8 +634,8 @@ multi_t2_fnd:
630 wake_up_process(task_to_wake); 634 wake_up_process(task_to_wake);
631 } else if (!is_valid_oplock_break(smb_buffer, server) && 635 } else if (!is_valid_oplock_break(smb_buffer, server) &&
632 !isMultiRsp) { 636 !isMultiRsp) {
633 cERROR(1, ("No task to wake, unknown frame received! " 637 cERROR(1, "No task to wake, unknown frame received! "
634 "NumMids %d", midCount.counter)); 638 "NumMids %d", midCount.counter);
635 cifs_dump_mem("Received Data is: ", (char *)smb_buffer, 639 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
636 sizeof(struct smb_hdr)); 640 sizeof(struct smb_hdr));
637#ifdef CONFIG_CIFS_DEBUG2 641#ifdef CONFIG_CIFS_DEBUG2
@@ -708,8 +712,8 @@ multi_t2_fnd:
708 list_for_each(tmp, &server->pending_mid_q) { 712 list_for_each(tmp, &server->pending_mid_q) {
709 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 713 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
710 if (mid_entry->midState == MID_REQUEST_SUBMITTED) { 714 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
711 cFYI(1, ("Clearing Mid 0x%x - waking up ", 715 cFYI(1, "Clearing Mid 0x%x - waking up ",
712 mid_entry->mid)); 716 mid_entry->mid);
713 task_to_wake = mid_entry->tsk; 717 task_to_wake = mid_entry->tsk;
714 if (task_to_wake) 718 if (task_to_wake)
715 wake_up_process(task_to_wake); 719 wake_up_process(task_to_wake);
@@ -728,7 +732,7 @@ multi_t2_fnd:
728 to wait at least 45 seconds before giving up 732 to wait at least 45 seconds before giving up
729 on a request getting a response and going ahead 733 on a request getting a response and going ahead
730 and killing cifsd */ 734 and killing cifsd */
731 cFYI(1, ("Wait for exit from demultiplex thread")); 735 cFYI(1, "Wait for exit from demultiplex thread");
732 msleep(46000); 736 msleep(46000);
733 /* if threads still have not exited they are probably never 737 /* if threads still have not exited they are probably never
734 coming home not much else we can do but free the memory */ 738 coming home not much else we can do but free the memory */
@@ -829,7 +833,8 @@ cifs_parse_mount_options(char *options, const char *devname,
829 /* null target name indicates to use *SMBSERVR default called name 833 /* null target name indicates to use *SMBSERVR default called name
830 if we end up sending RFC1001 session initialize */ 834 if we end up sending RFC1001 session initialize */
831 vol->target_rfc1001_name[0] = 0; 835 vol->target_rfc1001_name[0] = 0;
832 vol->linux_uid = current_uid(); /* use current_euid() instead? */ 836 vol->cred_uid = current_uid();
837 vol->linux_uid = current_uid();
833 vol->linux_gid = current_gid(); 838 vol->linux_gid = current_gid();
834 839
835 /* default to only allowing write access to owner of the mount */ 840 /* default to only allowing write access to owner of the mount */
@@ -849,7 +854,7 @@ cifs_parse_mount_options(char *options, const char *devname,
849 separator[0] = options[4]; 854 separator[0] = options[4];
850 options += 5; 855 options += 5;
851 } else { 856 } else {
852 cFYI(1, ("Null separator not allowed")); 857 cFYI(1, "Null separator not allowed");
853 } 858 }
854 } 859 }
855 860
@@ -974,7 +979,7 @@ cifs_parse_mount_options(char *options, const char *devname,
974 } 979 }
975 } else if (strnicmp(data, "sec", 3) == 0) { 980 } else if (strnicmp(data, "sec", 3) == 0) {
976 if (!value || !*value) { 981 if (!value || !*value) {
977 cERROR(1, ("no security value specified")); 982 cERROR(1, "no security value specified");
978 continue; 983 continue;
979 } else if (strnicmp(value, "krb5i", 5) == 0) { 984 } else if (strnicmp(value, "krb5i", 5) == 0) {
980 vol->secFlg |= CIFSSEC_MAY_KRB5 | 985 vol->secFlg |= CIFSSEC_MAY_KRB5 |
@@ -982,7 +987,7 @@ cifs_parse_mount_options(char *options, const char *devname,
982 } else if (strnicmp(value, "krb5p", 5) == 0) { 987 } else if (strnicmp(value, "krb5p", 5) == 0) {
983 /* vol->secFlg |= CIFSSEC_MUST_SEAL | 988 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
984 CIFSSEC_MAY_KRB5; */ 989 CIFSSEC_MAY_KRB5; */
985 cERROR(1, ("Krb5 cifs privacy not supported")); 990 cERROR(1, "Krb5 cifs privacy not supported");
986 return 1; 991 return 1;
987 } else if (strnicmp(value, "krb5", 4) == 0) { 992 } else if (strnicmp(value, "krb5", 4) == 0) {
988 vol->secFlg |= CIFSSEC_MAY_KRB5; 993 vol->secFlg |= CIFSSEC_MAY_KRB5;
@@ -1014,7 +1019,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1014 } else if (strnicmp(value, "none", 4) == 0) { 1019 } else if (strnicmp(value, "none", 4) == 0) {
1015 vol->nullauth = 1; 1020 vol->nullauth = 1;
1016 } else { 1021 } else {
1017 cERROR(1, ("bad security option: %s", value)); 1022 cERROR(1, "bad security option: %s", value);
1018 return 1; 1023 return 1;
1019 } 1024 }
1020 } else if ((strnicmp(data, "unc", 3) == 0) 1025 } else if ((strnicmp(data, "unc", 3) == 0)
@@ -1053,7 +1058,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1053 a domain name and need special handling? */ 1058 a domain name and need special handling? */
1054 if (strnlen(value, 256) < 256) { 1059 if (strnlen(value, 256) < 256) {
1055 vol->domainname = value; 1060 vol->domainname = value;
1056 cFYI(1, ("Domain name set")); 1061 cFYI(1, "Domain name set");
1057 } else { 1062 } else {
1058 printk(KERN_WARNING "CIFS: domain name too " 1063 printk(KERN_WARNING "CIFS: domain name too "
1059 "long\n"); 1064 "long\n");
@@ -1076,7 +1081,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1076 strcpy(vol->prepath+1, value); 1081 strcpy(vol->prepath+1, value);
1077 } else 1082 } else
1078 strcpy(vol->prepath, value); 1083 strcpy(vol->prepath, value);
1079 cFYI(1, ("prefix path %s", vol->prepath)); 1084 cFYI(1, "prefix path %s", vol->prepath);
1080 } else { 1085 } else {
1081 printk(KERN_WARNING "CIFS: prefix too long\n"); 1086 printk(KERN_WARNING "CIFS: prefix too long\n");
1082 return 1; 1087 return 1;
@@ -1092,7 +1097,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1092 vol->iocharset = value; 1097 vol->iocharset = value;
1093 /* if iocharset not set then load_nls_default 1098 /* if iocharset not set then load_nls_default
1094 is used by caller */ 1099 is used by caller */
1095 cFYI(1, ("iocharset set to %s", value)); 1100 cFYI(1, "iocharset set to %s", value);
1096 } else { 1101 } else {
1097 printk(KERN_WARNING "CIFS: iocharset name " 1102 printk(KERN_WARNING "CIFS: iocharset name "
1098 "too long.\n"); 1103 "too long.\n");
@@ -1144,14 +1149,14 @@ cifs_parse_mount_options(char *options, const char *devname,
1144 } 1149 }
1145 } else if (strnicmp(data, "sockopt", 5) == 0) { 1150 } else if (strnicmp(data, "sockopt", 5) == 0) {
1146 if (!value || !*value) { 1151 if (!value || !*value) {
1147 cERROR(1, ("no socket option specified")); 1152 cERROR(1, "no socket option specified");
1148 continue; 1153 continue;
1149 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) { 1154 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1150 vol->sockopt_tcp_nodelay = 1; 1155 vol->sockopt_tcp_nodelay = 1;
1151 } 1156 }
1152 } else if (strnicmp(data, "netbiosname", 4) == 0) { 1157 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1153 if (!value || !*value || (*value == ' ')) { 1158 if (!value || !*value || (*value == ' ')) {
1154 cFYI(1, ("invalid (empty) netbiosname")); 1159 cFYI(1, "invalid (empty) netbiosname");
1155 } else { 1160 } else {
1156 memset(vol->source_rfc1001_name, 0x20, 15); 1161 memset(vol->source_rfc1001_name, 0x20, 15);
1157 for (i = 0; i < 15; i++) { 1162 for (i = 0; i < 15; i++) {
@@ -1175,7 +1180,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1175 } else if (strnicmp(data, "servern", 7) == 0) { 1180 } else if (strnicmp(data, "servern", 7) == 0) {
1176 /* servernetbiosname specified override *SMBSERVER */ 1181 /* servernetbiosname specified override *SMBSERVER */
1177 if (!value || !*value || (*value == ' ')) { 1182 if (!value || !*value || (*value == ' ')) {
1178 cFYI(1, ("empty server netbiosname specified")); 1183 cFYI(1, "empty server netbiosname specified");
1179 } else { 1184 } else {
1180 /* last byte, type, is 0x20 for servr type */ 1185 /* last byte, type, is 0x20 for servr type */
1181 memset(vol->target_rfc1001_name, 0x20, 16); 1186 memset(vol->target_rfc1001_name, 0x20, 16);
@@ -1256,6 +1261,12 @@ cifs_parse_mount_options(char *options, const char *devname,
1256 } else if ((strnicmp(data, "nocase", 6) == 0) || 1261 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1257 (strnicmp(data, "ignorecase", 10) == 0)) { 1262 (strnicmp(data, "ignorecase", 10) == 0)) {
1258 vol->nocase = 1; 1263 vol->nocase = 1;
1264 } else if (strnicmp(data, "mand", 4) == 0) {
1265 /* ignore */
1266 } else if (strnicmp(data, "nomand", 6) == 0) {
1267 /* ignore */
1268 } else if (strnicmp(data, "_netdev", 7) == 0) {
1269 /* ignore */
1259 } else if (strnicmp(data, "brl", 3) == 0) { 1270 } else if (strnicmp(data, "brl", 3) == 0) {
1260 vol->nobrl = 0; 1271 vol->nobrl = 0;
1261 } else if ((strnicmp(data, "nobrl", 5) == 0) || 1272 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
@@ -1330,6 +1341,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1330 printk(KERN_WARNING "CIFS: Mount option noac not " 1341 printk(KERN_WARNING "CIFS: Mount option noac not "
1331 "supported. Instead set " 1342 "supported. Instead set "
1332 "/proc/fs/cifs/LookupCacheEnabled to 0\n"); 1343 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1344 } else if (strnicmp(data, "fsc", 3) == 0) {
1345 vol->fsc = true;
1333 } else 1346 } else
1334 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1347 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1335 data); 1348 data);
@@ -1379,18 +1392,92 @@ cifs_parse_mount_options(char *options, const char *devname,
1379 return 0; 1392 return 0;
1380} 1393}
1381 1394
1395static bool
1396match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1397{
1398 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1399 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1400
1401 switch (addr->sa_family) {
1402 case AF_INET:
1403 if (addr4->sin_addr.s_addr !=
1404 server->addr.sockAddr.sin_addr.s_addr)
1405 return false;
1406 if (addr4->sin_port &&
1407 addr4->sin_port != server->addr.sockAddr.sin_port)
1408 return false;
1409 break;
1410 case AF_INET6:
1411 if (!ipv6_addr_equal(&addr6->sin6_addr,
1412 &server->addr.sockAddr6.sin6_addr))
1413 return false;
1414 if (addr6->sin6_scope_id !=
1415 server->addr.sockAddr6.sin6_scope_id)
1416 return false;
1417 if (addr6->sin6_port &&
1418 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1419 return false;
1420 break;
1421 }
1422
1423 return true;
1424}
1425
1426static bool
1427match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1428{
1429 unsigned int secFlags;
1430
1431 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1432 secFlags = vol->secFlg;
1433 else
1434 secFlags = global_secflags | vol->secFlg;
1435
1436 switch (server->secType) {
1437 case LANMAN:
1438 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1439 return false;
1440 break;
1441 case NTLMv2:
1442 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1443 return false;
1444 break;
1445 case NTLM:
1446 if (!(secFlags & CIFSSEC_MAY_NTLM))
1447 return false;
1448 break;
1449 case Kerberos:
1450 if (!(secFlags & CIFSSEC_MAY_KRB5))
1451 return false;
1452 break;
1453 case RawNTLMSSP:
1454 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1455 return false;
1456 break;
1457 default:
1458 /* shouldn't happen */
1459 return false;
1460 }
1461
1462 /* now check if signing mode is acceptible */
1463 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1464 (server->secMode & SECMODE_SIGN_REQUIRED))
1465 return false;
1466 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1467 (server->secMode &
1468 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1469 return false;
1470
1471 return true;
1472}
1473
1382static struct TCP_Server_Info * 1474static struct TCP_Server_Info *
1383cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port) 1475cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1384{ 1476{
1385 struct list_head *tmp;
1386 struct TCP_Server_Info *server; 1477 struct TCP_Server_Info *server;
1387 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
1388 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
1389 1478
1390 write_lock(&cifs_tcp_ses_lock); 1479 write_lock(&cifs_tcp_ses_lock);
1391 list_for_each(tmp, &cifs_tcp_ses_list) { 1480 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1392 server = list_entry(tmp, struct TCP_Server_Info,
1393 tcp_ses_list);
1394 /* 1481 /*
1395 * the demux thread can exit on its own while still in CifsNew 1482 * the demux thread can exit on its own while still in CifsNew
1396 * so don't accept any sockets in that state. Since the 1483 * so don't accept any sockets in that state. Since the
@@ -1400,41 +1487,15 @@ cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
1400 if (server->tcpStatus == CifsNew) 1487 if (server->tcpStatus == CifsNew)
1401 continue; 1488 continue;
1402 1489
1403 switch (addr->ss_family) { 1490 if (!match_address(server, addr))
1404 case AF_INET: 1491 continue;
1405 if (addr4->sin_addr.s_addr ==
1406 server->addr.sockAddr.sin_addr.s_addr) {
1407 addr4->sin_port = htons(port);
1408 /* user overrode default port? */
1409 if (addr4->sin_port) {
1410 if (addr4->sin_port !=
1411 server->addr.sockAddr.sin_port)
1412 continue;
1413 }
1414 break;
1415 } else
1416 continue;
1417 1492
1418 case AF_INET6: 1493 if (!match_security(server, vol))
1419 if (ipv6_addr_equal(&addr6->sin6_addr, 1494 continue;
1420 &server->addr.sockAddr6.sin6_addr) &&
1421 (addr6->sin6_scope_id ==
1422 server->addr.sockAddr6.sin6_scope_id)) {
1423 addr6->sin6_port = htons(port);
1424 /* user overrode default port? */
1425 if (addr6->sin6_port) {
1426 if (addr6->sin6_port !=
1427 server->addr.sockAddr6.sin6_port)
1428 continue;
1429 }
1430 break;
1431 } else
1432 continue;
1433 }
1434 1495
1435 ++server->srv_count; 1496 ++server->srv_count;
1436 write_unlock(&cifs_tcp_ses_lock); 1497 write_unlock(&cifs_tcp_ses_lock);
1437 cFYI(1, ("Existing tcp session with server found")); 1498 cFYI(1, "Existing tcp session with server found");
1438 return server; 1499 return server;
1439 } 1500 }
1440 write_unlock(&cifs_tcp_ses_lock); 1501 write_unlock(&cifs_tcp_ses_lock);
@@ -1459,6 +1520,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1459 server->tcpStatus = CifsExiting; 1520 server->tcpStatus = CifsExiting;
1460 spin_unlock(&GlobalMid_Lock); 1521 spin_unlock(&GlobalMid_Lock);
1461 1522
1523 cifs_fscache_release_client_cookie(server);
1524
1462 task = xchg(&server->tsk, NULL); 1525 task = xchg(&server->tsk, NULL);
1463 if (task) 1526 if (task)
1464 force_sig(SIGKILL, task); 1527 force_sig(SIGKILL, task);
@@ -1475,10 +1538,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1475 1538
1476 memset(&addr, 0, sizeof(struct sockaddr_storage)); 1539 memset(&addr, 0, sizeof(struct sockaddr_storage));
1477 1540
1478 cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip)); 1541 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1479 1542
1480 if (volume_info->UNCip && volume_info->UNC) { 1543 if (volume_info->UNCip && volume_info->UNC) {
1481 rc = cifs_convert_address(volume_info->UNCip, &addr); 1544 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1545 volume_info->UNCip,
1546 strlen(volume_info->UNCip),
1547 volume_info->port);
1482 if (!rc) { 1548 if (!rc) {
1483 /* we failed translating address */ 1549 /* we failed translating address */
1484 rc = -EINVAL; 1550 rc = -EINVAL;
@@ -1487,19 +1553,18 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1487 } else if (volume_info->UNCip) { 1553 } else if (volume_info->UNCip) {
1488 /* BB using ip addr as tcp_ses name to connect to the 1554 /* BB using ip addr as tcp_ses name to connect to the
1489 DFS root below */ 1555 DFS root below */
1490 cERROR(1, ("Connecting to DFS root not implemented yet")); 1556 cERROR(1, "Connecting to DFS root not implemented yet");
1491 rc = -EINVAL; 1557 rc = -EINVAL;
1492 goto out_err; 1558 goto out_err;
1493 } else /* which tcp_sess DFS root would we conect to */ { 1559 } else /* which tcp_sess DFS root would we conect to */ {
1494 cERROR(1, 1560 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1495 ("CIFS mount error: No UNC path (e.g. -o " 1561 "unc=//192.168.1.100/public) specified");
1496 "unc=//192.168.1.100/public) specified"));
1497 rc = -EINVAL; 1562 rc = -EINVAL;
1498 goto out_err; 1563 goto out_err;
1499 } 1564 }
1500 1565
1501 /* see if we already have a matching tcp_ses */ 1566 /* see if we already have a matching tcp_ses */
1502 tcp_ses = cifs_find_tcp_session(&addr, volume_info->port); 1567 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1503 if (tcp_ses) 1568 if (tcp_ses)
1504 return tcp_ses; 1569 return tcp_ses;
1505 1570
@@ -1540,21 +1605,19 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1540 ++tcp_ses->srv_count; 1605 ++tcp_ses->srv_count;
1541 1606
1542 if (addr.ss_family == AF_INET6) { 1607 if (addr.ss_family == AF_INET6) {
1543 cFYI(1, ("attempting ipv6 connect")); 1608 cFYI(1, "attempting ipv6 connect");
1544 /* BB should we allow ipv6 on port 139? */ 1609 /* BB should we allow ipv6 on port 139? */
1545 /* other OS never observed in Wild doing 139 with v6 */ 1610 /* other OS never observed in Wild doing 139 with v6 */
1546 sin_server6->sin6_port = htons(volume_info->port);
1547 memcpy(&tcp_ses->addr.sockAddr6, sin_server6, 1611 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1548 sizeof(struct sockaddr_in6)); 1612 sizeof(struct sockaddr_in6));
1549 rc = ipv6_connect(tcp_ses); 1613 rc = ipv6_connect(tcp_ses);
1550 } else { 1614 } else {
1551 sin_server->sin_port = htons(volume_info->port);
1552 memcpy(&tcp_ses->addr.sockAddr, sin_server, 1615 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1553 sizeof(struct sockaddr_in)); 1616 sizeof(struct sockaddr_in));
1554 rc = ipv4_connect(tcp_ses); 1617 rc = ipv4_connect(tcp_ses);
1555 } 1618 }
1556 if (rc < 0) { 1619 if (rc < 0) {
1557 cERROR(1, ("Error connecting to socket. Aborting operation")); 1620 cERROR(1, "Error connecting to socket. Aborting operation");
1558 goto out_err; 1621 goto out_err;
1559 } 1622 }
1560 1623
@@ -1567,7 +1630,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1567 tcp_ses, "cifsd"); 1630 tcp_ses, "cifsd");
1568 if (IS_ERR(tcp_ses->tsk)) { 1631 if (IS_ERR(tcp_ses->tsk)) {
1569 rc = PTR_ERR(tcp_ses->tsk); 1632 rc = PTR_ERR(tcp_ses->tsk);
1570 cERROR(1, ("error %d create cifsd thread", rc)); 1633 cERROR(1, "error %d create cifsd thread", rc);
1571 module_put(THIS_MODULE); 1634 module_put(THIS_MODULE);
1572 goto out_err; 1635 goto out_err;
1573 } 1636 }
@@ -1577,6 +1640,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1577 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); 1640 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1578 write_unlock(&cifs_tcp_ses_lock); 1641 write_unlock(&cifs_tcp_ses_lock);
1579 1642
1643 cifs_fscache_get_client_cookie(tcp_ses);
1644
1580 return tcp_ses; 1645 return tcp_ses;
1581 1646
1582out_err: 1647out_err:
@@ -1591,17 +1656,27 @@ out_err:
1591} 1656}
1592 1657
1593static struct cifsSesInfo * 1658static struct cifsSesInfo *
1594cifs_find_smb_ses(struct TCP_Server_Info *server, char *username) 1659cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1595{ 1660{
1596 struct list_head *tmp;
1597 struct cifsSesInfo *ses; 1661 struct cifsSesInfo *ses;
1598 1662
1599 write_lock(&cifs_tcp_ses_lock); 1663 write_lock(&cifs_tcp_ses_lock);
1600 list_for_each(tmp, &server->smb_ses_list) { 1664 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1601 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 1665 switch (server->secType) {
1602 if (strncmp(ses->userName, username, MAX_USERNAME_SIZE)) 1666 case Kerberos:
1603 continue; 1667 if (vol->cred_uid != ses->cred_uid)
1604 1668 continue;
1669 break;
1670 default:
1671 /* anything else takes username/password */
1672 if (strncmp(ses->userName, vol->username,
1673 MAX_USERNAME_SIZE))
1674 continue;
1675 if (strlen(vol->username) != 0 &&
1676 strncmp(ses->password, vol->password,
1677 MAX_PASSWORD_SIZE))
1678 continue;
1679 }
1605 ++ses->ses_count; 1680 ++ses->ses_count;
1606 write_unlock(&cifs_tcp_ses_lock); 1681 write_unlock(&cifs_tcp_ses_lock);
1607 return ses; 1682 return ses;
@@ -1616,6 +1691,7 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1616 int xid; 1691 int xid;
1617 struct TCP_Server_Info *server = ses->server; 1692 struct TCP_Server_Info *server = ses->server;
1618 1693
1694 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1619 write_lock(&cifs_tcp_ses_lock); 1695 write_lock(&cifs_tcp_ses_lock);
1620 if (--ses->ses_count > 0) { 1696 if (--ses->ses_count > 0) {
1621 write_unlock(&cifs_tcp_ses_lock); 1697 write_unlock(&cifs_tcp_ses_lock);
@@ -1634,6 +1710,103 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1634 cifs_put_tcp_session(server); 1710 cifs_put_tcp_session(server);
1635} 1711}
1636 1712
1713static struct cifsSesInfo *
1714cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1715{
1716 int rc = -ENOMEM, xid;
1717 struct cifsSesInfo *ses;
1718
1719 xid = GetXid();
1720
1721 ses = cifs_find_smb_ses(server, volume_info);
1722 if (ses) {
1723 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1724
1725 /* existing SMB ses has a server reference already */
1726 cifs_put_tcp_session(server);
1727
1728 mutex_lock(&ses->session_mutex);
1729 rc = cifs_negotiate_protocol(xid, ses);
1730 if (rc) {
1731 mutex_unlock(&ses->session_mutex);
1732 /* problem -- put our ses reference */
1733 cifs_put_smb_ses(ses);
1734 FreeXid(xid);
1735 return ERR_PTR(rc);
1736 }
1737 if (ses->need_reconnect) {
1738 cFYI(1, "Session needs reconnect");
1739 rc = cifs_setup_session(xid, ses,
1740 volume_info->local_nls);
1741 if (rc) {
1742 mutex_unlock(&ses->session_mutex);
1743 /* problem -- put our reference */
1744 cifs_put_smb_ses(ses);
1745 FreeXid(xid);
1746 return ERR_PTR(rc);
1747 }
1748 }
1749 mutex_unlock(&ses->session_mutex);
1750 FreeXid(xid);
1751 return ses;
1752 }
1753
1754 cFYI(1, "Existing smb sess not found");
1755 ses = sesInfoAlloc();
1756 if (ses == NULL)
1757 goto get_ses_fail;
1758
1759 /* new SMB session uses our server ref */
1760 ses->server = server;
1761 if (server->addr.sockAddr6.sin6_family == AF_INET6)
1762 sprintf(ses->serverName, "%pI6",
1763 &server->addr.sockAddr6.sin6_addr);
1764 else
1765 sprintf(ses->serverName, "%pI4",
1766 &server->addr.sockAddr.sin_addr.s_addr);
1767
1768 if (volume_info->username)
1769 strncpy(ses->userName, volume_info->username,
1770 MAX_USERNAME_SIZE);
1771
1772 /* volume_info->password freed at unmount */
1773 if (volume_info->password) {
1774 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1775 if (!ses->password)
1776 goto get_ses_fail;
1777 }
1778 if (volume_info->domainname) {
1779 int len = strlen(volume_info->domainname);
1780 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1781 if (ses->domainName)
1782 strcpy(ses->domainName, volume_info->domainname);
1783 }
1784 ses->cred_uid = volume_info->cred_uid;
1785 ses->linux_uid = volume_info->linux_uid;
1786 ses->overrideSecFlg = volume_info->secFlg;
1787
1788 mutex_lock(&ses->session_mutex);
1789 rc = cifs_negotiate_protocol(xid, ses);
1790 if (!rc)
1791 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1792 mutex_unlock(&ses->session_mutex);
1793 if (rc)
1794 goto get_ses_fail;
1795
1796 /* success, put it on the list */
1797 write_lock(&cifs_tcp_ses_lock);
1798 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1799 write_unlock(&cifs_tcp_ses_lock);
1800
1801 FreeXid(xid);
1802 return ses;
1803
1804get_ses_fail:
1805 sesInfoFree(ses);
1806 FreeXid(xid);
1807 return ERR_PTR(rc);
1808}
1809
1637static struct cifsTconInfo * 1810static struct cifsTconInfo *
1638cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) 1811cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1639{ 1812{
@@ -1662,6 +1835,7 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
1662 int xid; 1835 int xid;
1663 struct cifsSesInfo *ses = tcon->ses; 1836 struct cifsSesInfo *ses = tcon->ses;
1664 1837
1838 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1665 write_lock(&cifs_tcp_ses_lock); 1839 write_lock(&cifs_tcp_ses_lock);
1666 if (--tcon->tc_count > 0) { 1840 if (--tcon->tc_count > 0) {
1667 write_unlock(&cifs_tcp_ses_lock); 1841 write_unlock(&cifs_tcp_ses_lock);
@@ -1675,10 +1849,87 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
1675 CIFSSMBTDis(xid, tcon); 1849 CIFSSMBTDis(xid, tcon);
1676 _FreeXid(xid); 1850 _FreeXid(xid);
1677 1851
1852 cifs_fscache_release_super_cookie(tcon);
1678 tconInfoFree(tcon); 1853 tconInfoFree(tcon);
1679 cifs_put_smb_ses(ses); 1854 cifs_put_smb_ses(ses);
1680} 1855}
1681 1856
1857static struct cifsTconInfo *
1858cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1859{
1860 int rc, xid;
1861 struct cifsTconInfo *tcon;
1862
1863 tcon = cifs_find_tcon(ses, volume_info->UNC);
1864 if (tcon) {
1865 cFYI(1, "Found match on UNC path");
1866 /* existing tcon already has a reference */
1867 cifs_put_smb_ses(ses);
1868 if (tcon->seal != volume_info->seal)
1869 cERROR(1, "transport encryption setting "
1870 "conflicts with existing tid");
1871 return tcon;
1872 }
1873
1874 tcon = tconInfoAlloc();
1875 if (tcon == NULL) {
1876 rc = -ENOMEM;
1877 goto out_fail;
1878 }
1879
1880 tcon->ses = ses;
1881 if (volume_info->password) {
1882 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1883 if (!tcon->password) {
1884 rc = -ENOMEM;
1885 goto out_fail;
1886 }
1887 }
1888
1889 if (strchr(volume_info->UNC + 3, '\\') == NULL
1890 && strchr(volume_info->UNC + 3, '/') == NULL) {
1891 cERROR(1, "Missing share name");
1892 rc = -ENODEV;
1893 goto out_fail;
1894 }
1895
1896 /* BB Do we need to wrap session_mutex around
1897 * this TCon call and Unix SetFS as
1898 * we do on SessSetup and reconnect? */
1899 xid = GetXid();
1900 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
1901 FreeXid(xid);
1902 cFYI(1, "CIFS Tcon rc = %d", rc);
1903 if (rc)
1904 goto out_fail;
1905
1906 if (volume_info->nodfs) {
1907 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
1908 cFYI(1, "DFS disabled (%d)", tcon->Flags);
1909 }
1910 tcon->seal = volume_info->seal;
1911 /* we can have only one retry value for a connection
1912 to a share so for resources mounted more than once
1913 to the same server share the last value passed in
1914 for the retry flag is used */
1915 tcon->retry = volume_info->retry;
1916 tcon->nocase = volume_info->nocase;
1917 tcon->local_lease = volume_info->local_lease;
1918
1919 write_lock(&cifs_tcp_ses_lock);
1920 list_add(&tcon->tcon_list, &ses->tcon_list);
1921 write_unlock(&cifs_tcp_ses_lock);
1922
1923 cifs_fscache_get_super_cookie(tcon);
1924
1925 return tcon;
1926
1927out_fail:
1928 tconInfoFree(tcon);
1929 return ERR_PTR(rc);
1930}
1931
1932
1682int 1933int
1683get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 1934get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1684 const struct nls_table *nls_codepage, unsigned int *pnum_referrals, 1935 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
@@ -1703,8 +1954,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1703 strcpy(temp_unc + 2, pSesInfo->serverName); 1954 strcpy(temp_unc + 2, pSesInfo->serverName);
1704 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$"); 1955 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1705 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); 1956 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1706 cFYI(1, 1957 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
1707 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1708 kfree(temp_unc); 1958 kfree(temp_unc);
1709 } 1959 }
1710 if (rc == 0) 1960 if (rc == 0)
@@ -1777,12 +2027,12 @@ ipv4_connect(struct TCP_Server_Info *server)
1777 rc = sock_create_kern(PF_INET, SOCK_STREAM, 2027 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1778 IPPROTO_TCP, &socket); 2028 IPPROTO_TCP, &socket);
1779 if (rc < 0) { 2029 if (rc < 0) {
1780 cERROR(1, ("Error %d creating socket", rc)); 2030 cERROR(1, "Error %d creating socket", rc);
1781 return rc; 2031 return rc;
1782 } 2032 }
1783 2033
1784 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2034 /* BB other socket options to set KEEPALIVE, NODELAY? */
1785 cFYI(1, ("Socket created")); 2035 cFYI(1, "Socket created");
1786 server->ssocket = socket; 2036 server->ssocket = socket;
1787 socket->sk->sk_allocation = GFP_NOFS; 2037 socket->sk->sk_allocation = GFP_NOFS;
1788 cifs_reclassify_socket4(socket); 2038 cifs_reclassify_socket4(socket);
@@ -1827,7 +2077,7 @@ ipv4_connect(struct TCP_Server_Info *server)
1827 if (!connected) { 2077 if (!connected) {
1828 if (orig_port) 2078 if (orig_port)
1829 server->addr.sockAddr.sin_port = orig_port; 2079 server->addr.sockAddr.sin_port = orig_port;
1830 cFYI(1, ("Error %d connecting to server via ipv4", rc)); 2080 cFYI(1, "Error %d connecting to server via ipv4", rc);
1831 sock_release(socket); 2081 sock_release(socket);
1832 server->ssocket = NULL; 2082 server->ssocket = NULL;
1833 return rc; 2083 return rc;
@@ -1855,12 +2105,12 @@ ipv4_connect(struct TCP_Server_Info *server)
1855 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2105 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
1856 (char *)&val, sizeof(val)); 2106 (char *)&val, sizeof(val));
1857 if (rc) 2107 if (rc)
1858 cFYI(1, ("set TCP_NODELAY socket option error %d", rc)); 2108 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
1859 } 2109 }
1860 2110
1861 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", 2111 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1862 socket->sk->sk_sndbuf, 2112 socket->sk->sk_sndbuf,
1863 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo)); 2113 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
1864 2114
1865 /* send RFC1001 sessinit */ 2115 /* send RFC1001 sessinit */
1866 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { 2116 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
@@ -1938,13 +2188,13 @@ ipv6_connect(struct TCP_Server_Info *server)
1938 rc = sock_create_kern(PF_INET6, SOCK_STREAM, 2188 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1939 IPPROTO_TCP, &socket); 2189 IPPROTO_TCP, &socket);
1940 if (rc < 0) { 2190 if (rc < 0) {
1941 cERROR(1, ("Error %d creating ipv6 socket", rc)); 2191 cERROR(1, "Error %d creating ipv6 socket", rc);
1942 socket = NULL; 2192 socket = NULL;
1943 return rc; 2193 return rc;
1944 } 2194 }
1945 2195
1946 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2196 /* BB other socket options to set KEEPALIVE, NODELAY? */
1947 cFYI(1, ("ipv6 Socket created")); 2197 cFYI(1, "ipv6 Socket created");
1948 server->ssocket = socket; 2198 server->ssocket = socket;
1949 socket->sk->sk_allocation = GFP_NOFS; 2199 socket->sk->sk_allocation = GFP_NOFS;
1950 cifs_reclassify_socket6(socket); 2200 cifs_reclassify_socket6(socket);
@@ -1988,7 +2238,7 @@ ipv6_connect(struct TCP_Server_Info *server)
1988 if (!connected) { 2238 if (!connected) {
1989 if (orig_port) 2239 if (orig_port)
1990 server->addr.sockAddr6.sin6_port = orig_port; 2240 server->addr.sockAddr6.sin6_port = orig_port;
1991 cFYI(1, ("Error %d connecting to server via ipv6", rc)); 2241 cFYI(1, "Error %d connecting to server via ipv6", rc);
1992 sock_release(socket); 2242 sock_release(socket);
1993 server->ssocket = NULL; 2243 server->ssocket = NULL;
1994 return rc; 2244 return rc;
@@ -2007,7 +2257,7 @@ ipv6_connect(struct TCP_Server_Info *server)
2007 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2257 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2008 (char *)&val, sizeof(val)); 2258 (char *)&val, sizeof(val));
2009 if (rc) 2259 if (rc)
2010 cFYI(1, ("set TCP_NODELAY socket option error %d", rc)); 2260 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2011 } 2261 }
2012 2262
2013 server->ssocket = socket; 2263 server->ssocket = socket;
@@ -2032,13 +2282,13 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2032 if (vol_info && vol_info->no_linux_ext) { 2282 if (vol_info && vol_info->no_linux_ext) {
2033 tcon->fsUnixInfo.Capability = 0; 2283 tcon->fsUnixInfo.Capability = 0;
2034 tcon->unix_ext = 0; /* Unix Extensions disabled */ 2284 tcon->unix_ext = 0; /* Unix Extensions disabled */
2035 cFYI(1, ("Linux protocol extensions disabled")); 2285 cFYI(1, "Linux protocol extensions disabled");
2036 return; 2286 return;
2037 } else if (vol_info) 2287 } else if (vol_info)
2038 tcon->unix_ext = 1; /* Unix Extensions supported */ 2288 tcon->unix_ext = 1; /* Unix Extensions supported */
2039 2289
2040 if (tcon->unix_ext == 0) { 2290 if (tcon->unix_ext == 0) {
2041 cFYI(1, ("Unix extensions disabled so not set on reconnect")); 2291 cFYI(1, "Unix extensions disabled so not set on reconnect");
2042 return; 2292 return;
2043 } 2293 }
2044 2294
@@ -2054,12 +2304,11 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2054 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2304 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2055 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { 2305 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2056 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 2306 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2057 cERROR(1, ("POSIXPATH support change")); 2307 cERROR(1, "POSIXPATH support change");
2058 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2308 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2059 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { 2309 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2060 cERROR(1, ("possible reconnect error")); 2310 cERROR(1, "possible reconnect error");
2061 cERROR(1, 2311 cERROR(1, "server disabled POSIX path support");
2062 ("server disabled POSIX path support"));
2063 } 2312 }
2064 } 2313 }
2065 2314
@@ -2067,7 +2316,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2067 if (vol_info && vol_info->no_psx_acl) 2316 if (vol_info && vol_info->no_psx_acl)
2068 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2317 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2069 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { 2318 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2070 cFYI(1, ("negotiated posix acl support")); 2319 cFYI(1, "negotiated posix acl support");
2071 if (sb) 2320 if (sb)
2072 sb->s_flags |= MS_POSIXACL; 2321 sb->s_flags |= MS_POSIXACL;
2073 } 2322 }
@@ -2075,7 +2324,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2075 if (vol_info && vol_info->posix_paths == 0) 2324 if (vol_info && vol_info->posix_paths == 0)
2076 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2325 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2077 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 2326 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2078 cFYI(1, ("negotiate posix pathnames")); 2327 cFYI(1, "negotiate posix pathnames");
2079 if (sb) 2328 if (sb)
2080 CIFS_SB(sb)->mnt_cifs_flags |= 2329 CIFS_SB(sb)->mnt_cifs_flags |=
2081 CIFS_MOUNT_POSIX_PATHS; 2330 CIFS_MOUNT_POSIX_PATHS;
@@ -2090,39 +2339,38 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2090 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2339 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2091 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2340 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2092 CIFS_SB(sb)->rsize = 127 * 1024; 2341 CIFS_SB(sb)->rsize = 127 * 1024;
2093 cFYI(DBG2, 2342 cFYI(DBG2, "larger reads not supported by srv");
2094 ("larger reads not supported by srv"));
2095 } 2343 }
2096 } 2344 }
2097 2345
2098 2346
2099 cFYI(1, ("Negotiate caps 0x%x", (int)cap)); 2347 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2100#ifdef CONFIG_CIFS_DEBUG2 2348#ifdef CONFIG_CIFS_DEBUG2
2101 if (cap & CIFS_UNIX_FCNTL_CAP) 2349 if (cap & CIFS_UNIX_FCNTL_CAP)
2102 cFYI(1, ("FCNTL cap")); 2350 cFYI(1, "FCNTL cap");
2103 if (cap & CIFS_UNIX_EXTATTR_CAP) 2351 if (cap & CIFS_UNIX_EXTATTR_CAP)
2104 cFYI(1, ("EXTATTR cap")); 2352 cFYI(1, "EXTATTR cap");
2105 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) 2353 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2106 cFYI(1, ("POSIX path cap")); 2354 cFYI(1, "POSIX path cap");
2107 if (cap & CIFS_UNIX_XATTR_CAP) 2355 if (cap & CIFS_UNIX_XATTR_CAP)
2108 cFYI(1, ("XATTR cap")); 2356 cFYI(1, "XATTR cap");
2109 if (cap & CIFS_UNIX_POSIX_ACL_CAP) 2357 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2110 cFYI(1, ("POSIX ACL cap")); 2358 cFYI(1, "POSIX ACL cap");
2111 if (cap & CIFS_UNIX_LARGE_READ_CAP) 2359 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2112 cFYI(1, ("very large read cap")); 2360 cFYI(1, "very large read cap");
2113 if (cap & CIFS_UNIX_LARGE_WRITE_CAP) 2361 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2114 cFYI(1, ("very large write cap")); 2362 cFYI(1, "very large write cap");
2115#endif /* CIFS_DEBUG2 */ 2363#endif /* CIFS_DEBUG2 */
2116 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 2364 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2117 if (vol_info == NULL) { 2365 if (vol_info == NULL) {
2118 cFYI(1, ("resetting capabilities failed")); 2366 cFYI(1, "resetting capabilities failed");
2119 } else 2367 } else
2120 cERROR(1, ("Negotiating Unix capabilities " 2368 cERROR(1, "Negotiating Unix capabilities "
2121 "with the server failed. Consider " 2369 "with the server failed. Consider "
2122 "mounting with the Unix Extensions\n" 2370 "mounting with the Unix Extensions\n"
2123 "disabled, if problems are found, " 2371 "disabled, if problems are found, "
2124 "by specifying the nounix mount " 2372 "by specifying the nounix mount "
2125 "option.")); 2373 "option.");
2126 2374
2127 } 2375 }
2128 } 2376 }
@@ -2152,8 +2400,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2152 struct cifs_sb_info *cifs_sb) 2400 struct cifs_sb_info *cifs_sb)
2153{ 2401{
2154 if (pvolume_info->rsize > CIFSMaxBufSize) { 2402 if (pvolume_info->rsize > CIFSMaxBufSize) {
2155 cERROR(1, ("rsize %d too large, using MaxBufSize", 2403 cERROR(1, "rsize %d too large, using MaxBufSize",
2156 pvolume_info->rsize)); 2404 pvolume_info->rsize);
2157 cifs_sb->rsize = CIFSMaxBufSize; 2405 cifs_sb->rsize = CIFSMaxBufSize;
2158 } else if ((pvolume_info->rsize) && 2406 } else if ((pvolume_info->rsize) &&
2159 (pvolume_info->rsize <= CIFSMaxBufSize)) 2407 (pvolume_info->rsize <= CIFSMaxBufSize))
@@ -2162,8 +2410,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2162 cifs_sb->rsize = CIFSMaxBufSize; 2410 cifs_sb->rsize = CIFSMaxBufSize;
2163 2411
2164 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { 2412 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2165 cERROR(1, ("wsize %d too large, using 4096 instead", 2413 cERROR(1, "wsize %d too large, using 4096 instead",
2166 pvolume_info->wsize)); 2414 pvolume_info->wsize);
2167 cifs_sb->wsize = 4096; 2415 cifs_sb->wsize = 4096;
2168 } else if (pvolume_info->wsize) 2416 } else if (pvolume_info->wsize)
2169 cifs_sb->wsize = pvolume_info->wsize; 2417 cifs_sb->wsize = pvolume_info->wsize;
@@ -2181,7 +2429,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2181 if (cifs_sb->rsize < 2048) { 2429 if (cifs_sb->rsize < 2048) {
2182 cifs_sb->rsize = 2048; 2430 cifs_sb->rsize = 2048;
2183 /* Windows ME may prefer this */ 2431 /* Windows ME may prefer this */
2184 cFYI(1, ("readsize set to minimum: 2048")); 2432 cFYI(1, "readsize set to minimum: 2048");
2185 } 2433 }
2186 /* calculate prepath */ 2434 /* calculate prepath */
2187 cifs_sb->prepath = pvolume_info->prepath; 2435 cifs_sb->prepath = pvolume_info->prepath;
@@ -2199,8 +2447,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2199 cifs_sb->mnt_gid = pvolume_info->linux_gid; 2447 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2200 cifs_sb->mnt_file_mode = pvolume_info->file_mode; 2448 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2201 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; 2449 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2202 cFYI(1, ("file mode: 0x%x dir mode: 0x%x", 2450 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2203 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode)); 2451 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2204 2452
2205 if (pvolume_info->noperm) 2453 if (pvolume_info->noperm)
2206 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2454 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -2228,14 +2476,16 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2228 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; 2476 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2229 if (pvolume_info->dynperm) 2477 if (pvolume_info->dynperm)
2230 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; 2478 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2479 if (pvolume_info->fsc)
2480 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2231 if (pvolume_info->direct_io) { 2481 if (pvolume_info->direct_io) {
2232 cFYI(1, ("mounting share using direct i/o")); 2482 cFYI(1, "mounting share using direct i/o");
2233 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2483 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2234 } 2484 }
2235 2485
2236 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) 2486 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2237 cERROR(1, ("mount option dynperm ignored if cifsacl " 2487 cERROR(1, "mount option dynperm ignored if cifsacl "
2238 "mount option supported")); 2488 "mount option supported");
2239} 2489}
2240 2490
2241static int 2491static int
@@ -2262,7 +2512,7 @@ cleanup_volume_info(struct smb_vol **pvolume_info)
2262{ 2512{
2263 struct smb_vol *volume_info; 2513 struct smb_vol *volume_info;
2264 2514
2265 if (!pvolume_info && !*pvolume_info) 2515 if (!pvolume_info || !*pvolume_info)
2266 return; 2516 return;
2267 2517
2268 volume_info = *pvolume_info; 2518 volume_info = *pvolume_info;
@@ -2344,11 +2594,11 @@ try_mount_again:
2344 } 2594 }
2345 2595
2346 if (volume_info->nullauth) { 2596 if (volume_info->nullauth) {
2347 cFYI(1, ("null user")); 2597 cFYI(1, "null user");
2348 volume_info->username = ""; 2598 volume_info->username = "";
2349 } else if (volume_info->username) { 2599 } else if (volume_info->username) {
2350 /* BB fixme parse for domain name here */ 2600 /* BB fixme parse for domain name here */
2351 cFYI(1, ("Username: %s", volume_info->username)); 2601 cFYI(1, "Username: %s", volume_info->username);
2352 } else { 2602 } else {
2353 cifserror("No username specified"); 2603 cifserror("No username specified");
2354 /* In userspace mount helper we can get user name from alternate 2604 /* In userspace mount helper we can get user name from alternate
@@ -2357,20 +2607,20 @@ try_mount_again:
2357 goto out; 2607 goto out;
2358 } 2608 }
2359 2609
2360
2361 /* this is needed for ASCII cp to Unicode converts */ 2610 /* this is needed for ASCII cp to Unicode converts */
2362 if (volume_info->iocharset == NULL) { 2611 if (volume_info->iocharset == NULL) {
2363 cifs_sb->local_nls = load_nls_default(); 2612 /* load_nls_default cannot return null */
2364 /* load_nls_default can not return null */ 2613 volume_info->local_nls = load_nls_default();
2365 } else { 2614 } else {
2366 cifs_sb->local_nls = load_nls(volume_info->iocharset); 2615 volume_info->local_nls = load_nls(volume_info->iocharset);
2367 if (cifs_sb->local_nls == NULL) { 2616 if (volume_info->local_nls == NULL) {
2368 cERROR(1, ("CIFS mount error: iocharset %s not found", 2617 cERROR(1, "CIFS mount error: iocharset %s not found",
2369 volume_info->iocharset)); 2618 volume_info->iocharset);
2370 rc = -ELIBACC; 2619 rc = -ELIBACC;
2371 goto out; 2620 goto out;
2372 } 2621 }
2373 } 2622 }
2623 cifs_sb->local_nls = volume_info->local_nls;
2374 2624
2375 /* get a reference to a tcp session */ 2625 /* get a reference to a tcp session */
2376 srvTcp = cifs_get_tcp_session(volume_info); 2626 srvTcp = cifs_get_tcp_session(volume_info);
@@ -2379,148 +2629,30 @@ try_mount_again:
2379 goto out; 2629 goto out;
2380 } 2630 }
2381 2631
2382 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); 2632 /* get a reference to a SMB session */
2383 if (pSesInfo) { 2633 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2384 cFYI(1, ("Existing smb sess found (status=%d)", 2634 if (IS_ERR(pSesInfo)) {
2385 pSesInfo->status)); 2635 rc = PTR_ERR(pSesInfo);
2386 /* 2636 pSesInfo = NULL;
2387 * The existing SMB session already has a reference to srvTcp, 2637 goto mount_fail_check;
2388 * so we can put back the extra one we got before
2389 */
2390 cifs_put_tcp_session(srvTcp);
2391
2392 mutex_lock(&pSesInfo->session_mutex);
2393 if (pSesInfo->need_reconnect) {
2394 cFYI(1, ("Session needs reconnect"));
2395 rc = cifs_setup_session(xid, pSesInfo,
2396 cifs_sb->local_nls);
2397 }
2398 mutex_unlock(&pSesInfo->session_mutex);
2399 } else if (!rc) {
2400 cFYI(1, ("Existing smb sess not found"));
2401 pSesInfo = sesInfoAlloc();
2402 if (pSesInfo == NULL) {
2403 rc = -ENOMEM;
2404 goto mount_fail_check;
2405 }
2406
2407 /* new SMB session uses our srvTcp ref */
2408 pSesInfo->server = srvTcp;
2409 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
2410 sprintf(pSesInfo->serverName, "%pI6",
2411 &srvTcp->addr.sockAddr6.sin6_addr);
2412 else
2413 sprintf(pSesInfo->serverName, "%pI4",
2414 &srvTcp->addr.sockAddr.sin_addr.s_addr);
2415
2416 write_lock(&cifs_tcp_ses_lock);
2417 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2418 write_unlock(&cifs_tcp_ses_lock);
2419
2420 /* volume_info->password freed at unmount */
2421 if (volume_info->password) {
2422 pSesInfo->password = kstrdup(volume_info->password,
2423 GFP_KERNEL);
2424 if (!pSesInfo->password) {
2425 rc = -ENOMEM;
2426 goto mount_fail_check;
2427 }
2428 }
2429 if (volume_info->username)
2430 strncpy(pSesInfo->userName, volume_info->username,
2431 MAX_USERNAME_SIZE);
2432 if (volume_info->domainname) {
2433 int len = strlen(volume_info->domainname);
2434 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2435 if (pSesInfo->domainName)
2436 strcpy(pSesInfo->domainName,
2437 volume_info->domainname);
2438 }
2439 pSesInfo->linux_uid = volume_info->linux_uid;
2440 pSesInfo->overrideSecFlg = volume_info->secFlg;
2441 mutex_lock(&pSesInfo->session_mutex);
2442
2443 /* BB FIXME need to pass vol->secFlgs BB */
2444 rc = cifs_setup_session(xid, pSesInfo,
2445 cifs_sb->local_nls);
2446 mutex_unlock(&pSesInfo->session_mutex);
2447 } 2638 }
2448 2639
2449 /* search for existing tcon to this server share */ 2640 setup_cifs_sb(volume_info, cifs_sb);
2450 if (!rc) { 2641 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2451 setup_cifs_sb(volume_info, cifs_sb); 2642 sb->s_maxbytes = MAX_LFS_FILESIZE;
2452 2643 else
2453 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC); 2644 sb->s_maxbytes = MAX_NON_LFS;
2454 if (tcon) {
2455 cFYI(1, ("Found match on UNC path"));
2456 /* existing tcon already has a reference */
2457 cifs_put_smb_ses(pSesInfo);
2458 if (tcon->seal != volume_info->seal)
2459 cERROR(1, ("transport encryption setting "
2460 "conflicts with existing tid"));
2461 } else {
2462 tcon = tconInfoAlloc();
2463 if (tcon == NULL) {
2464 rc = -ENOMEM;
2465 goto mount_fail_check;
2466 }
2467
2468 tcon->ses = pSesInfo;
2469 if (volume_info->password) {
2470 tcon->password = kstrdup(volume_info->password,
2471 GFP_KERNEL);
2472 if (!tcon->password) {
2473 rc = -ENOMEM;
2474 goto mount_fail_check;
2475 }
2476 }
2477
2478 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2479 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
2480 cERROR(1, ("Missing share name"));
2481 rc = -ENODEV;
2482 goto mount_fail_check;
2483 } else {
2484 /* BB Do we need to wrap sesSem around
2485 * this TCon call and Unix SetFS as
2486 * we do on SessSetup and reconnect? */
2487 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
2488 tcon, cifs_sb->local_nls);
2489 cFYI(1, ("CIFS Tcon rc = %d", rc));
2490 if (volume_info->nodfs) {
2491 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2492 cFYI(1, ("DFS disabled (%d)",
2493 tcon->Flags));
2494 }
2495 }
2496 if (rc)
2497 goto remote_path_check;
2498 tcon->seal = volume_info->seal;
2499 write_lock(&cifs_tcp_ses_lock);
2500 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2501 write_unlock(&cifs_tcp_ses_lock);
2502 }
2503
2504 /* we can have only one retry value for a connection
2505 to a share so for resources mounted more than once
2506 to the same server share the last value passed in
2507 for the retry flag is used */
2508 tcon->retry = volume_info->retry;
2509 tcon->nocase = volume_info->nocase;
2510 tcon->local_lease = volume_info->local_lease;
2511 }
2512 if (pSesInfo) {
2513 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2514 sb->s_maxbytes = MAX_LFS_FILESIZE;
2515 else
2516 sb->s_maxbytes = MAX_NON_LFS;
2517 }
2518 2645
2519 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 2646 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2520 sb->s_time_gran = 100; 2647 sb->s_time_gran = 100;
2521 2648
2522 if (rc) 2649 /* search for existing tcon to this server share */
2650 tcon = cifs_get_tcon(pSesInfo, volume_info);
2651 if (IS_ERR(tcon)) {
2652 rc = PTR_ERR(tcon);
2653 tcon = NULL;
2523 goto remote_path_check; 2654 goto remote_path_check;
2655 }
2524 2656
2525 cifs_sb->tcon = tcon; 2657 cifs_sb->tcon = tcon;
2526 2658
@@ -2544,7 +2676,7 @@ try_mount_again:
2544 2676
2545 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { 2677 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2546 cifs_sb->rsize = 1024 * 127; 2678 cifs_sb->rsize = 1024 * 127;
2547 cFYI(DBG2, ("no very large read support, rsize now 127K")); 2679 cFYI(DBG2, "no very large read support, rsize now 127K");
2548 } 2680 }
2549 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) 2681 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2550 cifs_sb->wsize = min(cifs_sb->wsize, 2682 cifs_sb->wsize = min(cifs_sb->wsize,
@@ -2593,7 +2725,7 @@ remote_path_check:
2593 goto mount_fail_check; 2725 goto mount_fail_check;
2594 } 2726 }
2595 2727
2596 cFYI(1, ("Getting referral for: %s", full_path)); 2728 cFYI(1, "Getting referral for: %s", full_path);
2597 rc = get_dfs_path(xid, pSesInfo , full_path + 1, 2729 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2598 cifs_sb->local_nls, &num_referrals, &referrals, 2730 cifs_sb->local_nls, &num_referrals, &referrals,
2599 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 2731 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -2707,7 +2839,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2707 by Samba (not sure whether other servers allow 2839 by Samba (not sure whether other servers allow
2708 NTLMv2 password here) */ 2840 NTLMv2 password here) */
2709#ifdef CONFIG_CIFS_WEAK_PW_HASH 2841#ifdef CONFIG_CIFS_WEAK_PW_HASH
2710 if ((extended_security & CIFSSEC_MAY_LANMAN) && 2842 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2711 (ses->server->secType == LANMAN)) 2843 (ses->server->secType == LANMAN))
2712 calc_lanman_hash(tcon->password, ses->server->cryptKey, 2844 calc_lanman_hash(tcon->password, ses->server->cryptKey,
2713 ses->server->secMode & 2845 ses->server->secMode &
@@ -2778,13 +2910,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2778 if (length == 3) { 2910 if (length == 3) {
2779 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && 2911 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
2780 (bcc_ptr[2] == 'C')) { 2912 (bcc_ptr[2] == 'C')) {
2781 cFYI(1, ("IPC connection")); 2913 cFYI(1, "IPC connection");
2782 tcon->ipc = 1; 2914 tcon->ipc = 1;
2783 } 2915 }
2784 } else if (length == 2) { 2916 } else if (length == 2) {
2785 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { 2917 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
2786 /* the most common case */ 2918 /* the most common case */
2787 cFYI(1, ("disk share connection")); 2919 cFYI(1, "disk share connection");
2788 } 2920 }
2789 } 2921 }
2790 bcc_ptr += length + 1; 2922 bcc_ptr += length + 1;
@@ -2797,7 +2929,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2797 bytes_left, is_unicode, 2929 bytes_left, is_unicode,
2798 nls_codepage); 2930 nls_codepage);
2799 2931
2800 cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem)); 2932 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
2801 2933
2802 if ((smb_buffer_response->WordCount == 3) || 2934 if ((smb_buffer_response->WordCount == 3) ||
2803 (smb_buffer_response->WordCount == 7)) 2935 (smb_buffer_response->WordCount == 7))
@@ -2805,7 +2937,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2805 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 2937 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
2806 else 2938 else
2807 tcon->Flags = 0; 2939 tcon->Flags = 0;
2808 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); 2940 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
2809 } else if ((rc == 0) && tcon == NULL) { 2941 } else if ((rc == 0) && tcon == NULL) {
2810 /* all we need to save for IPC$ connection */ 2942 /* all we need to save for IPC$ connection */
2811 ses->ipc_tid = smb_buffer_response->Tid; 2943 ses->ipc_tid = smb_buffer_response->Tid;
@@ -2833,57 +2965,61 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2833 return rc; 2965 return rc;
2834} 2966}
2835 2967
2836int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 2968int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
2837 struct nls_table *nls_info)
2838{ 2969{
2839 int rc = 0; 2970 int rc = 0;
2840 int first_time = 0; 2971 struct TCP_Server_Info *server = ses->server;
2841 struct TCP_Server_Info *server = pSesInfo->server; 2972
2842 2973 /* only send once per connect */
2843 /* what if server changes its buffer size after dropping the session? */ 2974 if (server->maxBuf != 0)
2844 if (server->maxBuf == 0) /* no need to send on reconnect */ { 2975 return 0;
2845 rc = CIFSSMBNegotiate(xid, pSesInfo); 2976
2846 if (rc == -EAGAIN) { 2977 rc = CIFSSMBNegotiate(xid, ses);
2847 /* retry only once on 1st time connection */ 2978 if (rc == -EAGAIN) {
2848 rc = CIFSSMBNegotiate(xid, pSesInfo); 2979 /* retry only once on 1st time connection */
2849 if (rc == -EAGAIN) 2980 rc = CIFSSMBNegotiate(xid, ses);
2850 rc = -EHOSTDOWN; 2981 if (rc == -EAGAIN)
2851 } 2982 rc = -EHOSTDOWN;
2852 if (rc == 0) { 2983 }
2853 spin_lock(&GlobalMid_Lock); 2984 if (rc == 0) {
2854 if (server->tcpStatus != CifsExiting) 2985 spin_lock(&GlobalMid_Lock);
2855 server->tcpStatus = CifsGood; 2986 if (server->tcpStatus != CifsExiting)
2856 else 2987 server->tcpStatus = CifsGood;
2857 rc = -EHOSTDOWN; 2988 else
2858 spin_unlock(&GlobalMid_Lock); 2989 rc = -EHOSTDOWN;
2990 spin_unlock(&GlobalMid_Lock);
2859 2991
2860 }
2861 first_time = 1;
2862 } 2992 }
2863 2993
2864 if (rc) 2994 return rc;
2865 goto ss_err_exit; 2995}
2996
2997
2998int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
2999 struct nls_table *nls_info)
3000{
3001 int rc = 0;
3002 struct TCP_Server_Info *server = ses->server;
2866 3003
2867 pSesInfo->flags = 0; 3004 ses->flags = 0;
2868 pSesInfo->capabilities = server->capabilities; 3005 ses->capabilities = server->capabilities;
2869 if (linuxExtEnabled == 0) 3006 if (linuxExtEnabled == 0)
2870 pSesInfo->capabilities &= (~CAP_UNIX); 3007 ses->capabilities &= (~CAP_UNIX);
2871 3008
2872 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3009 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
2873 server->secMode, server->capabilities, server->timeAdj)); 3010 server->secMode, server->capabilities, server->timeAdj);
2874 3011
2875 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info); 3012 rc = CIFS_SessSetup(xid, ses, nls_info);
2876 if (rc) { 3013 if (rc) {
2877 cERROR(1, ("Send error in SessSetup = %d", rc)); 3014 cERROR(1, "Send error in SessSetup = %d", rc);
2878 } else { 3015 } else {
2879 cFYI(1, ("CIFS Session Established successfully")); 3016 cFYI(1, "CIFS Session Established successfully");
2880 spin_lock(&GlobalMid_Lock); 3017 spin_lock(&GlobalMid_Lock);
2881 pSesInfo->status = CifsGood; 3018 ses->status = CifsGood;
2882 pSesInfo->need_reconnect = false; 3019 ses->need_reconnect = false;
2883 spin_unlock(&GlobalMid_Lock); 3020 spin_unlock(&GlobalMid_Lock);
2884 } 3021 }
2885 3022
2886ss_err_exit:
2887 return rc; 3023 return rc;
2888} 3024}
2889 3025