cifs: add routines to build sessions and tcons on the fly
[linux-2.6/cjktty.git] / fs / cifs / connect.c
blob3156a9de947da36f2a5a417123880d5b02dce043
1 /*
2 * fs/cifs/connect.c
4 * Copyright (C) International Business Machines Corp., 2002,2009
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/fs.h>
22 #include <linux/net.h>
23 #include <linux/string.h>
24 #include <linux/list.h>
25 #include <linux/wait.h>
26 #include <linux/slab.h>
27 #include <linux/pagemap.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/mempool.h>
31 #include <linux/delay.h>
32 #include <linux/completion.h>
33 #include <linux/kthread.h>
34 #include <linux/pagevec.h>
35 #include <linux/freezer.h>
36 #include <linux/namei.h>
37 #include <asm/uaccess.h>
38 #include <asm/processor.h>
39 #include <linux/inet.h>
40 #include <net/ipv6.h>
41 #include "cifspdu.h"
42 #include "cifsglob.h"
43 #include "cifsproto.h"
44 #include "cifs_unicode.h"
45 #include "cifs_debug.h"
46 #include "cifs_fs_sb.h"
47 #include "ntlmssp.h"
48 #include "nterr.h"
49 #include "rfc1002pdu.h"
50 #include "fscache.h"
52 #define CIFS_PORT 445
53 #define RFC1001_PORT 139
55 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
56 unsigned char *p24);
58 extern mempool_t *cifs_req_poolp;
60 struct smb_vol {
61 char *username;
62 char *password;
63 char *domainname;
64 char *UNC;
65 char *UNCip;
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
69 uid_t cred_uid;
70 uid_t linux_uid;
71 gid_t linux_gid;
72 mode_t file_mode;
73 mode_t dir_mode;
74 unsigned secFlg;
75 bool retry:1;
76 bool intr:1;
77 bool setuids:1;
78 bool override_uid:1;
79 bool override_gid:1;
80 bool dynperm:1;
81 bool noperm:1;
82 bool no_psx_acl:1; /* set if posix acl support should be disabled */
83 bool cifs_acl:1;
84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
86 bool direct_io:1;
87 bool remap:1; /* set to remap seven reserved chars in filenames */
88 bool posix_paths:1; /* unset to not ask for posix pathnames. */
89 bool no_linux_ext:1;
90 bool sfu_emul:1;
91 bool nullauth:1; /* attempt to authenticate with null user */
92 bool nocase:1; /* request case insensitive filenames */
93 bool nobrl:1; /* disable sending byte range locks to srv */
94 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
95 bool seal:1; /* request transport encryption on share */
96 bool nodfs:1; /* Do not request DFS, even if available */
97 bool local_lease:1; /* check leases only on local system, not remote */
98 bool noblocksnd:1;
99 bool noautotune:1;
100 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
101 bool fsc:1; /* enable fscache */
102 bool mfsymlinks:1; /* use Minshall+French Symlinks */
103 unsigned int rsize;
104 unsigned int wsize;
105 bool sockopt_tcp_nodelay:1;
106 unsigned short int port;
107 char *prepath;
108 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
109 struct nls_table *local_nls;
112 #define TLINK_ERROR_EXPIRE (1 * HZ)
115 static int ipv4_connect(struct TCP_Server_Info *server);
116 static int ipv6_connect(struct TCP_Server_Info *server);
119 * cifs tcp session reconnection
121 * mark tcp session as reconnecting so temporarily locked
122 * mark all smb sessions as reconnecting for tcp session
123 * reconnect tcp session
124 * wake up waiters on reconnection? - (not needed currently)
126 static int
127 cifs_reconnect(struct TCP_Server_Info *server)
129 int rc = 0;
130 struct list_head *tmp, *tmp2;
131 struct cifsSesInfo *ses;
132 struct cifsTconInfo *tcon;
133 struct mid_q_entry *mid_entry;
135 spin_lock(&GlobalMid_Lock);
136 if (server->tcpStatus == CifsExiting) {
137 /* the demux thread will exit normally
138 next time through the loop */
139 spin_unlock(&GlobalMid_Lock);
140 return rc;
141 } else
142 server->tcpStatus = CifsNeedReconnect;
143 spin_unlock(&GlobalMid_Lock);
144 server->maxBuf = 0;
146 cFYI(1, "Reconnecting tcp session");
148 /* before reconnecting the tcp session, mark the smb session (uid)
149 and the tid bad so they are not used until reconnected */
150 read_lock(&cifs_tcp_ses_lock);
151 list_for_each(tmp, &server->smb_ses_list) {
152 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
153 ses->need_reconnect = true;
154 ses->ipc_tid = 0;
155 list_for_each(tmp2, &ses->tcon_list) {
156 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
157 tcon->need_reconnect = true;
160 read_unlock(&cifs_tcp_ses_lock);
161 /* do not want to be sending data on a socket we are freeing */
162 mutex_lock(&server->srv_mutex);
163 if (server->ssocket) {
164 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
165 server->ssocket->flags);
166 kernel_sock_shutdown(server->ssocket, SHUT_WR);
167 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
168 server->ssocket->state,
169 server->ssocket->flags);
170 sock_release(server->ssocket);
171 server->ssocket = NULL;
174 spin_lock(&GlobalMid_Lock);
175 list_for_each(tmp, &server->pending_mid_q) {
176 mid_entry = list_entry(tmp, struct
177 mid_q_entry,
178 qhead);
179 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
180 /* Mark other intransit requests as needing
181 retry so we do not immediately mark the
182 session bad again (ie after we reconnect
183 below) as they timeout too */
184 mid_entry->midState = MID_RETRY_NEEDED;
187 spin_unlock(&GlobalMid_Lock);
188 mutex_unlock(&server->srv_mutex);
190 while ((server->tcpStatus != CifsExiting) &&
191 (server->tcpStatus != CifsGood)) {
192 try_to_freeze();
193 if (server->addr.sockAddr6.sin6_family == AF_INET6)
194 rc = ipv6_connect(server);
195 else
196 rc = ipv4_connect(server);
197 if (rc) {
198 cFYI(1, "reconnect error %d", rc);
199 msleep(3000);
200 } else {
201 atomic_inc(&tcpSesReconnectCount);
202 spin_lock(&GlobalMid_Lock);
203 if (server->tcpStatus != CifsExiting)
204 server->tcpStatus = CifsGood;
205 server->sequence_number = 0;
206 spin_unlock(&GlobalMid_Lock);
207 /* atomic_set(&server->inFlight,0);*/
208 wake_up(&server->response_q);
211 return rc;
215 return codes:
216 0 not a transact2, or all data present
217 >0 transact2 with that much data missing
218 -EINVAL = invalid transact2
221 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
223 struct smb_t2_rsp *pSMBt;
224 int total_data_size;
225 int data_in_this_rsp;
226 int remaining;
228 if (pSMB->Command != SMB_COM_TRANSACTION2)
229 return 0;
231 /* check for plausible wct, bcc and t2 data and parm sizes */
232 /* check for parm and data offset going beyond end of smb */
233 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
234 cFYI(1, "invalid transact2 word count");
235 return -EINVAL;
238 pSMBt = (struct smb_t2_rsp *)pSMB;
240 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
241 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
243 remaining = total_data_size - data_in_this_rsp;
245 if (remaining == 0)
246 return 0;
247 else if (remaining < 0) {
248 cFYI(1, "total data %d smaller than data in frame %d",
249 total_data_size, data_in_this_rsp);
250 return -EINVAL;
251 } else {
252 cFYI(1, "missing %d bytes from transact2, check next response",
253 remaining);
254 if (total_data_size > maxBufSize) {
255 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
256 total_data_size, maxBufSize);
257 return -EINVAL;
259 return remaining;
263 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
265 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
266 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
267 int total_data_size;
268 int total_in_buf;
269 int remaining;
270 int total_in_buf2;
271 char *data_area_of_target;
272 char *data_area_of_buf2;
273 __u16 byte_count;
275 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
277 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
278 cFYI(1, "total data size of primary and secondary t2 differ");
281 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
283 remaining = total_data_size - total_in_buf;
285 if (remaining < 0)
286 return -EINVAL;
288 if (remaining == 0) /* nothing to do, ignore */
289 return 0;
291 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
292 if (remaining < total_in_buf2) {
293 cFYI(1, "transact2 2nd response contains too much data");
296 /* find end of first SMB data area */
297 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
298 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
299 /* validate target area */
301 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
302 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
304 data_area_of_target += total_in_buf;
306 /* copy second buffer into end of first buffer */
307 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
308 total_in_buf += total_in_buf2;
309 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
310 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
311 byte_count += total_in_buf2;
312 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
314 byte_count = pTargetSMB->smb_buf_length;
315 byte_count += total_in_buf2;
317 /* BB also add check that we are not beyond maximum buffer size */
319 pTargetSMB->smb_buf_length = byte_count;
321 if (remaining == total_in_buf2) {
322 cFYI(1, "found the last secondary response");
323 return 0; /* we are done */
324 } else /* more responses to go */
325 return 1;
329 static int
330 cifs_demultiplex_thread(struct TCP_Server_Info *server)
332 int length;
333 unsigned int pdu_length, total_read;
334 struct smb_hdr *smb_buffer = NULL;
335 struct smb_hdr *bigbuf = NULL;
336 struct smb_hdr *smallbuf = NULL;
337 struct msghdr smb_msg;
338 struct kvec iov;
339 struct socket *csocket = server->ssocket;
340 struct list_head *tmp;
341 struct cifsSesInfo *ses;
342 struct task_struct *task_to_wake = NULL;
343 struct mid_q_entry *mid_entry;
344 char temp;
345 bool isLargeBuf = false;
346 bool isMultiRsp;
347 int reconnect;
349 current->flags |= PF_MEMALLOC;
350 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
352 length = atomic_inc_return(&tcpSesAllocCount);
353 if (length > 1)
354 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
355 GFP_KERNEL);
357 set_freezable();
358 while (server->tcpStatus != CifsExiting) {
359 if (try_to_freeze())
360 continue;
361 if (bigbuf == NULL) {
362 bigbuf = cifs_buf_get();
363 if (!bigbuf) {
364 cERROR(1, "No memory for large SMB response");
365 msleep(3000);
366 /* retry will check if exiting */
367 continue;
369 } else if (isLargeBuf) {
370 /* we are reusing a dirty large buf, clear its start */
371 memset(bigbuf, 0, sizeof(struct smb_hdr));
374 if (smallbuf == NULL) {
375 smallbuf = cifs_small_buf_get();
376 if (!smallbuf) {
377 cERROR(1, "No memory for SMB response");
378 msleep(1000);
379 /* retry will check if exiting */
380 continue;
382 /* beginning of smb buffer is cleared in our buf_get */
383 } else /* if existing small buf clear beginning */
384 memset(smallbuf, 0, sizeof(struct smb_hdr));
386 isLargeBuf = false;
387 isMultiRsp = false;
388 smb_buffer = smallbuf;
389 iov.iov_base = smb_buffer;
390 iov.iov_len = 4;
391 smb_msg.msg_control = NULL;
392 smb_msg.msg_controllen = 0;
393 pdu_length = 4; /* enough to get RFC1001 header */
394 incomplete_rcv:
395 length =
396 kernel_recvmsg(csocket, &smb_msg,
397 &iov, 1, pdu_length, 0 /* BB other flags? */);
399 if (server->tcpStatus == CifsExiting) {
400 break;
401 } else if (server->tcpStatus == CifsNeedReconnect) {
402 cFYI(1, "Reconnect after server stopped responding");
403 cifs_reconnect(server);
404 cFYI(1, "call to reconnect done");
405 csocket = server->ssocket;
406 continue;
407 } else if (length == -ERESTARTSYS ||
408 length == -EAGAIN ||
409 length == -EINTR) {
410 msleep(1); /* minimum sleep to prevent looping
411 allowing socket to clear and app threads to set
412 tcpStatus CifsNeedReconnect if server hung */
413 if (pdu_length < 4) {
414 iov.iov_base = (4 - pdu_length) +
415 (char *)smb_buffer;
416 iov.iov_len = pdu_length;
417 smb_msg.msg_control = NULL;
418 smb_msg.msg_controllen = 0;
419 goto incomplete_rcv;
420 } else
421 continue;
422 } else if (length <= 0) {
423 cFYI(1, "Reconnect after unexpected peek error %d",
424 length);
425 cifs_reconnect(server);
426 csocket = server->ssocket;
427 wake_up(&server->response_q);
428 continue;
429 } else if (length < pdu_length) {
430 cFYI(1, "requested %d bytes but only got %d bytes",
431 pdu_length, length);
432 pdu_length -= length;
433 msleep(1);
434 goto incomplete_rcv;
437 /* The right amount was read from socket - 4 bytes */
438 /* so we can now interpret the length field */
440 /* the first byte big endian of the length field,
441 is actually not part of the length but the type
442 with the most common, zero, as regular data */
443 temp = *((char *) smb_buffer);
445 /* Note that FC 1001 length is big endian on the wire,
446 but we convert it here so it is always manipulated
447 as host byte order */
448 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
449 smb_buffer->smb_buf_length = pdu_length;
451 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
453 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
454 continue;
455 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
456 cFYI(1, "Good RFC 1002 session rsp");
457 continue;
458 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
459 /* we get this from Windows 98 instead of
460 an error on SMB negprot response */
461 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
462 pdu_length);
463 /* give server a second to clean up */
464 msleep(1000);
465 /* always try 445 first on reconnect since we get NACK
466 * on some if we ever connected to port 139 (the NACK
467 * is since we do not begin with RFC1001 session
468 * initialize frame)
470 cifs_set_port((struct sockaddr *)
471 &server->addr.sockAddr, CIFS_PORT);
472 cifs_reconnect(server);
473 csocket = server->ssocket;
474 wake_up(&server->response_q);
475 continue;
476 } else if (temp != (char) 0) {
477 cERROR(1, "Unknown RFC 1002 frame");
478 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
479 length);
480 cifs_reconnect(server);
481 csocket = server->ssocket;
482 continue;
485 /* else we have an SMB response */
486 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
487 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
488 cERROR(1, "Invalid size SMB length %d pdu_length %d",
489 length, pdu_length+4);
490 cifs_reconnect(server);
491 csocket = server->ssocket;
492 wake_up(&server->response_q);
493 continue;
496 /* else length ok */
497 reconnect = 0;
499 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
500 isLargeBuf = true;
501 memcpy(bigbuf, smallbuf, 4);
502 smb_buffer = bigbuf;
504 length = 0;
505 iov.iov_base = 4 + (char *)smb_buffer;
506 iov.iov_len = pdu_length;
507 for (total_read = 0; total_read < pdu_length;
508 total_read += length) {
509 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
510 pdu_length - total_read, 0);
511 if (server->tcpStatus == CifsExiting) {
512 /* then will exit */
513 reconnect = 2;
514 break;
515 } else if (server->tcpStatus == CifsNeedReconnect) {
516 cifs_reconnect(server);
517 csocket = server->ssocket;
518 /* Reconnect wakes up rspns q */
519 /* Now we will reread sock */
520 reconnect = 1;
521 break;
522 } else if (length == -ERESTARTSYS ||
523 length == -EAGAIN ||
524 length == -EINTR) {
525 msleep(1); /* minimum sleep to prevent looping,
526 allowing socket to clear and app
527 threads to set tcpStatus
528 CifsNeedReconnect if server hung*/
529 length = 0;
530 continue;
531 } else if (length <= 0) {
532 cERROR(1, "Received no data, expecting %d",
533 pdu_length - total_read);
534 cifs_reconnect(server);
535 csocket = server->ssocket;
536 reconnect = 1;
537 break;
540 if (reconnect == 2)
541 break;
542 else if (reconnect == 1)
543 continue;
545 length += 4; /* account for rfc1002 hdr */
548 dump_smb(smb_buffer, length);
549 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
550 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
551 continue;
555 task_to_wake = NULL;
556 spin_lock(&GlobalMid_Lock);
557 list_for_each(tmp, &server->pending_mid_q) {
558 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
560 if ((mid_entry->mid == smb_buffer->Mid) &&
561 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
562 (mid_entry->command == smb_buffer->Command)) {
563 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
564 /* We have a multipart transact2 resp */
565 isMultiRsp = true;
566 if (mid_entry->resp_buf) {
567 /* merge response - fix up 1st*/
568 if (coalesce_t2(smb_buffer,
569 mid_entry->resp_buf)) {
570 mid_entry->multiRsp =
571 true;
572 break;
573 } else {
574 /* all parts received */
575 mid_entry->multiEnd =
576 true;
577 goto multi_t2_fnd;
579 } else {
580 if (!isLargeBuf) {
581 cERROR(1, "1st trans2 resp needs bigbuf");
582 /* BB maybe we can fix this up, switch
583 to already allocated large buffer? */
584 } else {
585 /* Have first buffer */
586 mid_entry->resp_buf =
587 smb_buffer;
588 mid_entry->largeBuf =
589 true;
590 bigbuf = NULL;
593 break;
595 mid_entry->resp_buf = smb_buffer;
596 mid_entry->largeBuf = isLargeBuf;
597 multi_t2_fnd:
598 task_to_wake = mid_entry->tsk;
599 mid_entry->midState = MID_RESPONSE_RECEIVED;
600 #ifdef CONFIG_CIFS_STATS2
601 mid_entry->when_received = jiffies;
602 #endif
603 /* so we do not time out requests to server
604 which is still responding (since server could
605 be busy but not dead) */
606 server->lstrp = jiffies;
607 break;
610 spin_unlock(&GlobalMid_Lock);
611 if (task_to_wake) {
612 /* Was previous buf put in mpx struct for multi-rsp? */
613 if (!isMultiRsp) {
614 /* smb buffer will be freed by user thread */
615 if (isLargeBuf)
616 bigbuf = NULL;
617 else
618 smallbuf = NULL;
620 wake_up_process(task_to_wake);
621 } else if (!is_valid_oplock_break(smb_buffer, server) &&
622 !isMultiRsp) {
623 cERROR(1, "No task to wake, unknown frame received! "
624 "NumMids %d", midCount.counter);
625 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
626 sizeof(struct smb_hdr));
627 #ifdef CONFIG_CIFS_DEBUG2
628 cifs_dump_detail(smb_buffer);
629 cifs_dump_mids(server);
630 #endif /* CIFS_DEBUG2 */
633 } /* end while !EXITING */
635 /* take it off the list, if it's not already */
636 write_lock(&cifs_tcp_ses_lock);
637 list_del_init(&server->tcp_ses_list);
638 write_unlock(&cifs_tcp_ses_lock);
640 spin_lock(&GlobalMid_Lock);
641 server->tcpStatus = CifsExiting;
642 spin_unlock(&GlobalMid_Lock);
643 wake_up_all(&server->response_q);
645 /* check if we have blocked requests that need to free */
646 /* Note that cifs_max_pending is normally 50, but
647 can be set at module install time to as little as two */
648 spin_lock(&GlobalMid_Lock);
649 if (atomic_read(&server->inFlight) >= cifs_max_pending)
650 atomic_set(&server->inFlight, cifs_max_pending - 1);
651 /* We do not want to set the max_pending too low or we
652 could end up with the counter going negative */
653 spin_unlock(&GlobalMid_Lock);
654 /* Although there should not be any requests blocked on
655 this queue it can not hurt to be paranoid and try to wake up requests
656 that may haven been blocked when more than 50 at time were on the wire
657 to the same server - they now will see the session is in exit state
658 and get out of SendReceive. */
659 wake_up_all(&server->request_q);
660 /* give those requests time to exit */
661 msleep(125);
663 if (server->ssocket) {
664 sock_release(csocket);
665 server->ssocket = NULL;
667 /* buffer usuallly freed in free_mid - need to free it here on exit */
668 cifs_buf_release(bigbuf);
669 if (smallbuf) /* no sense logging a debug message if NULL */
670 cifs_small_buf_release(smallbuf);
673 * BB: we shouldn't have to do any of this. It shouldn't be
674 * possible to exit from the thread with active SMB sessions
676 read_lock(&cifs_tcp_ses_lock);
677 if (list_empty(&server->pending_mid_q)) {
678 /* loop through server session structures attached to this and
679 mark them dead */
680 list_for_each(tmp, &server->smb_ses_list) {
681 ses = list_entry(tmp, struct cifsSesInfo,
682 smb_ses_list);
683 ses->status = CifsExiting;
684 ses->server = NULL;
686 read_unlock(&cifs_tcp_ses_lock);
687 } else {
688 /* although we can not zero the server struct pointer yet,
689 since there are active requests which may depnd on them,
690 mark the corresponding SMB sessions as exiting too */
691 list_for_each(tmp, &server->smb_ses_list) {
692 ses = list_entry(tmp, struct cifsSesInfo,
693 smb_ses_list);
694 ses->status = CifsExiting;
697 spin_lock(&GlobalMid_Lock);
698 list_for_each(tmp, &server->pending_mid_q) {
699 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
700 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
701 cFYI(1, "Clearing Mid 0x%x - waking up ",
702 mid_entry->mid);
703 task_to_wake = mid_entry->tsk;
704 if (task_to_wake)
705 wake_up_process(task_to_wake);
708 spin_unlock(&GlobalMid_Lock);
709 read_unlock(&cifs_tcp_ses_lock);
710 /* 1/8th of sec is more than enough time for them to exit */
711 msleep(125);
714 if (!list_empty(&server->pending_mid_q)) {
715 /* mpx threads have not exited yet give them
716 at least the smb send timeout time for long ops */
717 /* due to delays on oplock break requests, we need
718 to wait at least 45 seconds before giving up
719 on a request getting a response and going ahead
720 and killing cifsd */
721 cFYI(1, "Wait for exit from demultiplex thread");
722 msleep(46000);
723 /* if threads still have not exited they are probably never
724 coming home not much else we can do but free the memory */
727 /* last chance to mark ses pointers invalid
728 if there are any pointing to this (e.g
729 if a crazy root user tried to kill cifsd
730 kernel thread explicitly this might happen) */
731 /* BB: This shouldn't be necessary, see above */
732 read_lock(&cifs_tcp_ses_lock);
733 list_for_each(tmp, &server->smb_ses_list) {
734 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
735 ses->server = NULL;
737 read_unlock(&cifs_tcp_ses_lock);
739 kfree(server->hostname);
740 task_to_wake = xchg(&server->tsk, NULL);
741 kfree(server);
743 length = atomic_dec_return(&tcpSesAllocCount);
744 if (length > 0)
745 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
746 GFP_KERNEL);
748 /* if server->tsk was NULL then wait for a signal before exiting */
749 if (!task_to_wake) {
750 set_current_state(TASK_INTERRUPTIBLE);
751 while (!signal_pending(current)) {
752 schedule();
753 set_current_state(TASK_INTERRUPTIBLE);
755 set_current_state(TASK_RUNNING);
758 module_put_and_exit(0);
761 /* extract the host portion of the UNC string */
762 static char *
763 extract_hostname(const char *unc)
765 const char *src;
766 char *dst, *delim;
767 unsigned int len;
769 /* skip double chars at beginning of string */
770 /* BB: check validity of these bytes? */
771 src = unc + 2;
773 /* delimiter between hostname and sharename is always '\\' now */
774 delim = strchr(src, '\\');
775 if (!delim)
776 return ERR_PTR(-EINVAL);
778 len = delim - src;
779 dst = kmalloc((len + 1), GFP_KERNEL);
780 if (dst == NULL)
781 return ERR_PTR(-ENOMEM);
783 memcpy(dst, src, len);
784 dst[len] = '\0';
786 return dst;
789 static int
790 cifs_parse_mount_options(char *options, const char *devname,
791 struct smb_vol *vol)
793 char *value;
794 char *data;
795 unsigned int temp_len, i, j;
796 char separator[2];
797 short int override_uid = -1;
798 short int override_gid = -1;
799 bool uid_specified = false;
800 bool gid_specified = false;
802 separator[0] = ',';
803 separator[1] = 0;
805 if (Local_System_Name[0] != 0)
806 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
807 else {
808 char *nodename = utsname()->nodename;
809 int n = strnlen(nodename, 15);
810 memset(vol->source_rfc1001_name, 0x20, 15);
811 for (i = 0; i < n; i++) {
812 /* does not have to be perfect mapping since field is
813 informational, only used for servers that do not support
814 port 445 and it can be overridden at mount time */
815 vol->source_rfc1001_name[i] = toupper(nodename[i]);
818 vol->source_rfc1001_name[15] = 0;
819 /* null target name indicates to use *SMBSERVR default called name
820 if we end up sending RFC1001 session initialize */
821 vol->target_rfc1001_name[0] = 0;
822 vol->cred_uid = current_uid();
823 vol->linux_uid = current_uid();
824 vol->linux_gid = current_gid();
826 /* default to only allowing write access to owner of the mount */
827 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
829 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
830 /* default is always to request posix paths. */
831 vol->posix_paths = 1;
832 /* default to using server inode numbers where available */
833 vol->server_ino = 1;
835 if (!options)
836 return 1;
838 if (strncmp(options, "sep=", 4) == 0) {
839 if (options[4] != 0) {
840 separator[0] = options[4];
841 options += 5;
842 } else {
843 cFYI(1, "Null separator not allowed");
847 while ((data = strsep(&options, separator)) != NULL) {
848 if (!*data)
849 continue;
850 if ((value = strchr(data, '=')) != NULL)
851 *value++ = '\0';
853 /* Have to parse this before we parse for "user" */
854 if (strnicmp(data, "user_xattr", 10) == 0) {
855 vol->no_xattr = 0;
856 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
857 vol->no_xattr = 1;
858 } else if (strnicmp(data, "user", 4) == 0) {
859 if (!value) {
860 printk(KERN_WARNING
861 "CIFS: invalid or missing username\n");
862 return 1; /* needs_arg; */
863 } else if (!*value) {
864 /* null user, ie anonymous, authentication */
865 vol->nullauth = 1;
867 if (strnlen(value, 200) < 200) {
868 vol->username = value;
869 } else {
870 printk(KERN_WARNING "CIFS: username too long\n");
871 return 1;
873 } else if (strnicmp(data, "pass", 4) == 0) {
874 if (!value) {
875 vol->password = NULL;
876 continue;
877 } else if (value[0] == 0) {
878 /* check if string begins with double comma
879 since that would mean the password really
880 does start with a comma, and would not
881 indicate an empty string */
882 if (value[1] != separator[0]) {
883 vol->password = NULL;
884 continue;
887 temp_len = strlen(value);
888 /* removed password length check, NTLM passwords
889 can be arbitrarily long */
891 /* if comma in password, the string will be
892 prematurely null terminated. Commas in password are
893 specified across the cifs mount interface by a double
894 comma ie ,, and a comma used as in other cases ie ','
895 as a parameter delimiter/separator is single and due
896 to the strsep above is temporarily zeroed. */
898 /* NB: password legally can have multiple commas and
899 the only illegal character in a password is null */
901 if ((value[temp_len] == 0) &&
902 (value[temp_len+1] == separator[0])) {
903 /* reinsert comma */
904 value[temp_len] = separator[0];
905 temp_len += 2; /* move after second comma */
906 while (value[temp_len] != 0) {
907 if (value[temp_len] == separator[0]) {
908 if (value[temp_len+1] ==
909 separator[0]) {
910 /* skip second comma */
911 temp_len++;
912 } else {
913 /* single comma indicating start
914 of next parm */
915 break;
918 temp_len++;
920 if (value[temp_len] == 0) {
921 options = NULL;
922 } else {
923 value[temp_len] = 0;
924 /* point option to start of next parm */
925 options = value + temp_len + 1;
927 /* go from value to value + temp_len condensing
928 double commas to singles. Note that this ends up
929 allocating a few bytes too many, which is ok */
930 vol->password = kzalloc(temp_len, GFP_KERNEL);
931 if (vol->password == NULL) {
932 printk(KERN_WARNING "CIFS: no memory "
933 "for password\n");
934 return 1;
936 for (i = 0, j = 0; i < temp_len; i++, j++) {
937 vol->password[j] = value[i];
938 if (value[i] == separator[0]
939 && value[i+1] == separator[0]) {
940 /* skip second comma */
941 i++;
944 vol->password[j] = 0;
945 } else {
946 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
947 if (vol->password == NULL) {
948 printk(KERN_WARNING "CIFS: no memory "
949 "for password\n");
950 return 1;
952 strcpy(vol->password, value);
954 } else if (!strnicmp(data, "ip", 2) ||
955 !strnicmp(data, "addr", 4)) {
956 if (!value || !*value) {
957 vol->UNCip = NULL;
958 } else if (strnlen(value, INET6_ADDRSTRLEN) <
959 INET6_ADDRSTRLEN) {
960 vol->UNCip = value;
961 } else {
962 printk(KERN_WARNING "CIFS: ip address "
963 "too long\n");
964 return 1;
966 } else if (strnicmp(data, "sec", 3) == 0) {
967 if (!value || !*value) {
968 cERROR(1, "no security value specified");
969 continue;
970 } else if (strnicmp(value, "krb5i", 5) == 0) {
971 vol->secFlg |= CIFSSEC_MAY_KRB5 |
972 CIFSSEC_MUST_SIGN;
973 } else if (strnicmp(value, "krb5p", 5) == 0) {
974 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
975 CIFSSEC_MAY_KRB5; */
976 cERROR(1, "Krb5 cifs privacy not supported");
977 return 1;
978 } else if (strnicmp(value, "krb5", 4) == 0) {
979 vol->secFlg |= CIFSSEC_MAY_KRB5;
980 #ifdef CONFIG_CIFS_EXPERIMENTAL
981 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
982 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
983 CIFSSEC_MUST_SIGN;
984 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
985 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
986 #endif
987 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
988 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
989 CIFSSEC_MUST_SIGN;
990 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
991 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
992 } else if (strnicmp(value, "ntlmi", 5) == 0) {
993 vol->secFlg |= CIFSSEC_MAY_NTLM |
994 CIFSSEC_MUST_SIGN;
995 } else if (strnicmp(value, "ntlm", 4) == 0) {
996 /* ntlm is default so can be turned off too */
997 vol->secFlg |= CIFSSEC_MAY_NTLM;
998 } else if (strnicmp(value, "nontlm", 6) == 0) {
999 /* BB is there a better way to do this? */
1000 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1001 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1002 } else if (strnicmp(value, "lanman", 6) == 0) {
1003 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1004 #endif
1005 } else if (strnicmp(value, "none", 4) == 0) {
1006 vol->nullauth = 1;
1007 } else {
1008 cERROR(1, "bad security option: %s", value);
1009 return 1;
1011 } else if ((strnicmp(data, "unc", 3) == 0)
1012 || (strnicmp(data, "target", 6) == 0)
1013 || (strnicmp(data, "path", 4) == 0)) {
1014 if (!value || !*value) {
1015 printk(KERN_WARNING "CIFS: invalid path to "
1016 "network resource\n");
1017 return 1; /* needs_arg; */
1019 if ((temp_len = strnlen(value, 300)) < 300) {
1020 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1021 if (vol->UNC == NULL)
1022 return 1;
1023 strcpy(vol->UNC, value);
1024 if (strncmp(vol->UNC, "//", 2) == 0) {
1025 vol->UNC[0] = '\\';
1026 vol->UNC[1] = '\\';
1027 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1028 printk(KERN_WARNING
1029 "CIFS: UNC Path does not begin "
1030 "with // or \\\\ \n");
1031 return 1;
1033 } else {
1034 printk(KERN_WARNING "CIFS: UNC name too long\n");
1035 return 1;
1037 } else if ((strnicmp(data, "domain", 3) == 0)
1038 || (strnicmp(data, "workgroup", 5) == 0)) {
1039 if (!value || !*value) {
1040 printk(KERN_WARNING "CIFS: invalid domain name\n");
1041 return 1; /* needs_arg; */
1043 /* BB are there cases in which a comma can be valid in
1044 a domain name and need special handling? */
1045 if (strnlen(value, 256) < 256) {
1046 vol->domainname = value;
1047 cFYI(1, "Domain name set");
1048 } else {
1049 printk(KERN_WARNING "CIFS: domain name too "
1050 "long\n");
1051 return 1;
1053 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1054 vol->srcaddr.ss_family = AF_UNSPEC;
1056 if (!value || !*value) {
1057 printk(KERN_WARNING "CIFS: srcaddr value"
1058 " not specified.\n");
1059 return 1; /* needs_arg; */
1061 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1062 value, strlen(value));
1063 if (i < 0) {
1064 printk(KERN_WARNING "CIFS: Could not parse"
1065 " srcaddr: %s\n",
1066 value);
1067 return 1;
1069 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1070 if (!value || !*value) {
1071 printk(KERN_WARNING
1072 "CIFS: invalid path prefix\n");
1073 return 1; /* needs_argument */
1075 if ((temp_len = strnlen(value, 1024)) < 1024) {
1076 if (value[0] != '/')
1077 temp_len++; /* missing leading slash */
1078 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1079 if (vol->prepath == NULL)
1080 return 1;
1081 if (value[0] != '/') {
1082 vol->prepath[0] = '/';
1083 strcpy(vol->prepath+1, value);
1084 } else
1085 strcpy(vol->prepath, value);
1086 cFYI(1, "prefix path %s", vol->prepath);
1087 } else {
1088 printk(KERN_WARNING "CIFS: prefix too long\n");
1089 return 1;
1091 } else if (strnicmp(data, "iocharset", 9) == 0) {
1092 if (!value || !*value) {
1093 printk(KERN_WARNING "CIFS: invalid iocharset "
1094 "specified\n");
1095 return 1; /* needs_arg; */
1097 if (strnlen(value, 65) < 65) {
1098 if (strnicmp(value, "default", 7))
1099 vol->iocharset = value;
1100 /* if iocharset not set then load_nls_default
1101 is used by caller */
1102 cFYI(1, "iocharset set to %s", value);
1103 } else {
1104 printk(KERN_WARNING "CIFS: iocharset name "
1105 "too long.\n");
1106 return 1;
1108 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1109 vol->linux_uid = simple_strtoul(value, &value, 0);
1110 uid_specified = true;
1111 } else if (!strnicmp(data, "forceuid", 8)) {
1112 override_uid = 1;
1113 } else if (!strnicmp(data, "noforceuid", 10)) {
1114 override_uid = 0;
1115 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1116 vol->linux_gid = simple_strtoul(value, &value, 0);
1117 gid_specified = true;
1118 } else if (!strnicmp(data, "forcegid", 8)) {
1119 override_gid = 1;
1120 } else if (!strnicmp(data, "noforcegid", 10)) {
1121 override_gid = 0;
1122 } else if (strnicmp(data, "file_mode", 4) == 0) {
1123 if (value && *value) {
1124 vol->file_mode =
1125 simple_strtoul(value, &value, 0);
1127 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1128 if (value && *value) {
1129 vol->dir_mode =
1130 simple_strtoul(value, &value, 0);
1132 } else if (strnicmp(data, "dirmode", 4) == 0) {
1133 if (value && *value) {
1134 vol->dir_mode =
1135 simple_strtoul(value, &value, 0);
1137 } else if (strnicmp(data, "port", 4) == 0) {
1138 if (value && *value) {
1139 vol->port =
1140 simple_strtoul(value, &value, 0);
1142 } else if (strnicmp(data, "rsize", 5) == 0) {
1143 if (value && *value) {
1144 vol->rsize =
1145 simple_strtoul(value, &value, 0);
1147 } else if (strnicmp(data, "wsize", 5) == 0) {
1148 if (value && *value) {
1149 vol->wsize =
1150 simple_strtoul(value, &value, 0);
1152 } else if (strnicmp(data, "sockopt", 5) == 0) {
1153 if (!value || !*value) {
1154 cERROR(1, "no socket option specified");
1155 continue;
1156 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1157 vol->sockopt_tcp_nodelay = 1;
1159 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1160 if (!value || !*value || (*value == ' ')) {
1161 cFYI(1, "invalid (empty) netbiosname");
1162 } else {
1163 memset(vol->source_rfc1001_name, 0x20, 15);
1164 for (i = 0; i < 15; i++) {
1165 /* BB are there cases in which a comma can be
1166 valid in this workstation netbios name (and need
1167 special handling)? */
1169 /* We do not uppercase netbiosname for user */
1170 if (value[i] == 0)
1171 break;
1172 else
1173 vol->source_rfc1001_name[i] =
1174 value[i];
1176 /* The string has 16th byte zero still from
1177 set at top of the function */
1178 if ((i == 15) && (value[i] != 0))
1179 printk(KERN_WARNING "CIFS: netbiosname"
1180 " longer than 15 truncated.\n");
1182 } else if (strnicmp(data, "servern", 7) == 0) {
1183 /* servernetbiosname specified override *SMBSERVER */
1184 if (!value || !*value || (*value == ' ')) {
1185 cFYI(1, "empty server netbiosname specified");
1186 } else {
1187 /* last byte, type, is 0x20 for servr type */
1188 memset(vol->target_rfc1001_name, 0x20, 16);
1190 for (i = 0; i < 15; i++) {
1191 /* BB are there cases in which a comma can be
1192 valid in this workstation netbios name
1193 (and need special handling)? */
1195 /* user or mount helper must uppercase
1196 the netbiosname */
1197 if (value[i] == 0)
1198 break;
1199 else
1200 vol->target_rfc1001_name[i] =
1201 value[i];
1203 /* The string has 16th byte zero still from
1204 set at top of the function */
1205 if ((i == 15) && (value[i] != 0))
1206 printk(KERN_WARNING "CIFS: server net"
1207 "biosname longer than 15 truncated.\n");
1209 } else if (strnicmp(data, "credentials", 4) == 0) {
1210 /* ignore */
1211 } else if (strnicmp(data, "version", 3) == 0) {
1212 /* ignore */
1213 } else if (strnicmp(data, "guest", 5) == 0) {
1214 /* ignore */
1215 } else if (strnicmp(data, "rw", 2) == 0) {
1216 /* ignore */
1217 } else if (strnicmp(data, "ro", 2) == 0) {
1218 /* ignore */
1219 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1220 vol->noblocksnd = 1;
1221 } else if (strnicmp(data, "noautotune", 10) == 0) {
1222 vol->noautotune = 1;
1223 } else if ((strnicmp(data, "suid", 4) == 0) ||
1224 (strnicmp(data, "nosuid", 6) == 0) ||
1225 (strnicmp(data, "exec", 4) == 0) ||
1226 (strnicmp(data, "noexec", 6) == 0) ||
1227 (strnicmp(data, "nodev", 5) == 0) ||
1228 (strnicmp(data, "noauto", 6) == 0) ||
1229 (strnicmp(data, "dev", 3) == 0)) {
1230 /* The mount tool or mount.cifs helper (if present)
1231 uses these opts to set flags, and the flags are read
1232 by the kernel vfs layer before we get here (ie
1233 before read super) so there is no point trying to
1234 parse these options again and set anything and it
1235 is ok to just ignore them */
1236 continue;
1237 } else if (strnicmp(data, "hard", 4) == 0) {
1238 vol->retry = 1;
1239 } else if (strnicmp(data, "soft", 4) == 0) {
1240 vol->retry = 0;
1241 } else if (strnicmp(data, "perm", 4) == 0) {
1242 vol->noperm = 0;
1243 } else if (strnicmp(data, "noperm", 6) == 0) {
1244 vol->noperm = 1;
1245 } else if (strnicmp(data, "mapchars", 8) == 0) {
1246 vol->remap = 1;
1247 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1248 vol->remap = 0;
1249 } else if (strnicmp(data, "sfu", 3) == 0) {
1250 vol->sfu_emul = 1;
1251 } else if (strnicmp(data, "nosfu", 5) == 0) {
1252 vol->sfu_emul = 0;
1253 } else if (strnicmp(data, "nodfs", 5) == 0) {
1254 vol->nodfs = 1;
1255 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1256 vol->posix_paths = 1;
1257 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1258 vol->posix_paths = 0;
1259 } else if (strnicmp(data, "nounix", 6) == 0) {
1260 vol->no_linux_ext = 1;
1261 } else if (strnicmp(data, "nolinux", 7) == 0) {
1262 vol->no_linux_ext = 1;
1263 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1264 (strnicmp(data, "ignorecase", 10) == 0)) {
1265 vol->nocase = 1;
1266 } else if (strnicmp(data, "mand", 4) == 0) {
1267 /* ignore */
1268 } else if (strnicmp(data, "nomand", 6) == 0) {
1269 /* ignore */
1270 } else if (strnicmp(data, "_netdev", 7) == 0) {
1271 /* ignore */
1272 } else if (strnicmp(data, "brl", 3) == 0) {
1273 vol->nobrl = 0;
1274 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1275 (strnicmp(data, "nolock", 6) == 0)) {
1276 vol->nobrl = 1;
1277 /* turn off mandatory locking in mode
1278 if remote locking is turned off since the
1279 local vfs will do advisory */
1280 if (vol->file_mode ==
1281 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1282 vol->file_mode = S_IALLUGO;
1283 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1284 /* will take the shorter form "forcemand" as well */
1285 /* This mount option will force use of mandatory
1286 (DOS/Windows style) byte range locks, instead of
1287 using posix advisory byte range locks, even if the
1288 Unix extensions are available and posix locks would
1289 be supported otherwise. If Unix extensions are not
1290 negotiated this has no effect since mandatory locks
1291 would be used (mandatory locks is all that those
1292 those servers support) */
1293 vol->mand_lock = 1;
1294 } else if (strnicmp(data, "setuids", 7) == 0) {
1295 vol->setuids = 1;
1296 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1297 vol->setuids = 0;
1298 } else if (strnicmp(data, "dynperm", 7) == 0) {
1299 vol->dynperm = true;
1300 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1301 vol->dynperm = false;
1302 } else if (strnicmp(data, "nohard", 6) == 0) {
1303 vol->retry = 0;
1304 } else if (strnicmp(data, "nosoft", 6) == 0) {
1305 vol->retry = 1;
1306 } else if (strnicmp(data, "nointr", 6) == 0) {
1307 vol->intr = 0;
1308 } else if (strnicmp(data, "intr", 4) == 0) {
1309 vol->intr = 1;
1310 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1311 vol->nostrictsync = 1;
1312 } else if (strnicmp(data, "strictsync", 10) == 0) {
1313 vol->nostrictsync = 0;
1314 } else if (strnicmp(data, "serverino", 7) == 0) {
1315 vol->server_ino = 1;
1316 } else if (strnicmp(data, "noserverino", 9) == 0) {
1317 vol->server_ino = 0;
1318 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1319 vol->cifs_acl = 1;
1320 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1321 vol->cifs_acl = 0;
1322 } else if (strnicmp(data, "acl", 3) == 0) {
1323 vol->no_psx_acl = 0;
1324 } else if (strnicmp(data, "noacl", 5) == 0) {
1325 vol->no_psx_acl = 1;
1326 #ifdef CONFIG_CIFS_EXPERIMENTAL
1327 } else if (strnicmp(data, "locallease", 6) == 0) {
1328 vol->local_lease = 1;
1329 #endif
1330 } else if (strnicmp(data, "sign", 4) == 0) {
1331 vol->secFlg |= CIFSSEC_MUST_SIGN;
1332 } else if (strnicmp(data, "seal", 4) == 0) {
1333 /* we do not do the following in secFlags because seal
1334 is a per tree connection (mount) not a per socket
1335 or per-smb connection option in the protocol */
1336 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1337 vol->seal = 1;
1338 } else if (strnicmp(data, "direct", 6) == 0) {
1339 vol->direct_io = 1;
1340 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1341 vol->direct_io = 1;
1342 } else if (strnicmp(data, "noac", 4) == 0) {
1343 printk(KERN_WARNING "CIFS: Mount option noac not "
1344 "supported. Instead set "
1345 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1346 } else if (strnicmp(data, "fsc", 3) == 0) {
1347 vol->fsc = true;
1348 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1349 vol->mfsymlinks = true;
1350 } else
1351 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1352 data);
1354 if (vol->UNC == NULL) {
1355 if (devname == NULL) {
1356 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1357 "target\n");
1358 return 1;
1360 if ((temp_len = strnlen(devname, 300)) < 300) {
1361 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1362 if (vol->UNC == NULL)
1363 return 1;
1364 strcpy(vol->UNC, devname);
1365 if (strncmp(vol->UNC, "//", 2) == 0) {
1366 vol->UNC[0] = '\\';
1367 vol->UNC[1] = '\\';
1368 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1369 printk(KERN_WARNING "CIFS: UNC Path does not "
1370 "begin with // or \\\\ \n");
1371 return 1;
1373 value = strpbrk(vol->UNC+2, "/\\");
1374 if (value)
1375 *value = '\\';
1376 } else {
1377 printk(KERN_WARNING "CIFS: UNC name too long\n");
1378 return 1;
1381 if (vol->UNCip == NULL)
1382 vol->UNCip = &vol->UNC[2];
1384 if (uid_specified)
1385 vol->override_uid = override_uid;
1386 else if (override_uid == 1)
1387 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1388 "specified with no uid= option.\n");
1390 if (gid_specified)
1391 vol->override_gid = override_gid;
1392 else if (override_gid == 1)
1393 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1394 "specified with no gid= option.\n");
1396 return 0;
1399 /** Returns true if srcaddr isn't specified and rhs isn't
1400 * specified, or if srcaddr is specified and
1401 * matches the IP address of the rhs argument.
1403 static bool
1404 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1406 switch (srcaddr->sa_family) {
1407 case AF_UNSPEC:
1408 return (rhs->sa_family == AF_UNSPEC);
1409 case AF_INET: {
1410 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1411 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1412 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1414 case AF_INET6: {
1415 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1416 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1417 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1419 default:
1420 WARN_ON(1);
1421 return false; /* don't expect to be here */
1426 static bool
1427 match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1428 struct sockaddr *srcaddr)
1430 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1431 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1433 switch (addr->sa_family) {
1434 case AF_INET:
1435 if (addr4->sin_addr.s_addr !=
1436 server->addr.sockAddr.sin_addr.s_addr)
1437 return false;
1438 if (addr4->sin_port &&
1439 addr4->sin_port != server->addr.sockAddr.sin_port)
1440 return false;
1441 break;
1442 case AF_INET6:
1443 if (!ipv6_addr_equal(&addr6->sin6_addr,
1444 &server->addr.sockAddr6.sin6_addr))
1445 return false;
1446 if (addr6->sin6_scope_id !=
1447 server->addr.sockAddr6.sin6_scope_id)
1448 return false;
1449 if (addr6->sin6_port &&
1450 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1451 return false;
1452 break;
1455 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1456 return false;
1458 return true;
1461 static bool
1462 match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1464 unsigned int secFlags;
1466 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1467 secFlags = vol->secFlg;
1468 else
1469 secFlags = global_secflags | vol->secFlg;
1471 switch (server->secType) {
1472 case LANMAN:
1473 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1474 return false;
1475 break;
1476 case NTLMv2:
1477 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1478 return false;
1479 break;
1480 case NTLM:
1481 if (!(secFlags & CIFSSEC_MAY_NTLM))
1482 return false;
1483 break;
1484 case Kerberos:
1485 if (!(secFlags & CIFSSEC_MAY_KRB5))
1486 return false;
1487 break;
1488 case RawNTLMSSP:
1489 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1490 return false;
1491 break;
1492 default:
1493 /* shouldn't happen */
1494 return false;
1497 /* now check if signing mode is acceptible */
1498 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1499 (server->secMode & SECMODE_SIGN_REQUIRED))
1500 return false;
1501 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1502 (server->secMode &
1503 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1504 return false;
1506 return true;
1509 static struct TCP_Server_Info *
1510 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1512 struct TCP_Server_Info *server;
1514 write_lock(&cifs_tcp_ses_lock);
1515 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1516 if (!match_address(server, addr,
1517 (struct sockaddr *)&vol->srcaddr))
1518 continue;
1520 if (!match_security(server, vol))
1521 continue;
1523 ++server->srv_count;
1524 write_unlock(&cifs_tcp_ses_lock);
1525 cFYI(1, "Existing tcp session with server found");
1526 return server;
1528 write_unlock(&cifs_tcp_ses_lock);
1529 return NULL;
1532 static void
1533 cifs_put_tcp_session(struct TCP_Server_Info *server)
1535 struct task_struct *task;
1537 write_lock(&cifs_tcp_ses_lock);
1538 if (--server->srv_count > 0) {
1539 write_unlock(&cifs_tcp_ses_lock);
1540 return;
1543 list_del_init(&server->tcp_ses_list);
1544 write_unlock(&cifs_tcp_ses_lock);
1546 spin_lock(&GlobalMid_Lock);
1547 server->tcpStatus = CifsExiting;
1548 spin_unlock(&GlobalMid_Lock);
1550 cifs_fscache_release_client_cookie(server);
1552 task = xchg(&server->tsk, NULL);
1553 if (task)
1554 force_sig(SIGKILL, task);
1557 static struct TCP_Server_Info *
1558 cifs_get_tcp_session(struct smb_vol *volume_info)
1560 struct TCP_Server_Info *tcp_ses = NULL;
1561 struct sockaddr_storage addr;
1562 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1563 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1564 int rc;
1566 memset(&addr, 0, sizeof(struct sockaddr_storage));
1568 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1570 if (volume_info->UNCip && volume_info->UNC) {
1571 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1572 volume_info->UNCip,
1573 strlen(volume_info->UNCip),
1574 volume_info->port);
1575 if (!rc) {
1576 /* we failed translating address */
1577 rc = -EINVAL;
1578 goto out_err;
1580 } else if (volume_info->UNCip) {
1581 /* BB using ip addr as tcp_ses name to connect to the
1582 DFS root below */
1583 cERROR(1, "Connecting to DFS root not implemented yet");
1584 rc = -EINVAL;
1585 goto out_err;
1586 } else /* which tcp_sess DFS root would we conect to */ {
1587 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1588 "unc=//192.168.1.100/public) specified");
1589 rc = -EINVAL;
1590 goto out_err;
1593 /* see if we already have a matching tcp_ses */
1594 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1595 if (tcp_ses)
1596 return tcp_ses;
1598 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1599 if (!tcp_ses) {
1600 rc = -ENOMEM;
1601 goto out_err;
1604 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1605 if (IS_ERR(tcp_ses->hostname)) {
1606 rc = PTR_ERR(tcp_ses->hostname);
1607 goto out_err;
1610 tcp_ses->noblocksnd = volume_info->noblocksnd;
1611 tcp_ses->noautotune = volume_info->noautotune;
1612 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1613 atomic_set(&tcp_ses->inFlight, 0);
1614 init_waitqueue_head(&tcp_ses->response_q);
1615 init_waitqueue_head(&tcp_ses->request_q);
1616 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1617 mutex_init(&tcp_ses->srv_mutex);
1618 memcpy(tcp_ses->workstation_RFC1001_name,
1619 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1620 memcpy(tcp_ses->server_RFC1001_name,
1621 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1622 tcp_ses->sequence_number = 0;
1623 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1624 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1627 * at this point we are the only ones with the pointer
1628 * to the struct since the kernel thread not created yet
1629 * no need to spinlock this init of tcpStatus or srv_count
1631 tcp_ses->tcpStatus = CifsNew;
1632 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1633 sizeof(tcp_ses->srcaddr));
1634 ++tcp_ses->srv_count;
1636 if (addr.ss_family == AF_INET6) {
1637 cFYI(1, "attempting ipv6 connect");
1638 /* BB should we allow ipv6 on port 139? */
1639 /* other OS never observed in Wild doing 139 with v6 */
1640 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1641 sizeof(struct sockaddr_in6));
1642 rc = ipv6_connect(tcp_ses);
1643 } else {
1644 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1645 sizeof(struct sockaddr_in));
1646 rc = ipv4_connect(tcp_ses);
1648 if (rc < 0) {
1649 cERROR(1, "Error connecting to socket. Aborting operation");
1650 goto out_err;
1654 * since we're in a cifs function already, we know that
1655 * this will succeed. No need for try_module_get().
1657 __module_get(THIS_MODULE);
1658 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1659 tcp_ses, "cifsd");
1660 if (IS_ERR(tcp_ses->tsk)) {
1661 rc = PTR_ERR(tcp_ses->tsk);
1662 cERROR(1, "error %d create cifsd thread", rc);
1663 module_put(THIS_MODULE);
1664 goto out_err;
1667 /* thread spawned, put it on the list */
1668 write_lock(&cifs_tcp_ses_lock);
1669 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1670 write_unlock(&cifs_tcp_ses_lock);
1672 cifs_fscache_get_client_cookie(tcp_ses);
1674 return tcp_ses;
1676 out_err:
1677 if (tcp_ses) {
1678 if (!IS_ERR(tcp_ses->hostname))
1679 kfree(tcp_ses->hostname);
1680 if (tcp_ses->ssocket)
1681 sock_release(tcp_ses->ssocket);
1682 kfree(tcp_ses);
1684 return ERR_PTR(rc);
1687 static struct cifsSesInfo *
1688 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1690 struct cifsSesInfo *ses;
1692 write_lock(&cifs_tcp_ses_lock);
1693 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1694 switch (server->secType) {
1695 case Kerberos:
1696 if (vol->cred_uid != ses->cred_uid)
1697 continue;
1698 break;
1699 default:
1700 /* anything else takes username/password */
1701 if (strncmp(ses->userName, vol->username,
1702 MAX_USERNAME_SIZE))
1703 continue;
1704 if (strlen(vol->username) != 0 &&
1705 ses->password != NULL &&
1706 strncmp(ses->password,
1707 vol->password ? vol->password : "",
1708 MAX_PASSWORD_SIZE))
1709 continue;
1711 ++ses->ses_count;
1712 write_unlock(&cifs_tcp_ses_lock);
1713 return ses;
1715 write_unlock(&cifs_tcp_ses_lock);
1716 return NULL;
1719 static void
1720 cifs_put_smb_ses(struct cifsSesInfo *ses)
1722 int xid;
1723 struct TCP_Server_Info *server = ses->server;
1725 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1726 write_lock(&cifs_tcp_ses_lock);
1727 if (--ses->ses_count > 0) {
1728 write_unlock(&cifs_tcp_ses_lock);
1729 return;
1732 list_del_init(&ses->smb_ses_list);
1733 write_unlock(&cifs_tcp_ses_lock);
1735 if (ses->status == CifsGood) {
1736 xid = GetXid();
1737 CIFSSMBLogoff(xid, ses);
1738 _FreeXid(xid);
1740 sesInfoFree(ses);
1741 cifs_put_tcp_session(server);
1744 static struct cifsSesInfo *
1745 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1747 int rc = -ENOMEM, xid;
1748 struct cifsSesInfo *ses;
1750 xid = GetXid();
1752 ses = cifs_find_smb_ses(server, volume_info);
1753 if (ses) {
1754 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1756 mutex_lock(&ses->session_mutex);
1757 rc = cifs_negotiate_protocol(xid, ses);
1758 if (rc) {
1759 mutex_unlock(&ses->session_mutex);
1760 /* problem -- put our ses reference */
1761 cifs_put_smb_ses(ses);
1762 FreeXid(xid);
1763 return ERR_PTR(rc);
1765 if (ses->need_reconnect) {
1766 cFYI(1, "Session needs reconnect");
1767 rc = cifs_setup_session(xid, ses,
1768 volume_info->local_nls);
1769 if (rc) {
1770 mutex_unlock(&ses->session_mutex);
1771 /* problem -- put our reference */
1772 cifs_put_smb_ses(ses);
1773 FreeXid(xid);
1774 return ERR_PTR(rc);
1777 mutex_unlock(&ses->session_mutex);
1779 /* existing SMB ses has a server reference already */
1780 cifs_put_tcp_session(server);
1781 FreeXid(xid);
1782 return ses;
1785 cFYI(1, "Existing smb sess not found");
1786 ses = sesInfoAlloc();
1787 if (ses == NULL)
1788 goto get_ses_fail;
1790 ses->tilen = 0;
1791 ses->tiblob = NULL;
1792 /* new SMB session uses our server ref */
1793 ses->server = server;
1794 if (server->addr.sockAddr6.sin6_family == AF_INET6)
1795 sprintf(ses->serverName, "%pI6",
1796 &server->addr.sockAddr6.sin6_addr);
1797 else
1798 sprintf(ses->serverName, "%pI4",
1799 &server->addr.sockAddr.sin_addr.s_addr);
1801 if (volume_info->username)
1802 strncpy(ses->userName, volume_info->username,
1803 MAX_USERNAME_SIZE);
1805 /* volume_info->password freed at unmount */
1806 if (volume_info->password) {
1807 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1808 if (!ses->password)
1809 goto get_ses_fail;
1811 if (volume_info->domainname) {
1812 int len = strlen(volume_info->domainname);
1813 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1814 if (ses->domainName)
1815 strcpy(ses->domainName, volume_info->domainname);
1817 ses->cred_uid = volume_info->cred_uid;
1818 ses->linux_uid = volume_info->linux_uid;
1819 ses->overrideSecFlg = volume_info->secFlg;
1821 mutex_lock(&ses->session_mutex);
1822 rc = cifs_negotiate_protocol(xid, ses);
1823 if (!rc)
1824 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1825 mutex_unlock(&ses->session_mutex);
1826 if (rc)
1827 goto get_ses_fail;
1829 /* success, put it on the list */
1830 write_lock(&cifs_tcp_ses_lock);
1831 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1832 write_unlock(&cifs_tcp_ses_lock);
1834 FreeXid(xid);
1835 return ses;
1837 get_ses_fail:
1838 sesInfoFree(ses);
1839 FreeXid(xid);
1840 return ERR_PTR(rc);
1843 static struct cifsTconInfo *
1844 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1846 struct list_head *tmp;
1847 struct cifsTconInfo *tcon;
1849 write_lock(&cifs_tcp_ses_lock);
1850 list_for_each(tmp, &ses->tcon_list) {
1851 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1852 if (tcon->tidStatus == CifsExiting)
1853 continue;
1854 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1855 continue;
1857 ++tcon->tc_count;
1858 write_unlock(&cifs_tcp_ses_lock);
1859 return tcon;
1861 write_unlock(&cifs_tcp_ses_lock);
1862 return NULL;
1865 static void
1866 cifs_put_tcon(struct cifsTconInfo *tcon)
1868 int xid;
1869 struct cifsSesInfo *ses = tcon->ses;
1871 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1872 write_lock(&cifs_tcp_ses_lock);
1873 if (--tcon->tc_count > 0) {
1874 write_unlock(&cifs_tcp_ses_lock);
1875 return;
1878 list_del_init(&tcon->tcon_list);
1879 write_unlock(&cifs_tcp_ses_lock);
1881 xid = GetXid();
1882 CIFSSMBTDis(xid, tcon);
1883 _FreeXid(xid);
1885 cifs_fscache_release_super_cookie(tcon);
1886 tconInfoFree(tcon);
1887 cifs_put_smb_ses(ses);
1890 static struct cifsTconInfo *
1891 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1893 int rc, xid;
1894 struct cifsTconInfo *tcon;
1896 tcon = cifs_find_tcon(ses, volume_info->UNC);
1897 if (tcon) {
1898 cFYI(1, "Found match on UNC path");
1899 /* existing tcon already has a reference */
1900 cifs_put_smb_ses(ses);
1901 if (tcon->seal != volume_info->seal)
1902 cERROR(1, "transport encryption setting "
1903 "conflicts with existing tid");
1904 return tcon;
1907 tcon = tconInfoAlloc();
1908 if (tcon == NULL) {
1909 rc = -ENOMEM;
1910 goto out_fail;
1913 tcon->ses = ses;
1914 if (volume_info->password) {
1915 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1916 if (!tcon->password) {
1917 rc = -ENOMEM;
1918 goto out_fail;
1922 if (strchr(volume_info->UNC + 3, '\\') == NULL
1923 && strchr(volume_info->UNC + 3, '/') == NULL) {
1924 cERROR(1, "Missing share name");
1925 rc = -ENODEV;
1926 goto out_fail;
1929 /* BB Do we need to wrap session_mutex around
1930 * this TCon call and Unix SetFS as
1931 * we do on SessSetup and reconnect? */
1932 xid = GetXid();
1933 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
1934 FreeXid(xid);
1935 cFYI(1, "CIFS Tcon rc = %d", rc);
1936 if (rc)
1937 goto out_fail;
1939 if (volume_info->nodfs) {
1940 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
1941 cFYI(1, "DFS disabled (%d)", tcon->Flags);
1943 tcon->seal = volume_info->seal;
1944 /* we can have only one retry value for a connection
1945 to a share so for resources mounted more than once
1946 to the same server share the last value passed in
1947 for the retry flag is used */
1948 tcon->retry = volume_info->retry;
1949 tcon->nocase = volume_info->nocase;
1950 tcon->local_lease = volume_info->local_lease;
1952 write_lock(&cifs_tcp_ses_lock);
1953 list_add(&tcon->tcon_list, &ses->tcon_list);
1954 write_unlock(&cifs_tcp_ses_lock);
1956 cifs_fscache_get_super_cookie(tcon);
1958 return tcon;
1960 out_fail:
1961 tconInfoFree(tcon);
1962 return ERR_PTR(rc);
1965 void
1966 cifs_put_tlink(struct tcon_link *tlink)
1968 if (!tlink || IS_ERR(tlink))
1969 return;
1971 if (!atomic_dec_and_test(&tlink->tl_count) ||
1972 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
1973 tlink->tl_time = jiffies;
1974 return;
1977 if (!IS_ERR(tlink_tcon(tlink)))
1978 cifs_put_tcon(tlink_tcon(tlink));
1979 kfree(tlink);
1980 return;
1984 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1985 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1986 struct dfs_info3_param **preferrals, int remap)
1988 char *temp_unc;
1989 int rc = 0;
1991 *pnum_referrals = 0;
1992 *preferrals = NULL;
1994 if (pSesInfo->ipc_tid == 0) {
1995 temp_unc = kmalloc(2 /* for slashes */ +
1996 strnlen(pSesInfo->serverName,
1997 SERVER_NAME_LEN_WITH_NULL * 2)
1998 + 1 + 4 /* slash IPC$ */ + 2,
1999 GFP_KERNEL);
2000 if (temp_unc == NULL)
2001 return -ENOMEM;
2002 temp_unc[0] = '\\';
2003 temp_unc[1] = '\\';
2004 strcpy(temp_unc + 2, pSesInfo->serverName);
2005 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
2006 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
2007 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
2008 kfree(temp_unc);
2010 if (rc == 0)
2011 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
2012 pnum_referrals, nls_codepage, remap);
2013 /* BB map targetUNCs to dfs_info3 structures, here or
2014 in CIFSGetDFSRefer BB */
2016 return rc;
2019 #ifdef CONFIG_DEBUG_LOCK_ALLOC
2020 static struct lock_class_key cifs_key[2];
2021 static struct lock_class_key cifs_slock_key[2];
2023 static inline void
2024 cifs_reclassify_socket4(struct socket *sock)
2026 struct sock *sk = sock->sk;
2027 BUG_ON(sock_owned_by_user(sk));
2028 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2029 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2032 static inline void
2033 cifs_reclassify_socket6(struct socket *sock)
2035 struct sock *sk = sock->sk;
2036 BUG_ON(sock_owned_by_user(sk));
2037 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2038 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2040 #else
2041 static inline void
2042 cifs_reclassify_socket4(struct socket *sock)
2046 static inline void
2047 cifs_reclassify_socket6(struct socket *sock)
2050 #endif
2052 /* See RFC1001 section 14 on representation of Netbios names */
2053 static void rfc1002mangle(char *target, char *source, unsigned int length)
2055 unsigned int i, j;
2057 for (i = 0, j = 0; i < (length); i++) {
2058 /* mask a nibble at a time and encode */
2059 target[j] = 'A' + (0x0F & (source[i] >> 4));
2060 target[j+1] = 'A' + (0x0F & source[i]);
2061 j += 2;
2066 static int
2067 bind_socket(struct TCP_Server_Info *server)
2069 int rc = 0;
2070 if (server->srcaddr.ss_family != AF_UNSPEC) {
2071 /* Bind to the specified local IP address */
2072 struct socket *socket = server->ssocket;
2073 rc = socket->ops->bind(socket,
2074 (struct sockaddr *) &server->srcaddr,
2075 sizeof(server->srcaddr));
2076 if (rc < 0) {
2077 struct sockaddr_in *saddr4;
2078 struct sockaddr_in6 *saddr6;
2079 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2080 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2081 if (saddr6->sin6_family == AF_INET6)
2082 cERROR(1, "cifs: "
2083 "Failed to bind to: %pI6c, error: %d\n",
2084 &saddr6->sin6_addr, rc);
2085 else
2086 cERROR(1, "cifs: "
2087 "Failed to bind to: %pI4, error: %d\n",
2088 &saddr4->sin_addr.s_addr, rc);
2091 return rc;
2094 static int
2095 ipv4_connect(struct TCP_Server_Info *server)
2097 int rc = 0;
2098 int val;
2099 bool connected = false;
2100 __be16 orig_port = 0;
2101 struct socket *socket = server->ssocket;
2103 if (socket == NULL) {
2104 rc = sock_create_kern(PF_INET, SOCK_STREAM,
2105 IPPROTO_TCP, &socket);
2106 if (rc < 0) {
2107 cERROR(1, "Error %d creating socket", rc);
2108 return rc;
2111 /* BB other socket options to set KEEPALIVE, NODELAY? */
2112 cFYI(1, "Socket created");
2113 server->ssocket = socket;
2114 socket->sk->sk_allocation = GFP_NOFS;
2115 cifs_reclassify_socket4(socket);
2118 rc = bind_socket(server);
2119 if (rc < 0)
2120 return rc;
2122 /* user overrode default port */
2123 if (server->addr.sockAddr.sin_port) {
2124 rc = socket->ops->connect(socket, (struct sockaddr *)
2125 &server->addr.sockAddr,
2126 sizeof(struct sockaddr_in), 0);
2127 if (rc >= 0)
2128 connected = true;
2131 if (!connected) {
2132 /* save original port so we can retry user specified port
2133 later if fall back ports fail this time */
2134 orig_port = server->addr.sockAddr.sin_port;
2136 /* do not retry on the same port we just failed on */
2137 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2138 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2139 rc = socket->ops->connect(socket,
2140 (struct sockaddr *)
2141 &server->addr.sockAddr,
2142 sizeof(struct sockaddr_in), 0);
2143 if (rc >= 0)
2144 connected = true;
2147 if (!connected) {
2148 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2149 rc = socket->ops->connect(socket, (struct sockaddr *)
2150 &server->addr.sockAddr,
2151 sizeof(struct sockaddr_in), 0);
2152 if (rc >= 0)
2153 connected = true;
2156 /* give up here - unless we want to retry on different
2157 protocol families some day */
2158 if (!connected) {
2159 if (orig_port)
2160 server->addr.sockAddr.sin_port = orig_port;
2161 cFYI(1, "Error %d connecting to server via ipv4", rc);
2162 sock_release(socket);
2163 server->ssocket = NULL;
2164 return rc;
2169 * Eventually check for other socket options to change from
2170 * the default. sock_setsockopt not used because it expects
2171 * user space buffer
2173 socket->sk->sk_rcvtimeo = 7 * HZ;
2174 socket->sk->sk_sndtimeo = 5 * HZ;
2176 /* make the bufsizes depend on wsize/rsize and max requests */
2177 if (server->noautotune) {
2178 if (socket->sk->sk_sndbuf < (200 * 1024))
2179 socket->sk->sk_sndbuf = 200 * 1024;
2180 if (socket->sk->sk_rcvbuf < (140 * 1024))
2181 socket->sk->sk_rcvbuf = 140 * 1024;
2184 if (server->tcp_nodelay) {
2185 val = 1;
2186 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2187 (char *)&val, sizeof(val));
2188 if (rc)
2189 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2192 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
2193 socket->sk->sk_sndbuf,
2194 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2196 /* send RFC1001 sessinit */
2197 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
2198 /* some servers require RFC1001 sessinit before sending
2199 negprot - BB check reconnection in case where second
2200 sessinit is sent but no second negprot */
2201 struct rfc1002_session_packet *ses_init_buf;
2202 struct smb_hdr *smb_buf;
2203 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2204 GFP_KERNEL);
2205 if (ses_init_buf) {
2206 ses_init_buf->trailer.session_req.called_len = 32;
2207 if (server->server_RFC1001_name &&
2208 server->server_RFC1001_name[0] != 0)
2209 rfc1002mangle(ses_init_buf->trailer.
2210 session_req.called_name,
2211 server->server_RFC1001_name,
2212 RFC1001_NAME_LEN_WITH_NULL);
2213 else
2214 rfc1002mangle(ses_init_buf->trailer.
2215 session_req.called_name,
2216 DEFAULT_CIFS_CALLED_NAME,
2217 RFC1001_NAME_LEN_WITH_NULL);
2219 ses_init_buf->trailer.session_req.calling_len = 32;
2221 /* calling name ends in null (byte 16) from old smb
2222 convention. */
2223 if (server->workstation_RFC1001_name &&
2224 server->workstation_RFC1001_name[0] != 0)
2225 rfc1002mangle(ses_init_buf->trailer.
2226 session_req.calling_name,
2227 server->workstation_RFC1001_name,
2228 RFC1001_NAME_LEN_WITH_NULL);
2229 else
2230 rfc1002mangle(ses_init_buf->trailer.
2231 session_req.calling_name,
2232 "LINUX_CIFS_CLNT",
2233 RFC1001_NAME_LEN_WITH_NULL);
2235 ses_init_buf->trailer.session_req.scope1 = 0;
2236 ses_init_buf->trailer.session_req.scope2 = 0;
2237 smb_buf = (struct smb_hdr *)ses_init_buf;
2238 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2239 smb_buf->smb_buf_length = 0x81000044;
2240 rc = smb_send(server, smb_buf, 0x44);
2241 kfree(ses_init_buf);
2242 msleep(1); /* RFC1001 layer in at least one server
2243 requires very short break before negprot
2244 presumably because not expecting negprot
2245 to follow so fast. This is a simple
2246 solution that works without
2247 complicating the code and causes no
2248 significant slowing down on mount
2249 for everyone else */
2251 /* else the negprot may still work without this
2252 even though malloc failed */
2256 return rc;
2259 static int
2260 ipv6_connect(struct TCP_Server_Info *server)
2262 int rc = 0;
2263 int val;
2264 bool connected = false;
2265 __be16 orig_port = 0;
2266 struct socket *socket = server->ssocket;
2268 if (socket == NULL) {
2269 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
2270 IPPROTO_TCP, &socket);
2271 if (rc < 0) {
2272 cERROR(1, "Error %d creating ipv6 socket", rc);
2273 socket = NULL;
2274 return rc;
2277 /* BB other socket options to set KEEPALIVE, NODELAY? */
2278 cFYI(1, "ipv6 Socket created");
2279 server->ssocket = socket;
2280 socket->sk->sk_allocation = GFP_NOFS;
2281 cifs_reclassify_socket6(socket);
2284 rc = bind_socket(server);
2285 if (rc < 0)
2286 return rc;
2288 /* user overrode default port */
2289 if (server->addr.sockAddr6.sin6_port) {
2290 rc = socket->ops->connect(socket,
2291 (struct sockaddr *) &server->addr.sockAddr6,
2292 sizeof(struct sockaddr_in6), 0);
2293 if (rc >= 0)
2294 connected = true;
2297 if (!connected) {
2298 /* save original port so we can retry user specified port
2299 later if fall back ports fail this time */
2301 orig_port = server->addr.sockAddr6.sin6_port;
2302 /* do not retry on the same port we just failed on */
2303 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2304 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2305 rc = socket->ops->connect(socket, (struct sockaddr *)
2306 &server->addr.sockAddr6,
2307 sizeof(struct sockaddr_in6), 0);
2308 if (rc >= 0)
2309 connected = true;
2312 if (!connected) {
2313 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2314 rc = socket->ops->connect(socket, (struct sockaddr *)
2315 &server->addr.sockAddr6,
2316 sizeof(struct sockaddr_in6), 0);
2317 if (rc >= 0)
2318 connected = true;
2321 /* give up here - unless we want to retry on different
2322 protocol families some day */
2323 if (!connected) {
2324 if (orig_port)
2325 server->addr.sockAddr6.sin6_port = orig_port;
2326 cFYI(1, "Error %d connecting to server via ipv6", rc);
2327 sock_release(socket);
2328 server->ssocket = NULL;
2329 return rc;
2333 * Eventually check for other socket options to change from
2334 * the default. sock_setsockopt not used because it expects
2335 * user space buffer
2337 socket->sk->sk_rcvtimeo = 7 * HZ;
2338 socket->sk->sk_sndtimeo = 5 * HZ;
2340 if (server->tcp_nodelay) {
2341 val = 1;
2342 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2343 (char *)&val, sizeof(val));
2344 if (rc)
2345 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2348 server->ssocket = socket;
2350 return rc;
2353 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2354 struct super_block *sb, struct smb_vol *vol_info)
2356 /* if we are reconnecting then should we check to see if
2357 * any requested capabilities changed locally e.g. via
2358 * remount but we can not do much about it here
2359 * if they have (even if we could detect it by the following)
2360 * Perhaps we could add a backpointer to array of sb from tcon
2361 * or if we change to make all sb to same share the same
2362 * sb as NFS - then we only have one backpointer to sb.
2363 * What if we wanted to mount the server share twice once with
2364 * and once without posixacls or posix paths? */
2365 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2367 if (vol_info && vol_info->no_linux_ext) {
2368 tcon->fsUnixInfo.Capability = 0;
2369 tcon->unix_ext = 0; /* Unix Extensions disabled */
2370 cFYI(1, "Linux protocol extensions disabled");
2371 return;
2372 } else if (vol_info)
2373 tcon->unix_ext = 1; /* Unix Extensions supported */
2375 if (tcon->unix_ext == 0) {
2376 cFYI(1, "Unix extensions disabled so not set on reconnect");
2377 return;
2380 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2381 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2383 /* check for reconnect case in which we do not
2384 want to change the mount behavior if we can avoid it */
2385 if (vol_info == NULL) {
2386 /* turn off POSIX ACL and PATHNAMES if not set
2387 originally at mount time */
2388 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2389 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2390 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2391 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2392 cERROR(1, "POSIXPATH support change");
2393 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2394 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2395 cERROR(1, "possible reconnect error");
2396 cERROR(1, "server disabled POSIX path support");
2400 cap &= CIFS_UNIX_CAP_MASK;
2401 if (vol_info && vol_info->no_psx_acl)
2402 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2403 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2404 cFYI(1, "negotiated posix acl support");
2405 if (sb)
2406 sb->s_flags |= MS_POSIXACL;
2409 if (vol_info && vol_info->posix_paths == 0)
2410 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2411 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2412 cFYI(1, "negotiate posix pathnames");
2413 if (sb)
2414 CIFS_SB(sb)->mnt_cifs_flags |=
2415 CIFS_MOUNT_POSIX_PATHS;
2418 /* We might be setting the path sep back to a different
2419 form if we are reconnecting and the server switched its
2420 posix path capability for this share */
2421 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2422 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2424 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2425 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2426 CIFS_SB(sb)->rsize = 127 * 1024;
2427 cFYI(DBG2, "larger reads not supported by srv");
2432 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2433 #ifdef CONFIG_CIFS_DEBUG2
2434 if (cap & CIFS_UNIX_FCNTL_CAP)
2435 cFYI(1, "FCNTL cap");
2436 if (cap & CIFS_UNIX_EXTATTR_CAP)
2437 cFYI(1, "EXTATTR cap");
2438 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2439 cFYI(1, "POSIX path cap");
2440 if (cap & CIFS_UNIX_XATTR_CAP)
2441 cFYI(1, "XATTR cap");
2442 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2443 cFYI(1, "POSIX ACL cap");
2444 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2445 cFYI(1, "very large read cap");
2446 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2447 cFYI(1, "very large write cap");
2448 #endif /* CIFS_DEBUG2 */
2449 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2450 if (vol_info == NULL) {
2451 cFYI(1, "resetting capabilities failed");
2452 } else
2453 cERROR(1, "Negotiating Unix capabilities "
2454 "with the server failed. Consider "
2455 "mounting with the Unix Extensions\n"
2456 "disabled, if problems are found, "
2457 "by specifying the nounix mount "
2458 "option.");
2464 static void
2465 convert_delimiter(char *path, char delim)
2467 int i;
2468 char old_delim;
2470 if (path == NULL)
2471 return;
2473 if (delim == '/')
2474 old_delim = '\\';
2475 else
2476 old_delim = '/';
2478 for (i = 0; path[i] != '\0'; i++) {
2479 if (path[i] == old_delim)
2480 path[i] = delim;
2484 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2485 struct cifs_sb_info *cifs_sb)
2487 if (pvolume_info->rsize > CIFSMaxBufSize) {
2488 cERROR(1, "rsize %d too large, using MaxBufSize",
2489 pvolume_info->rsize);
2490 cifs_sb->rsize = CIFSMaxBufSize;
2491 } else if ((pvolume_info->rsize) &&
2492 (pvolume_info->rsize <= CIFSMaxBufSize))
2493 cifs_sb->rsize = pvolume_info->rsize;
2494 else /* default */
2495 cifs_sb->rsize = CIFSMaxBufSize;
2497 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2498 cERROR(1, "wsize %d too large, using 4096 instead",
2499 pvolume_info->wsize);
2500 cifs_sb->wsize = 4096;
2501 } else if (pvolume_info->wsize)
2502 cifs_sb->wsize = pvolume_info->wsize;
2503 else
2504 cifs_sb->wsize = min_t(const int,
2505 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2506 127*1024);
2507 /* old default of CIFSMaxBufSize was too small now
2508 that SMB Write2 can send multiple pages in kvec.
2509 RFC1001 does not describe what happens when frame
2510 bigger than 128K is sent so use that as max in
2511 conjunction with 52K kvec constraint on arch with 4K
2512 page size */
2514 if (cifs_sb->rsize < 2048) {
2515 cifs_sb->rsize = 2048;
2516 /* Windows ME may prefer this */
2517 cFYI(1, "readsize set to minimum: 2048");
2519 /* calculate prepath */
2520 cifs_sb->prepath = pvolume_info->prepath;
2521 if (cifs_sb->prepath) {
2522 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2523 /* we can not convert the / to \ in the path
2524 separators in the prefixpath yet because we do not
2525 know (until reset_cifs_unix_caps is called later)
2526 whether POSIX PATH CAP is available. We normalize
2527 the / to \ after reset_cifs_unix_caps is called */
2528 pvolume_info->prepath = NULL;
2529 } else
2530 cifs_sb->prepathlen = 0;
2531 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2532 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2533 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2534 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2535 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2536 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2538 if (pvolume_info->noperm)
2539 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2540 if (pvolume_info->setuids)
2541 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2542 if (pvolume_info->server_ino)
2543 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2544 if (pvolume_info->remap)
2545 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2546 if (pvolume_info->no_xattr)
2547 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2548 if (pvolume_info->sfu_emul)
2549 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2550 if (pvolume_info->nobrl)
2551 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2552 if (pvolume_info->nostrictsync)
2553 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2554 if (pvolume_info->mand_lock)
2555 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2556 if (pvolume_info->cifs_acl)
2557 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2558 if (pvolume_info->override_uid)
2559 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2560 if (pvolume_info->override_gid)
2561 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2562 if (pvolume_info->dynperm)
2563 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2564 if (pvolume_info->fsc)
2565 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2566 if (pvolume_info->direct_io) {
2567 cFYI(1, "mounting share using direct i/o");
2568 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2570 if (pvolume_info->mfsymlinks) {
2571 if (pvolume_info->sfu_emul) {
2572 cERROR(1, "mount option mfsymlinks ignored if sfu "
2573 "mount option is used");
2574 } else {
2575 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2579 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2580 cERROR(1, "mount option dynperm ignored if cifsacl "
2581 "mount option supported");
2584 static int
2585 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2586 struct cifs_sb_info *cifs_sb, const char *full_path)
2588 int rc;
2589 FILE_ALL_INFO *pfile_info;
2591 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2592 if (pfile_info == NULL)
2593 return -ENOMEM;
2595 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2596 0 /* not legacy */, cifs_sb->local_nls,
2597 cifs_sb->mnt_cifs_flags &
2598 CIFS_MOUNT_MAP_SPECIAL_CHR);
2599 kfree(pfile_info);
2600 return rc;
2603 static void
2604 cleanup_volume_info(struct smb_vol **pvolume_info)
2606 struct smb_vol *volume_info;
2608 if (!pvolume_info || !*pvolume_info)
2609 return;
2611 volume_info = *pvolume_info;
2612 kzfree(volume_info->password);
2613 kfree(volume_info->UNC);
2614 kfree(volume_info->prepath);
2615 kfree(volume_info);
2616 *pvolume_info = NULL;
2617 return;
2620 #ifdef CONFIG_CIFS_DFS_UPCALL
2621 /* build_path_to_root returns full path to root when
2622 * we do not have an exiting connection (tcon) */
2623 static char *
2624 build_unc_path_to_root(const struct smb_vol *volume_info,
2625 const struct cifs_sb_info *cifs_sb)
2627 char *full_path;
2629 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2630 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2631 if (full_path == NULL)
2632 return ERR_PTR(-ENOMEM);
2634 strncpy(full_path, volume_info->UNC, unc_len);
2635 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2636 int i;
2637 for (i = 0; i < unc_len; i++) {
2638 if (full_path[i] == '\\')
2639 full_path[i] = '/';
2643 if (cifs_sb->prepathlen)
2644 strncpy(full_path + unc_len, cifs_sb->prepath,
2645 cifs_sb->prepathlen);
2647 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2648 return full_path;
2650 #endif
2653 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2654 char *mount_data_global, const char *devname)
2656 int rc;
2657 int xid;
2658 struct smb_vol *volume_info;
2659 struct cifsSesInfo *pSesInfo;
2660 struct cifsTconInfo *tcon;
2661 struct TCP_Server_Info *srvTcp;
2662 char *full_path;
2663 char *mount_data = mount_data_global;
2664 struct tcon_link *tlink;
2665 #ifdef CONFIG_CIFS_DFS_UPCALL
2666 struct dfs_info3_param *referrals = NULL;
2667 unsigned int num_referrals = 0;
2668 int referral_walks_count = 0;
2669 try_mount_again:
2670 #endif
2671 rc = 0;
2672 tcon = NULL;
2673 pSesInfo = NULL;
2674 srvTcp = NULL;
2675 full_path = NULL;
2676 tlink = NULL;
2678 xid = GetXid();
2680 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2681 if (!volume_info) {
2682 rc = -ENOMEM;
2683 goto out;
2686 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2687 rc = -EINVAL;
2688 goto out;
2691 if (volume_info->nullauth) {
2692 cFYI(1, "null user");
2693 volume_info->username = "";
2694 } else if (volume_info->username) {
2695 /* BB fixme parse for domain name here */
2696 cFYI(1, "Username: %s", volume_info->username);
2697 } else {
2698 cifserror("No username specified");
2699 /* In userspace mount helper we can get user name from alternate
2700 locations such as env variables and files on disk */
2701 rc = -EINVAL;
2702 goto out;
2705 /* this is needed for ASCII cp to Unicode converts */
2706 if (volume_info->iocharset == NULL) {
2707 /* load_nls_default cannot return null */
2708 volume_info->local_nls = load_nls_default();
2709 } else {
2710 volume_info->local_nls = load_nls(volume_info->iocharset);
2711 if (volume_info->local_nls == NULL) {
2712 cERROR(1, "CIFS mount error: iocharset %s not found",
2713 volume_info->iocharset);
2714 rc = -ELIBACC;
2715 goto out;
2718 cifs_sb->local_nls = volume_info->local_nls;
2720 /* get a reference to a tcp session */
2721 srvTcp = cifs_get_tcp_session(volume_info);
2722 if (IS_ERR(srvTcp)) {
2723 rc = PTR_ERR(srvTcp);
2724 goto out;
2727 /* get a reference to a SMB session */
2728 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2729 if (IS_ERR(pSesInfo)) {
2730 rc = PTR_ERR(pSesInfo);
2731 pSesInfo = NULL;
2732 goto mount_fail_check;
2735 setup_cifs_sb(volume_info, cifs_sb);
2736 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2737 sb->s_maxbytes = MAX_LFS_FILESIZE;
2738 else
2739 sb->s_maxbytes = MAX_NON_LFS;
2741 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2742 sb->s_time_gran = 100;
2744 /* search for existing tcon to this server share */
2745 tcon = cifs_get_tcon(pSesInfo, volume_info);
2746 if (IS_ERR(tcon)) {
2747 rc = PTR_ERR(tcon);
2748 tcon = NULL;
2749 goto remote_path_check;
2752 /* do not care if following two calls succeed - informational */
2753 if (!tcon->ipc) {
2754 CIFSSMBQFSDeviceInfo(xid, tcon);
2755 CIFSSMBQFSAttributeInfo(xid, tcon);
2758 /* tell server which Unix caps we support */
2759 if (tcon->ses->capabilities & CAP_UNIX)
2760 /* reset of caps checks mount to see if unix extensions
2761 disabled for just this mount */
2762 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2763 else
2764 tcon->unix_ext = 0; /* server does not support them */
2766 /* convert forward to back slashes in prepath here if needed */
2767 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2768 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2770 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2771 cifs_sb->rsize = 1024 * 127;
2772 cFYI(DBG2, "no very large read support, rsize now 127K");
2774 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2775 cifs_sb->wsize = min(cifs_sb->wsize,
2776 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2777 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2778 cifs_sb->rsize = min(cifs_sb->rsize,
2779 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2781 remote_path_check:
2782 /* check if a whole path (including prepath) is not remote */
2783 if (!rc && cifs_sb->prepathlen && tcon) {
2784 /* build_path_to_root works only when we have a valid tcon */
2785 full_path = cifs_build_path_to_root(cifs_sb);
2786 if (full_path == NULL) {
2787 rc = -ENOMEM;
2788 goto mount_fail_check;
2790 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2791 if (rc != -EREMOTE) {
2792 kfree(full_path);
2793 goto mount_fail_check;
2795 kfree(full_path);
2798 /* get referral if needed */
2799 if (rc == -EREMOTE) {
2800 #ifdef CONFIG_CIFS_DFS_UPCALL
2801 if (referral_walks_count > MAX_NESTED_LINKS) {
2803 * BB: when we implement proper loop detection,
2804 * we will remove this check. But now we need it
2805 * to prevent an indefinite loop if 'DFS tree' is
2806 * misconfigured (i.e. has loops).
2808 rc = -ELOOP;
2809 goto mount_fail_check;
2811 /* convert forward to back slashes in prepath here if needed */
2812 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2813 convert_delimiter(cifs_sb->prepath,
2814 CIFS_DIR_SEP(cifs_sb));
2815 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2816 if (IS_ERR(full_path)) {
2817 rc = PTR_ERR(full_path);
2818 goto mount_fail_check;
2821 cFYI(1, "Getting referral for: %s", full_path);
2822 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2823 cifs_sb->local_nls, &num_referrals, &referrals,
2824 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2825 if (!rc && num_referrals > 0) {
2826 char *fake_devname = NULL;
2828 if (mount_data != mount_data_global)
2829 kfree(mount_data);
2831 mount_data = cifs_compose_mount_options(
2832 cifs_sb->mountdata, full_path + 1,
2833 referrals, &fake_devname);
2835 free_dfs_info_array(referrals, num_referrals);
2836 kfree(fake_devname);
2837 kfree(full_path);
2839 if (IS_ERR(mount_data)) {
2840 rc = PTR_ERR(mount_data);
2841 mount_data = NULL;
2842 goto mount_fail_check;
2845 if (tcon)
2846 cifs_put_tcon(tcon);
2847 else if (pSesInfo)
2848 cifs_put_smb_ses(pSesInfo);
2850 cleanup_volume_info(&volume_info);
2851 referral_walks_count++;
2852 FreeXid(xid);
2853 goto try_mount_again;
2855 #else /* No DFS support, return error on mount */
2856 rc = -EOPNOTSUPP;
2857 #endif
2860 if (rc)
2861 goto mount_fail_check;
2863 /* now, hang the tcon off of the superblock */
2864 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2865 if (tlink == NULL) {
2866 rc = -ENOMEM;
2867 goto mount_fail_check;
2870 tlink->tl_index = pSesInfo->linux_uid;
2871 tlink->tl_tcon = tcon;
2872 tlink->tl_time = jiffies;
2873 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2874 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2876 rc = radix_tree_preload(GFP_KERNEL);
2877 if (rc == -ENOMEM) {
2878 kfree(tlink);
2879 goto mount_fail_check;
2882 spin_lock(&cifs_sb->tlink_tree_lock);
2883 radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink);
2884 radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid,
2885 CIFS_TLINK_MASTER_TAG);
2886 spin_unlock(&cifs_sb->tlink_tree_lock);
2887 radix_tree_preload_end();
2889 mount_fail_check:
2890 /* on error free sesinfo and tcon struct if needed */
2891 if (rc) {
2892 if (mount_data != mount_data_global)
2893 kfree(mount_data);
2894 /* If find_unc succeeded then rc == 0 so we can not end */
2895 /* up accidently freeing someone elses tcon struct */
2896 if (tcon)
2897 cifs_put_tcon(tcon);
2898 else if (pSesInfo)
2899 cifs_put_smb_ses(pSesInfo);
2900 else
2901 cifs_put_tcp_session(srvTcp);
2902 goto out;
2905 /* volume_info->password is freed above when existing session found
2906 (in which case it is not needed anymore) but when new sesion is created
2907 the password ptr is put in the new session structure (in which case the
2908 password will be freed at unmount time) */
2909 out:
2910 /* zero out password before freeing */
2911 cleanup_volume_info(&volume_info);
2912 FreeXid(xid);
2913 return rc;
2917 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2918 const char *tree, struct cifsTconInfo *tcon,
2919 const struct nls_table *nls_codepage)
2921 struct smb_hdr *smb_buffer;
2922 struct smb_hdr *smb_buffer_response;
2923 TCONX_REQ *pSMB;
2924 TCONX_RSP *pSMBr;
2925 unsigned char *bcc_ptr;
2926 int rc = 0;
2927 int length, bytes_left;
2928 __u16 count;
2930 if (ses == NULL)
2931 return -EIO;
2933 smb_buffer = cifs_buf_get();
2934 if (smb_buffer == NULL)
2935 return -ENOMEM;
2937 smb_buffer_response = smb_buffer;
2939 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2940 NULL /*no tid */ , 4 /*wct */ );
2942 smb_buffer->Mid = GetNextMid(ses->server);
2943 smb_buffer->Uid = ses->Suid;
2944 pSMB = (TCONX_REQ *) smb_buffer;
2945 pSMBr = (TCONX_RSP *) smb_buffer_response;
2947 pSMB->AndXCommand = 0xFF;
2948 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
2949 bcc_ptr = &pSMB->Password[0];
2950 if ((ses->server->secMode) & SECMODE_USER) {
2951 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
2952 *bcc_ptr = 0; /* password is null byte */
2953 bcc_ptr++; /* skip password */
2954 /* already aligned so no need to do it below */
2955 } else {
2956 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
2957 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2958 specified as required (when that support is added to
2959 the vfs in the future) as only NTLM or the much
2960 weaker LANMAN (which we do not send by default) is accepted
2961 by Samba (not sure whether other servers allow
2962 NTLMv2 password here) */
2963 #ifdef CONFIG_CIFS_WEAK_PW_HASH
2964 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2965 (ses->server->secType == LANMAN))
2966 calc_lanman_hash(tcon->password, ses->server->cryptKey,
2967 ses->server->secMode &
2968 SECMODE_PW_ENCRYPT ? true : false,
2969 bcc_ptr);
2970 else
2971 #endif /* CIFS_WEAK_PW_HASH */
2972 SMBNTencrypt(tcon->password, ses->server->cryptKey,
2973 bcc_ptr);
2975 bcc_ptr += CIFS_SESS_KEY_SIZE;
2976 if (ses->capabilities & CAP_UNICODE) {
2977 /* must align unicode strings */
2978 *bcc_ptr = 0; /* null byte password */
2979 bcc_ptr++;
2983 if (ses->server->secMode &
2984 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2985 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2987 if (ses->capabilities & CAP_STATUS32) {
2988 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2990 if (ses->capabilities & CAP_DFS) {
2991 smb_buffer->Flags2 |= SMBFLG2_DFS;
2993 if (ses->capabilities & CAP_UNICODE) {
2994 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2995 length =
2996 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
2997 6 /* max utf8 char length in bytes */ *
2998 (/* server len*/ + 256 /* share len */), nls_codepage);
2999 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3000 bcc_ptr += 2; /* skip trailing null */
3001 } else { /* ASCII */
3002 strcpy(bcc_ptr, tree);
3003 bcc_ptr += strlen(tree) + 1;
3005 strcpy(bcc_ptr, "?????");
3006 bcc_ptr += strlen("?????");
3007 bcc_ptr += 1;
3008 count = bcc_ptr - &pSMB->Password[0];
3009 pSMB->hdr.smb_buf_length += count;
3010 pSMB->ByteCount = cpu_to_le16(count);
3012 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3013 CIFS_STD_OP);
3015 /* above now done in SendReceive */
3016 if ((rc == 0) && (tcon != NULL)) {
3017 bool is_unicode;
3019 tcon->tidStatus = CifsGood;
3020 tcon->need_reconnect = false;
3021 tcon->tid = smb_buffer_response->Tid;
3022 bcc_ptr = pByteArea(smb_buffer_response);
3023 bytes_left = BCC(smb_buffer_response);
3024 length = strnlen(bcc_ptr, bytes_left - 2);
3025 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3026 is_unicode = true;
3027 else
3028 is_unicode = false;
3031 /* skip service field (NB: this field is always ASCII) */
3032 if (length == 3) {
3033 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3034 (bcc_ptr[2] == 'C')) {
3035 cFYI(1, "IPC connection");
3036 tcon->ipc = 1;
3038 } else if (length == 2) {
3039 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3040 /* the most common case */
3041 cFYI(1, "disk share connection");
3044 bcc_ptr += length + 1;
3045 bytes_left -= (length + 1);
3046 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3048 /* mostly informational -- no need to fail on error here */
3049 kfree(tcon->nativeFileSystem);
3050 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3051 bytes_left, is_unicode,
3052 nls_codepage);
3054 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
3056 if ((smb_buffer_response->WordCount == 3) ||
3057 (smb_buffer_response->WordCount == 7))
3058 /* field is in same location */
3059 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3060 else
3061 tcon->Flags = 0;
3062 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
3063 } else if ((rc == 0) && tcon == NULL) {
3064 /* all we need to save for IPC$ connection */
3065 ses->ipc_tid = smb_buffer_response->Tid;
3068 cifs_buf_release(smb_buffer);
3069 return rc;
3073 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3075 int i, ret;
3076 char *tmp;
3077 struct tcon_link *tlink[8];
3078 unsigned long index = 0;
3080 do {
3081 spin_lock(&cifs_sb->tlink_tree_lock);
3082 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3083 (void **)tlink, index,
3084 ARRAY_SIZE(tlink));
3085 /* increment index for next pass */
3086 if (ret > 0)
3087 index = tlink[ret - 1]->tl_index + 1;
3088 for (i = 0; i < ret; i++) {
3089 cifs_get_tlink(tlink[i]);
3090 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3091 radix_tree_delete(&cifs_sb->tlink_tree,
3092 tlink[i]->tl_index);
3094 spin_unlock(&cifs_sb->tlink_tree_lock);
3096 for (i = 0; i < ret; i++)
3097 cifs_put_tlink(tlink[i]);
3098 } while (ret != 0);
3100 tmp = cifs_sb->prepath;
3101 cifs_sb->prepathlen = 0;
3102 cifs_sb->prepath = NULL;
3103 kfree(tmp);
3105 return 0;
3108 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3110 int rc = 0;
3111 struct TCP_Server_Info *server = ses->server;
3113 /* only send once per connect */
3114 if (server->maxBuf != 0)
3115 return 0;
3117 rc = CIFSSMBNegotiate(xid, ses);
3118 if (rc == -EAGAIN) {
3119 /* retry only once on 1st time connection */
3120 rc = CIFSSMBNegotiate(xid, ses);
3121 if (rc == -EAGAIN)
3122 rc = -EHOSTDOWN;
3124 if (rc == 0) {
3125 spin_lock(&GlobalMid_Lock);
3126 if (server->tcpStatus != CifsExiting)
3127 server->tcpStatus = CifsGood;
3128 else
3129 rc = -EHOSTDOWN;
3130 spin_unlock(&GlobalMid_Lock);
3134 return rc;
3138 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3139 struct nls_table *nls_info)
3141 int rc = 0;
3142 struct TCP_Server_Info *server = ses->server;
3144 ses->flags = 0;
3145 ses->capabilities = server->capabilities;
3146 if (linuxExtEnabled == 0)
3147 ses->capabilities &= (~CAP_UNIX);
3149 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3150 server->secMode, server->capabilities, server->timeAdj);
3152 rc = CIFS_SessSetup(xid, ses, nls_info);
3153 if (rc) {
3154 cERROR(1, "Send error in SessSetup = %d", rc);
3155 } else {
3156 cFYI(1, "CIFS Session Established successfully");
3157 spin_lock(&GlobalMid_Lock);
3158 ses->status = CifsGood;
3159 ses->need_reconnect = false;
3160 spin_unlock(&GlobalMid_Lock);
3163 return rc;
3166 struct cifsTconInfo *
3167 cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3169 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3170 struct cifsSesInfo *ses;
3171 struct cifsTconInfo *tcon = NULL;
3172 struct smb_vol *vol_info;
3173 char username[MAX_USERNAME_SIZE + 1];
3175 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3176 if (vol_info == NULL) {
3177 tcon = ERR_PTR(-ENOMEM);
3178 goto out;
3181 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3182 vol_info->username = username;
3183 vol_info->local_nls = cifs_sb->local_nls;
3184 vol_info->linux_uid = fsuid;
3185 vol_info->cred_uid = fsuid;
3186 vol_info->UNC = master_tcon->treeName;
3187 vol_info->retry = master_tcon->retry;
3188 vol_info->nocase = master_tcon->nocase;
3189 vol_info->local_lease = master_tcon->local_lease;
3190 vol_info->no_linux_ext = !master_tcon->unix_ext;
3192 /* FIXME: allow for other secFlg settings */
3193 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3195 /* get a reference for the same TCP session */
3196 write_lock(&cifs_tcp_ses_lock);
3197 ++master_tcon->ses->server->srv_count;
3198 write_unlock(&cifs_tcp_ses_lock);
3200 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3201 if (IS_ERR(ses)) {
3202 tcon = (struct cifsTconInfo *)ses;
3203 cifs_put_tcp_session(master_tcon->ses->server);
3204 goto out;
3207 tcon = cifs_get_tcon(ses, vol_info);
3208 if (IS_ERR(tcon)) {
3209 cifs_put_smb_ses(ses);
3210 goto out;
3213 if (ses->capabilities & CAP_UNIX)
3214 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3215 out:
3216 kfree(vol_info);
3218 return tcon;
3221 static struct tcon_link *
3222 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3224 struct tcon_link *tlink;
3225 unsigned int ret;
3227 spin_lock(&cifs_sb->tlink_tree_lock);
3228 ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink,
3229 0, 1, CIFS_TLINK_MASTER_TAG);
3230 spin_unlock(&cifs_sb->tlink_tree_lock);
3232 /* the master tcon should always be present */
3233 if (ret == 0)
3234 BUG();
3236 return tlink;
3239 struct cifsTconInfo *
3240 cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3242 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3245 static int
3246 cifs_sb_tcon_pending_wait(void *unused)
3248 schedule();
3249 return signal_pending(current) ? -ERESTARTSYS : 0;
3253 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3254 * current task.
3256 * If the superblock doesn't refer to a multiuser mount, then just return
3257 * the master tcon for the mount.
3259 * First, search the radix tree for an existing tcon for this fsuid. If one
3260 * exists, then check to see if it's pending construction. If it is then wait
3261 * for construction to complete. Once it's no longer pending, check to see if
3262 * it failed and either return an error or retry construction, depending on
3263 * the timeout.
3265 * If one doesn't exist then insert a new tcon_link struct into the tree and
3266 * try to construct a new one.
3268 struct tcon_link *
3269 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3271 int ret;
3272 unsigned long fsuid = (unsigned long) current_fsuid();
3273 struct tcon_link *tlink, *newtlink;
3275 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3276 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3278 spin_lock(&cifs_sb->tlink_tree_lock);
3279 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3280 if (tlink)
3281 cifs_get_tlink(tlink);
3282 spin_unlock(&cifs_sb->tlink_tree_lock);
3284 if (tlink == NULL) {
3285 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3286 if (newtlink == NULL)
3287 return ERR_PTR(-ENOMEM);
3288 newtlink->tl_index = fsuid;
3289 newtlink->tl_tcon = ERR_PTR(-EACCES);
3290 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3291 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3292 cifs_get_tlink(newtlink);
3294 ret = radix_tree_preload(GFP_KERNEL);
3295 if (ret != 0) {
3296 kfree(newtlink);
3297 return ERR_PTR(ret);
3300 spin_lock(&cifs_sb->tlink_tree_lock);
3301 /* was one inserted after previous search? */
3302 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3303 if (tlink) {
3304 cifs_get_tlink(tlink);
3305 spin_unlock(&cifs_sb->tlink_tree_lock);
3306 radix_tree_preload_end();
3307 kfree(newtlink);
3308 goto wait_for_construction;
3310 ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink);
3311 spin_unlock(&cifs_sb->tlink_tree_lock);
3312 radix_tree_preload_end();
3313 if (ret) {
3314 kfree(newtlink);
3315 return ERR_PTR(ret);
3317 tlink = newtlink;
3318 } else {
3319 wait_for_construction:
3320 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3321 cifs_sb_tcon_pending_wait,
3322 TASK_INTERRUPTIBLE);
3323 if (ret) {
3324 cifs_put_tlink(tlink);
3325 return ERR_PTR(ret);
3328 /* if it's good, return it */
3329 if (!IS_ERR(tlink->tl_tcon))
3330 return tlink;
3332 /* return error if we tried this already recently */
3333 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3334 cifs_put_tlink(tlink);
3335 return ERR_PTR(-EACCES);
3338 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3339 goto wait_for_construction;
3342 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3343 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3344 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3346 if (IS_ERR(tlink->tl_tcon)) {
3347 cifs_put_tlink(tlink);
3348 return ERR_PTR(-EACCES);
3351 return tlink;