ARM i.MX51 mx51-3ds: remove unnecessary CONFIG_KEYBOARD_IMX ifdefs
[linux-2.6/btrfs-unstable.git] / fs / cifs / connect.c
blob9f59887badd2255457a384feffee95a98a2fb9e7
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[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
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 bool multiuser:1;
104 unsigned int rsize;
105 unsigned int wsize;
106 bool sockopt_tcp_nodelay:1;
107 unsigned short int port;
108 unsigned long actimeo; /* attribute cache timeout (jiffies) */
109 char *prepath;
110 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
111 struct nls_table *local_nls;
114 /* FIXME: should these be tunable? */
115 #define TLINK_ERROR_EXPIRE (1 * HZ)
116 #define TLINK_IDLE_EXPIRE (600 * HZ)
118 static int ip_connect(struct TCP_Server_Info *server);
119 static int generic_ip_connect(struct TCP_Server_Info *server);
120 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
121 static void cifs_prune_tlinks(struct work_struct *work);
124 * cifs tcp session reconnection
126 * mark tcp session as reconnecting so temporarily locked
127 * mark all smb sessions as reconnecting for tcp session
128 * reconnect tcp session
129 * wake up waiters on reconnection? - (not needed currently)
131 static int
132 cifs_reconnect(struct TCP_Server_Info *server)
134 int rc = 0;
135 struct list_head *tmp, *tmp2;
136 struct cifsSesInfo *ses;
137 struct cifsTconInfo *tcon;
138 struct mid_q_entry *mid_entry;
140 spin_lock(&GlobalMid_Lock);
141 if (server->tcpStatus == CifsExiting) {
142 /* the demux thread will exit normally
143 next time through the loop */
144 spin_unlock(&GlobalMid_Lock);
145 return rc;
146 } else
147 server->tcpStatus = CifsNeedReconnect;
148 spin_unlock(&GlobalMid_Lock);
149 server->maxBuf = 0;
151 cFYI(1, "Reconnecting tcp session");
153 /* before reconnecting the tcp session, mark the smb session (uid)
154 and the tid bad so they are not used until reconnected */
155 spin_lock(&cifs_tcp_ses_lock);
156 list_for_each(tmp, &server->smb_ses_list) {
157 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
158 ses->need_reconnect = true;
159 ses->ipc_tid = 0;
160 list_for_each(tmp2, &ses->tcon_list) {
161 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
162 tcon->need_reconnect = true;
165 spin_unlock(&cifs_tcp_ses_lock);
166 /* do not want to be sending data on a socket we are freeing */
167 mutex_lock(&server->srv_mutex);
168 if (server->ssocket) {
169 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
170 server->ssocket->flags);
171 kernel_sock_shutdown(server->ssocket, SHUT_WR);
172 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
173 server->ssocket->state,
174 server->ssocket->flags);
175 sock_release(server->ssocket);
176 server->ssocket = NULL;
178 server->sequence_number = 0;
179 server->session_estab = false;
180 kfree(server->session_key.response);
181 server->session_key.response = NULL;
182 server->session_key.len = 0;
184 spin_lock(&GlobalMid_Lock);
185 list_for_each(tmp, &server->pending_mid_q) {
186 mid_entry = list_entry(tmp, struct
187 mid_q_entry,
188 qhead);
189 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
190 /* Mark other intransit requests as needing
191 retry so we do not immediately mark the
192 session bad again (ie after we reconnect
193 below) as they timeout too */
194 mid_entry->midState = MID_RETRY_NEEDED;
197 spin_unlock(&GlobalMid_Lock);
198 mutex_unlock(&server->srv_mutex);
200 while ((server->tcpStatus != CifsExiting) &&
201 (server->tcpStatus != CifsGood)) {
202 try_to_freeze();
204 /* we should try only the port we connected to before */
205 rc = generic_ip_connect(server);
206 if (rc) {
207 cFYI(1, "reconnect error %d", rc);
208 msleep(3000);
209 } else {
210 atomic_inc(&tcpSesReconnectCount);
211 spin_lock(&GlobalMid_Lock);
212 if (server->tcpStatus != CifsExiting)
213 server->tcpStatus = CifsGood;
214 spin_unlock(&GlobalMid_Lock);
215 /* atomic_set(&server->inFlight,0);*/
216 wake_up(&server->response_q);
219 return rc;
223 return codes:
224 0 not a transact2, or all data present
225 >0 transact2 with that much data missing
226 -EINVAL = invalid transact2
229 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
231 struct smb_t2_rsp *pSMBt;
232 int total_data_size;
233 int data_in_this_rsp;
234 int remaining;
236 if (pSMB->Command != SMB_COM_TRANSACTION2)
237 return 0;
239 /* check for plausible wct, bcc and t2 data and parm sizes */
240 /* check for parm and data offset going beyond end of smb */
241 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
242 cFYI(1, "invalid transact2 word count");
243 return -EINVAL;
246 pSMBt = (struct smb_t2_rsp *)pSMB;
248 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
249 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
251 remaining = total_data_size - data_in_this_rsp;
253 if (remaining == 0)
254 return 0;
255 else if (remaining < 0) {
256 cFYI(1, "total data %d smaller than data in frame %d",
257 total_data_size, data_in_this_rsp);
258 return -EINVAL;
259 } else {
260 cFYI(1, "missing %d bytes from transact2, check next response",
261 remaining);
262 if (total_data_size > maxBufSize) {
263 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
264 total_data_size, maxBufSize);
265 return -EINVAL;
267 return remaining;
271 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
273 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
274 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
275 int total_data_size;
276 int total_in_buf;
277 int remaining;
278 int total_in_buf2;
279 char *data_area_of_target;
280 char *data_area_of_buf2;
281 __u16 byte_count;
283 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
285 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
286 cFYI(1, "total data size of primary and secondary t2 differ");
289 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
291 remaining = total_data_size - total_in_buf;
293 if (remaining < 0)
294 return -EINVAL;
296 if (remaining == 0) /* nothing to do, ignore */
297 return 0;
299 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
300 if (remaining < total_in_buf2) {
301 cFYI(1, "transact2 2nd response contains too much data");
304 /* find end of first SMB data area */
305 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
306 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
307 /* validate target area */
309 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
310 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
312 data_area_of_target += total_in_buf;
314 /* copy second buffer into end of first buffer */
315 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
316 total_in_buf += total_in_buf2;
317 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
318 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
319 byte_count += total_in_buf2;
320 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
322 byte_count = pTargetSMB->smb_buf_length;
323 byte_count += total_in_buf2;
325 /* BB also add check that we are not beyond maximum buffer size */
327 pTargetSMB->smb_buf_length = byte_count;
329 if (remaining == total_in_buf2) {
330 cFYI(1, "found the last secondary response");
331 return 0; /* we are done */
332 } else /* more responses to go */
333 return 1;
337 static int
338 cifs_demultiplex_thread(struct TCP_Server_Info *server)
340 int length;
341 unsigned int pdu_length, total_read;
342 struct smb_hdr *smb_buffer = NULL;
343 struct smb_hdr *bigbuf = NULL;
344 struct smb_hdr *smallbuf = NULL;
345 struct msghdr smb_msg;
346 struct kvec iov;
347 struct socket *csocket = server->ssocket;
348 struct list_head *tmp;
349 struct cifsSesInfo *ses;
350 struct task_struct *task_to_wake = NULL;
351 struct mid_q_entry *mid_entry;
352 char temp;
353 bool isLargeBuf = false;
354 bool isMultiRsp;
355 int reconnect;
357 current->flags |= PF_MEMALLOC;
358 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
360 length = atomic_inc_return(&tcpSesAllocCount);
361 if (length > 1)
362 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
363 GFP_KERNEL);
365 set_freezable();
366 while (server->tcpStatus != CifsExiting) {
367 if (try_to_freeze())
368 continue;
369 if (bigbuf == NULL) {
370 bigbuf = cifs_buf_get();
371 if (!bigbuf) {
372 cERROR(1, "No memory for large SMB response");
373 msleep(3000);
374 /* retry will check if exiting */
375 continue;
377 } else if (isLargeBuf) {
378 /* we are reusing a dirty large buf, clear its start */
379 memset(bigbuf, 0, sizeof(struct smb_hdr));
382 if (smallbuf == NULL) {
383 smallbuf = cifs_small_buf_get();
384 if (!smallbuf) {
385 cERROR(1, "No memory for SMB response");
386 msleep(1000);
387 /* retry will check if exiting */
388 continue;
390 /* beginning of smb buffer is cleared in our buf_get */
391 } else /* if existing small buf clear beginning */
392 memset(smallbuf, 0, sizeof(struct smb_hdr));
394 isLargeBuf = false;
395 isMultiRsp = false;
396 smb_buffer = smallbuf;
397 iov.iov_base = smb_buffer;
398 iov.iov_len = 4;
399 smb_msg.msg_control = NULL;
400 smb_msg.msg_controllen = 0;
401 pdu_length = 4; /* enough to get RFC1001 header */
402 incomplete_rcv:
403 length =
404 kernel_recvmsg(csocket, &smb_msg,
405 &iov, 1, pdu_length, 0 /* BB other flags? */);
407 if (server->tcpStatus == CifsExiting) {
408 break;
409 } else if (server->tcpStatus == CifsNeedReconnect) {
410 cFYI(1, "Reconnect after server stopped responding");
411 cifs_reconnect(server);
412 cFYI(1, "call to reconnect done");
413 csocket = server->ssocket;
414 continue;
415 } else if (length == -ERESTARTSYS ||
416 length == -EAGAIN ||
417 length == -EINTR) {
418 msleep(1); /* minimum sleep to prevent looping
419 allowing socket to clear and app threads to set
420 tcpStatus CifsNeedReconnect if server hung */
421 if (pdu_length < 4) {
422 iov.iov_base = (4 - pdu_length) +
423 (char *)smb_buffer;
424 iov.iov_len = pdu_length;
425 smb_msg.msg_control = NULL;
426 smb_msg.msg_controllen = 0;
427 goto incomplete_rcv;
428 } else
429 continue;
430 } else if (length <= 0) {
431 cFYI(1, "Reconnect after unexpected peek error %d",
432 length);
433 cifs_reconnect(server);
434 csocket = server->ssocket;
435 wake_up(&server->response_q);
436 continue;
437 } else if (length < pdu_length) {
438 cFYI(1, "requested %d bytes but only got %d bytes",
439 pdu_length, length);
440 pdu_length -= length;
441 msleep(1);
442 goto incomplete_rcv;
445 /* The right amount was read from socket - 4 bytes */
446 /* so we can now interpret the length field */
448 /* the first byte big endian of the length field,
449 is actually not part of the length but the type
450 with the most common, zero, as regular data */
451 temp = *((char *) smb_buffer);
453 /* Note that FC 1001 length is big endian on the wire,
454 but we convert it here so it is always manipulated
455 as host byte order */
456 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
457 smb_buffer->smb_buf_length = pdu_length;
459 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
461 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
462 continue;
463 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
464 cFYI(1, "Good RFC 1002 session rsp");
465 continue;
466 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
467 /* we get this from Windows 98 instead of
468 an error on SMB negprot response */
469 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
470 pdu_length);
471 /* give server a second to clean up */
472 msleep(1000);
473 /* always try 445 first on reconnect since we get NACK
474 * on some if we ever connected to port 139 (the NACK
475 * is since we do not begin with RFC1001 session
476 * initialize frame)
478 cifs_set_port((struct sockaddr *)
479 &server->dstaddr, CIFS_PORT);
480 cifs_reconnect(server);
481 csocket = server->ssocket;
482 wake_up(&server->response_q);
483 continue;
484 } else if (temp != (char) 0) {
485 cERROR(1, "Unknown RFC 1002 frame");
486 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
487 length);
488 cifs_reconnect(server);
489 csocket = server->ssocket;
490 continue;
493 /* else we have an SMB response */
494 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
495 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
496 cERROR(1, "Invalid size SMB length %d pdu_length %d",
497 length, pdu_length+4);
498 cifs_reconnect(server);
499 csocket = server->ssocket;
500 wake_up(&server->response_q);
501 continue;
504 /* else length ok */
505 reconnect = 0;
507 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
508 isLargeBuf = true;
509 memcpy(bigbuf, smallbuf, 4);
510 smb_buffer = bigbuf;
512 length = 0;
513 iov.iov_base = 4 + (char *)smb_buffer;
514 iov.iov_len = pdu_length;
515 for (total_read = 0; total_read < pdu_length;
516 total_read += length) {
517 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
518 pdu_length - total_read, 0);
519 if (server->tcpStatus == CifsExiting) {
520 /* then will exit */
521 reconnect = 2;
522 break;
523 } else if (server->tcpStatus == CifsNeedReconnect) {
524 cifs_reconnect(server);
525 csocket = server->ssocket;
526 /* Reconnect wakes up rspns q */
527 /* Now we will reread sock */
528 reconnect = 1;
529 break;
530 } else if (length == -ERESTARTSYS ||
531 length == -EAGAIN ||
532 length == -EINTR) {
533 msleep(1); /* minimum sleep to prevent looping,
534 allowing socket to clear and app
535 threads to set tcpStatus
536 CifsNeedReconnect if server hung*/
537 length = 0;
538 continue;
539 } else if (length <= 0) {
540 cERROR(1, "Received no data, expecting %d",
541 pdu_length - total_read);
542 cifs_reconnect(server);
543 csocket = server->ssocket;
544 reconnect = 1;
545 break;
548 if (reconnect == 2)
549 break;
550 else if (reconnect == 1)
551 continue;
553 length += 4; /* account for rfc1002 hdr */
556 dump_smb(smb_buffer, length);
557 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
558 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
559 continue;
563 task_to_wake = NULL;
564 spin_lock(&GlobalMid_Lock);
565 list_for_each(tmp, &server->pending_mid_q) {
566 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
568 if ((mid_entry->mid == smb_buffer->Mid) &&
569 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
570 (mid_entry->command == smb_buffer->Command)) {
571 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
572 /* We have a multipart transact2 resp */
573 isMultiRsp = true;
574 if (mid_entry->resp_buf) {
575 /* merge response - fix up 1st*/
576 if (coalesce_t2(smb_buffer,
577 mid_entry->resp_buf)) {
578 mid_entry->multiRsp =
579 true;
580 break;
581 } else {
582 /* all parts received */
583 mid_entry->multiEnd =
584 true;
585 goto multi_t2_fnd;
587 } else {
588 if (!isLargeBuf) {
589 cERROR(1, "1st trans2 resp needs bigbuf");
590 /* BB maybe we can fix this up, switch
591 to already allocated large buffer? */
592 } else {
593 /* Have first buffer */
594 mid_entry->resp_buf =
595 smb_buffer;
596 mid_entry->largeBuf =
597 true;
598 bigbuf = NULL;
601 break;
603 mid_entry->resp_buf = smb_buffer;
604 mid_entry->largeBuf = isLargeBuf;
605 multi_t2_fnd:
606 task_to_wake = mid_entry->tsk;
607 mid_entry->midState = MID_RESPONSE_RECEIVED;
608 #ifdef CONFIG_CIFS_STATS2
609 mid_entry->when_received = jiffies;
610 #endif
611 /* so we do not time out requests to server
612 which is still responding (since server could
613 be busy but not dead) */
614 server->lstrp = jiffies;
615 break;
618 spin_unlock(&GlobalMid_Lock);
619 if (task_to_wake) {
620 /* Was previous buf put in mpx struct for multi-rsp? */
621 if (!isMultiRsp) {
622 /* smb buffer will be freed by user thread */
623 if (isLargeBuf)
624 bigbuf = NULL;
625 else
626 smallbuf = NULL;
628 wake_up_process(task_to_wake);
629 } else if (!is_valid_oplock_break(smb_buffer, server) &&
630 !isMultiRsp) {
631 cERROR(1, "No task to wake, unknown frame received! "
632 "NumMids %d", midCount.counter);
633 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
634 sizeof(struct smb_hdr));
635 #ifdef CONFIG_CIFS_DEBUG2
636 cifs_dump_detail(smb_buffer);
637 cifs_dump_mids(server);
638 #endif /* CIFS_DEBUG2 */
641 } /* end while !EXITING */
643 /* take it off the list, if it's not already */
644 spin_lock(&cifs_tcp_ses_lock);
645 list_del_init(&server->tcp_ses_list);
646 spin_unlock(&cifs_tcp_ses_lock);
648 spin_lock(&GlobalMid_Lock);
649 server->tcpStatus = CifsExiting;
650 spin_unlock(&GlobalMid_Lock);
651 wake_up_all(&server->response_q);
653 /* check if we have blocked requests that need to free */
654 /* Note that cifs_max_pending is normally 50, but
655 can be set at module install time to as little as two */
656 spin_lock(&GlobalMid_Lock);
657 if (atomic_read(&server->inFlight) >= cifs_max_pending)
658 atomic_set(&server->inFlight, cifs_max_pending - 1);
659 /* We do not want to set the max_pending too low or we
660 could end up with the counter going negative */
661 spin_unlock(&GlobalMid_Lock);
662 /* Although there should not be any requests blocked on
663 this queue it can not hurt to be paranoid and try to wake up requests
664 that may haven been blocked when more than 50 at time were on the wire
665 to the same server - they now will see the session is in exit state
666 and get out of SendReceive. */
667 wake_up_all(&server->request_q);
668 /* give those requests time to exit */
669 msleep(125);
671 if (server->ssocket) {
672 sock_release(csocket);
673 server->ssocket = NULL;
675 /* buffer usuallly freed in free_mid - need to free it here on exit */
676 cifs_buf_release(bigbuf);
677 if (smallbuf) /* no sense logging a debug message if NULL */
678 cifs_small_buf_release(smallbuf);
681 * BB: we shouldn't have to do any of this. It shouldn't be
682 * possible to exit from the thread with active SMB sessions
684 spin_lock(&cifs_tcp_ses_lock);
685 if (list_empty(&server->pending_mid_q)) {
686 /* loop through server session structures attached to this and
687 mark them dead */
688 list_for_each(tmp, &server->smb_ses_list) {
689 ses = list_entry(tmp, struct cifsSesInfo,
690 smb_ses_list);
691 ses->status = CifsExiting;
692 ses->server = NULL;
694 spin_unlock(&cifs_tcp_ses_lock);
695 } else {
696 /* although we can not zero the server struct pointer yet,
697 since there are active requests which may depnd on them,
698 mark the corresponding SMB sessions as exiting too */
699 list_for_each(tmp, &server->smb_ses_list) {
700 ses = list_entry(tmp, struct cifsSesInfo,
701 smb_ses_list);
702 ses->status = CifsExiting;
705 spin_lock(&GlobalMid_Lock);
706 list_for_each(tmp, &server->pending_mid_q) {
707 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
708 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
709 cFYI(1, "Clearing Mid 0x%x - waking up ",
710 mid_entry->mid);
711 task_to_wake = mid_entry->tsk;
712 if (task_to_wake)
713 wake_up_process(task_to_wake);
716 spin_unlock(&GlobalMid_Lock);
717 spin_unlock(&cifs_tcp_ses_lock);
718 /* 1/8th of sec is more than enough time for them to exit */
719 msleep(125);
722 if (!list_empty(&server->pending_mid_q)) {
723 /* mpx threads have not exited yet give them
724 at least the smb send timeout time for long ops */
725 /* due to delays on oplock break requests, we need
726 to wait at least 45 seconds before giving up
727 on a request getting a response and going ahead
728 and killing cifsd */
729 cFYI(1, "Wait for exit from demultiplex thread");
730 msleep(46000);
731 /* if threads still have not exited they are probably never
732 coming home not much else we can do but free the memory */
735 /* last chance to mark ses pointers invalid
736 if there are any pointing to this (e.g
737 if a crazy root user tried to kill cifsd
738 kernel thread explicitly this might happen) */
739 /* BB: This shouldn't be necessary, see above */
740 spin_lock(&cifs_tcp_ses_lock);
741 list_for_each(tmp, &server->smb_ses_list) {
742 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
743 ses->server = NULL;
745 spin_unlock(&cifs_tcp_ses_lock);
747 kfree(server->hostname);
748 task_to_wake = xchg(&server->tsk, NULL);
749 kfree(server);
751 length = atomic_dec_return(&tcpSesAllocCount);
752 if (length > 0)
753 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
754 GFP_KERNEL);
756 /* if server->tsk was NULL then wait for a signal before exiting */
757 if (!task_to_wake) {
758 set_current_state(TASK_INTERRUPTIBLE);
759 while (!signal_pending(current)) {
760 schedule();
761 set_current_state(TASK_INTERRUPTIBLE);
763 set_current_state(TASK_RUNNING);
766 module_put_and_exit(0);
769 /* extract the host portion of the UNC string */
770 static char *
771 extract_hostname(const char *unc)
773 const char *src;
774 char *dst, *delim;
775 unsigned int len;
777 /* skip double chars at beginning of string */
778 /* BB: check validity of these bytes? */
779 src = unc + 2;
781 /* delimiter between hostname and sharename is always '\\' now */
782 delim = strchr(src, '\\');
783 if (!delim)
784 return ERR_PTR(-EINVAL);
786 len = delim - src;
787 dst = kmalloc((len + 1), GFP_KERNEL);
788 if (dst == NULL)
789 return ERR_PTR(-ENOMEM);
791 memcpy(dst, src, len);
792 dst[len] = '\0';
794 return dst;
797 static int
798 cifs_parse_mount_options(char *options, const char *devname,
799 struct smb_vol *vol)
801 char *value;
802 char *data;
803 unsigned int temp_len, i, j;
804 char separator[2];
805 short int override_uid = -1;
806 short int override_gid = -1;
807 bool uid_specified = false;
808 bool gid_specified = false;
809 char *nodename = utsname()->nodename;
811 separator[0] = ',';
812 separator[1] = 0;
815 * does not have to be perfect mapping since field is
816 * informational, only used for servers that do not support
817 * port 445 and it can be overridden at mount time
819 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
820 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
821 vol->source_rfc1001_name[i] = toupper(nodename[i]);
823 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
824 /* null target name indicates to use *SMBSERVR default called name
825 if we end up sending RFC1001 session initialize */
826 vol->target_rfc1001_name[0] = 0;
827 vol->cred_uid = current_uid();
828 vol->linux_uid = current_uid();
829 vol->linux_gid = current_gid();
831 /* default to only allowing write access to owner of the mount */
832 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
834 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
835 /* default is always to request posix paths. */
836 vol->posix_paths = 1;
837 /* default to using server inode numbers where available */
838 vol->server_ino = 1;
840 vol->actimeo = CIFS_DEF_ACTIMEO;
842 if (!options)
843 return 1;
845 if (strncmp(options, "sep=", 4) == 0) {
846 if (options[4] != 0) {
847 separator[0] = options[4];
848 options += 5;
849 } else {
850 cFYI(1, "Null separator not allowed");
854 while ((data = strsep(&options, separator)) != NULL) {
855 if (!*data)
856 continue;
857 if ((value = strchr(data, '=')) != NULL)
858 *value++ = '\0';
860 /* Have to parse this before we parse for "user" */
861 if (strnicmp(data, "user_xattr", 10) == 0) {
862 vol->no_xattr = 0;
863 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
864 vol->no_xattr = 1;
865 } else if (strnicmp(data, "user", 4) == 0) {
866 if (!value) {
867 printk(KERN_WARNING
868 "CIFS: invalid or missing username\n");
869 return 1; /* needs_arg; */
870 } else if (!*value) {
871 /* null user, ie anonymous, authentication */
872 vol->nullauth = 1;
874 if (strnlen(value, 200) < 200) {
875 vol->username = value;
876 } else {
877 printk(KERN_WARNING "CIFS: username too long\n");
878 return 1;
880 } else if (strnicmp(data, "pass", 4) == 0) {
881 if (!value) {
882 vol->password = NULL;
883 continue;
884 } else if (value[0] == 0) {
885 /* check if string begins with double comma
886 since that would mean the password really
887 does start with a comma, and would not
888 indicate an empty string */
889 if (value[1] != separator[0]) {
890 vol->password = NULL;
891 continue;
894 temp_len = strlen(value);
895 /* removed password length check, NTLM passwords
896 can be arbitrarily long */
898 /* if comma in password, the string will be
899 prematurely null terminated. Commas in password are
900 specified across the cifs mount interface by a double
901 comma ie ,, and a comma used as in other cases ie ','
902 as a parameter delimiter/separator is single and due
903 to the strsep above is temporarily zeroed. */
905 /* NB: password legally can have multiple commas and
906 the only illegal character in a password is null */
908 if ((value[temp_len] == 0) &&
909 (value[temp_len+1] == separator[0])) {
910 /* reinsert comma */
911 value[temp_len] = separator[0];
912 temp_len += 2; /* move after second comma */
913 while (value[temp_len] != 0) {
914 if (value[temp_len] == separator[0]) {
915 if (value[temp_len+1] ==
916 separator[0]) {
917 /* skip second comma */
918 temp_len++;
919 } else {
920 /* single comma indicating start
921 of next parm */
922 break;
925 temp_len++;
927 if (value[temp_len] == 0) {
928 options = NULL;
929 } else {
930 value[temp_len] = 0;
931 /* point option to start of next parm */
932 options = value + temp_len + 1;
934 /* go from value to value + temp_len condensing
935 double commas to singles. Note that this ends up
936 allocating a few bytes too many, which is ok */
937 vol->password = kzalloc(temp_len, GFP_KERNEL);
938 if (vol->password == NULL) {
939 printk(KERN_WARNING "CIFS: no memory "
940 "for password\n");
941 return 1;
943 for (i = 0, j = 0; i < temp_len; i++, j++) {
944 vol->password[j] = value[i];
945 if (value[i] == separator[0]
946 && value[i+1] == separator[0]) {
947 /* skip second comma */
948 i++;
951 vol->password[j] = 0;
952 } else {
953 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
954 if (vol->password == NULL) {
955 printk(KERN_WARNING "CIFS: no memory "
956 "for password\n");
957 return 1;
959 strcpy(vol->password, value);
961 } else if (!strnicmp(data, "ip", 2) ||
962 !strnicmp(data, "addr", 4)) {
963 if (!value || !*value) {
964 vol->UNCip = NULL;
965 } else if (strnlen(value, INET6_ADDRSTRLEN) <
966 INET6_ADDRSTRLEN) {
967 vol->UNCip = value;
968 } else {
969 printk(KERN_WARNING "CIFS: ip address "
970 "too long\n");
971 return 1;
973 } else if (strnicmp(data, "sec", 3) == 0) {
974 if (!value || !*value) {
975 cERROR(1, "no security value specified");
976 continue;
977 } else if (strnicmp(value, "krb5i", 5) == 0) {
978 vol->secFlg |= CIFSSEC_MAY_KRB5 |
979 CIFSSEC_MUST_SIGN;
980 } else if (strnicmp(value, "krb5p", 5) == 0) {
981 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
982 CIFSSEC_MAY_KRB5; */
983 cERROR(1, "Krb5 cifs privacy not supported");
984 return 1;
985 } else if (strnicmp(value, "krb5", 4) == 0) {
986 vol->secFlg |= CIFSSEC_MAY_KRB5;
987 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
988 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
989 CIFSSEC_MUST_SIGN;
990 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
991 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
992 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
993 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
994 CIFSSEC_MUST_SIGN;
995 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
996 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
997 } else if (strnicmp(value, "ntlmi", 5) == 0) {
998 vol->secFlg |= CIFSSEC_MAY_NTLM |
999 CIFSSEC_MUST_SIGN;
1000 } else if (strnicmp(value, "ntlm", 4) == 0) {
1001 /* ntlm is default so can be turned off too */
1002 vol->secFlg |= CIFSSEC_MAY_NTLM;
1003 } else if (strnicmp(value, "nontlm", 6) == 0) {
1004 /* BB is there a better way to do this? */
1005 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1006 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1007 } else if (strnicmp(value, "lanman", 6) == 0) {
1008 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1009 #endif
1010 } else if (strnicmp(value, "none", 4) == 0) {
1011 vol->nullauth = 1;
1012 } else {
1013 cERROR(1, "bad security option: %s", value);
1014 return 1;
1016 } else if ((strnicmp(data, "unc", 3) == 0)
1017 || (strnicmp(data, "target", 6) == 0)
1018 || (strnicmp(data, "path", 4) == 0)) {
1019 if (!value || !*value) {
1020 printk(KERN_WARNING "CIFS: invalid path to "
1021 "network resource\n");
1022 return 1; /* needs_arg; */
1024 if ((temp_len = strnlen(value, 300)) < 300) {
1025 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1026 if (vol->UNC == NULL)
1027 return 1;
1028 strcpy(vol->UNC, value);
1029 if (strncmp(vol->UNC, "//", 2) == 0) {
1030 vol->UNC[0] = '\\';
1031 vol->UNC[1] = '\\';
1032 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1033 printk(KERN_WARNING
1034 "CIFS: UNC Path does not begin "
1035 "with // or \\\\ \n");
1036 return 1;
1038 } else {
1039 printk(KERN_WARNING "CIFS: UNC name too long\n");
1040 return 1;
1042 } else if ((strnicmp(data, "domain", 3) == 0)
1043 || (strnicmp(data, "workgroup", 5) == 0)) {
1044 if (!value || !*value) {
1045 printk(KERN_WARNING "CIFS: invalid domain name\n");
1046 return 1; /* needs_arg; */
1048 /* BB are there cases in which a comma can be valid in
1049 a domain name and need special handling? */
1050 if (strnlen(value, 256) < 256) {
1051 vol->domainname = value;
1052 cFYI(1, "Domain name set");
1053 } else {
1054 printk(KERN_WARNING "CIFS: domain name too "
1055 "long\n");
1056 return 1;
1058 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1059 vol->srcaddr.ss_family = AF_UNSPEC;
1061 if (!value || !*value) {
1062 printk(KERN_WARNING "CIFS: srcaddr value"
1063 " not specified.\n");
1064 return 1; /* needs_arg; */
1066 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1067 value, strlen(value));
1068 if (i == 0) {
1069 printk(KERN_WARNING "CIFS: Could not parse"
1070 " srcaddr: %s\n",
1071 value);
1072 return 1;
1074 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1075 if (!value || !*value) {
1076 printk(KERN_WARNING
1077 "CIFS: invalid path prefix\n");
1078 return 1; /* needs_argument */
1080 if ((temp_len = strnlen(value, 1024)) < 1024) {
1081 if (value[0] != '/')
1082 temp_len++; /* missing leading slash */
1083 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1084 if (vol->prepath == NULL)
1085 return 1;
1086 if (value[0] != '/') {
1087 vol->prepath[0] = '/';
1088 strcpy(vol->prepath+1, value);
1089 } else
1090 strcpy(vol->prepath, value);
1091 cFYI(1, "prefix path %s", vol->prepath);
1092 } else {
1093 printk(KERN_WARNING "CIFS: prefix too long\n");
1094 return 1;
1096 } else if (strnicmp(data, "iocharset", 9) == 0) {
1097 if (!value || !*value) {
1098 printk(KERN_WARNING "CIFS: invalid iocharset "
1099 "specified\n");
1100 return 1; /* needs_arg; */
1102 if (strnlen(value, 65) < 65) {
1103 if (strnicmp(value, "default", 7))
1104 vol->iocharset = value;
1105 /* if iocharset not set then load_nls_default
1106 is used by caller */
1107 cFYI(1, "iocharset set to %s", value);
1108 } else {
1109 printk(KERN_WARNING "CIFS: iocharset name "
1110 "too long.\n");
1111 return 1;
1113 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1114 vol->linux_uid = simple_strtoul(value, &value, 0);
1115 uid_specified = true;
1116 } else if (!strnicmp(data, "cruid", 5) && value && *value) {
1117 vol->cred_uid = simple_strtoul(value, &value, 0);
1118 } else if (!strnicmp(data, "forceuid", 8)) {
1119 override_uid = 1;
1120 } else if (!strnicmp(data, "noforceuid", 10)) {
1121 override_uid = 0;
1122 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1123 vol->linux_gid = simple_strtoul(value, &value, 0);
1124 gid_specified = true;
1125 } else if (!strnicmp(data, "forcegid", 8)) {
1126 override_gid = 1;
1127 } else if (!strnicmp(data, "noforcegid", 10)) {
1128 override_gid = 0;
1129 } else if (strnicmp(data, "file_mode", 4) == 0) {
1130 if (value && *value) {
1131 vol->file_mode =
1132 simple_strtoul(value, &value, 0);
1134 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1135 if (value && *value) {
1136 vol->dir_mode =
1137 simple_strtoul(value, &value, 0);
1139 } else if (strnicmp(data, "dirmode", 4) == 0) {
1140 if (value && *value) {
1141 vol->dir_mode =
1142 simple_strtoul(value, &value, 0);
1144 } else if (strnicmp(data, "port", 4) == 0) {
1145 if (value && *value) {
1146 vol->port =
1147 simple_strtoul(value, &value, 0);
1149 } else if (strnicmp(data, "rsize", 5) == 0) {
1150 if (value && *value) {
1151 vol->rsize =
1152 simple_strtoul(value, &value, 0);
1154 } else if (strnicmp(data, "wsize", 5) == 0) {
1155 if (value && *value) {
1156 vol->wsize =
1157 simple_strtoul(value, &value, 0);
1159 } else if (strnicmp(data, "sockopt", 5) == 0) {
1160 if (!value || !*value) {
1161 cERROR(1, "no socket option specified");
1162 continue;
1163 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1164 vol->sockopt_tcp_nodelay = 1;
1166 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1167 if (!value || !*value || (*value == ' ')) {
1168 cFYI(1, "invalid (empty) netbiosname");
1169 } else {
1170 memset(vol->source_rfc1001_name, 0x20,
1171 RFC1001_NAME_LEN);
1173 * FIXME: are there cases in which a comma can
1174 * be valid in workstation netbios name (and
1175 * need special handling)?
1177 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1178 /* don't ucase netbiosname for user */
1179 if (value[i] == 0)
1180 break;
1181 vol->source_rfc1001_name[i] = value[i];
1183 /* The string has 16th byte zero still from
1184 set at top of the function */
1185 if (i == RFC1001_NAME_LEN && value[i] != 0)
1186 printk(KERN_WARNING "CIFS: netbiosname"
1187 " longer than 15 truncated.\n");
1189 } else if (strnicmp(data, "servern", 7) == 0) {
1190 /* servernetbiosname specified override *SMBSERVER */
1191 if (!value || !*value || (*value == ' ')) {
1192 cFYI(1, "empty server netbiosname specified");
1193 } else {
1194 /* last byte, type, is 0x20 for servr type */
1195 memset(vol->target_rfc1001_name, 0x20,
1196 RFC1001_NAME_LEN_WITH_NULL);
1198 for (i = 0; i < 15; i++) {
1199 /* BB are there cases in which a comma can be
1200 valid in this workstation netbios name
1201 (and need special handling)? */
1203 /* user or mount helper must uppercase
1204 the netbiosname */
1205 if (value[i] == 0)
1206 break;
1207 else
1208 vol->target_rfc1001_name[i] =
1209 value[i];
1211 /* The string has 16th byte zero still from
1212 set at top of the function */
1213 if (i == RFC1001_NAME_LEN && value[i] != 0)
1214 printk(KERN_WARNING "CIFS: server net"
1215 "biosname longer than 15 truncated.\n");
1217 } else if (strnicmp(data, "actimeo", 7) == 0) {
1218 if (value && *value) {
1219 vol->actimeo = HZ * simple_strtoul(value,
1220 &value, 0);
1221 if (vol->actimeo > CIFS_MAX_ACTIMEO) {
1222 cERROR(1, "CIFS: attribute cache"
1223 "timeout too large");
1224 return 1;
1227 } else if (strnicmp(data, "credentials", 4) == 0) {
1228 /* ignore */
1229 } else if (strnicmp(data, "version", 3) == 0) {
1230 /* ignore */
1231 } else if (strnicmp(data, "guest", 5) == 0) {
1232 /* ignore */
1233 } else if (strnicmp(data, "rw", 2) == 0) {
1234 /* ignore */
1235 } else if (strnicmp(data, "ro", 2) == 0) {
1236 /* ignore */
1237 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1238 vol->noblocksnd = 1;
1239 } else if (strnicmp(data, "noautotune", 10) == 0) {
1240 vol->noautotune = 1;
1241 } else if ((strnicmp(data, "suid", 4) == 0) ||
1242 (strnicmp(data, "nosuid", 6) == 0) ||
1243 (strnicmp(data, "exec", 4) == 0) ||
1244 (strnicmp(data, "noexec", 6) == 0) ||
1245 (strnicmp(data, "nodev", 5) == 0) ||
1246 (strnicmp(data, "noauto", 6) == 0) ||
1247 (strnicmp(data, "dev", 3) == 0)) {
1248 /* The mount tool or mount.cifs helper (if present)
1249 uses these opts to set flags, and the flags are read
1250 by the kernel vfs layer before we get here (ie
1251 before read super) so there is no point trying to
1252 parse these options again and set anything and it
1253 is ok to just ignore them */
1254 continue;
1255 } else if (strnicmp(data, "hard", 4) == 0) {
1256 vol->retry = 1;
1257 } else if (strnicmp(data, "soft", 4) == 0) {
1258 vol->retry = 0;
1259 } else if (strnicmp(data, "perm", 4) == 0) {
1260 vol->noperm = 0;
1261 } else if (strnicmp(data, "noperm", 6) == 0) {
1262 vol->noperm = 1;
1263 } else if (strnicmp(data, "mapchars", 8) == 0) {
1264 vol->remap = 1;
1265 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1266 vol->remap = 0;
1267 } else if (strnicmp(data, "sfu", 3) == 0) {
1268 vol->sfu_emul = 1;
1269 } else if (strnicmp(data, "nosfu", 5) == 0) {
1270 vol->sfu_emul = 0;
1271 } else if (strnicmp(data, "nodfs", 5) == 0) {
1272 vol->nodfs = 1;
1273 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1274 vol->posix_paths = 1;
1275 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1276 vol->posix_paths = 0;
1277 } else if (strnicmp(data, "nounix", 6) == 0) {
1278 vol->no_linux_ext = 1;
1279 } else if (strnicmp(data, "nolinux", 7) == 0) {
1280 vol->no_linux_ext = 1;
1281 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1282 (strnicmp(data, "ignorecase", 10) == 0)) {
1283 vol->nocase = 1;
1284 } else if (strnicmp(data, "mand", 4) == 0) {
1285 /* ignore */
1286 } else if (strnicmp(data, "nomand", 6) == 0) {
1287 /* ignore */
1288 } else if (strnicmp(data, "_netdev", 7) == 0) {
1289 /* ignore */
1290 } else if (strnicmp(data, "brl", 3) == 0) {
1291 vol->nobrl = 0;
1292 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1293 (strnicmp(data, "nolock", 6) == 0)) {
1294 vol->nobrl = 1;
1295 /* turn off mandatory locking in mode
1296 if remote locking is turned off since the
1297 local vfs will do advisory */
1298 if (vol->file_mode ==
1299 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1300 vol->file_mode = S_IALLUGO;
1301 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1302 /* will take the shorter form "forcemand" as well */
1303 /* This mount option will force use of mandatory
1304 (DOS/Windows style) byte range locks, instead of
1305 using posix advisory byte range locks, even if the
1306 Unix extensions are available and posix locks would
1307 be supported otherwise. If Unix extensions are not
1308 negotiated this has no effect since mandatory locks
1309 would be used (mandatory locks is all that those
1310 those servers support) */
1311 vol->mand_lock = 1;
1312 } else if (strnicmp(data, "setuids", 7) == 0) {
1313 vol->setuids = 1;
1314 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1315 vol->setuids = 0;
1316 } else if (strnicmp(data, "dynperm", 7) == 0) {
1317 vol->dynperm = true;
1318 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1319 vol->dynperm = false;
1320 } else if (strnicmp(data, "nohard", 6) == 0) {
1321 vol->retry = 0;
1322 } else if (strnicmp(data, "nosoft", 6) == 0) {
1323 vol->retry = 1;
1324 } else if (strnicmp(data, "nointr", 6) == 0) {
1325 vol->intr = 0;
1326 } else if (strnicmp(data, "intr", 4) == 0) {
1327 vol->intr = 1;
1328 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1329 vol->nostrictsync = 1;
1330 } else if (strnicmp(data, "strictsync", 10) == 0) {
1331 vol->nostrictsync = 0;
1332 } else if (strnicmp(data, "serverino", 7) == 0) {
1333 vol->server_ino = 1;
1334 } else if (strnicmp(data, "noserverino", 9) == 0) {
1335 vol->server_ino = 0;
1336 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1337 vol->cifs_acl = 1;
1338 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1339 vol->cifs_acl = 0;
1340 } else if (strnicmp(data, "acl", 3) == 0) {
1341 vol->no_psx_acl = 0;
1342 } else if (strnicmp(data, "noacl", 5) == 0) {
1343 vol->no_psx_acl = 1;
1344 } else if (strnicmp(data, "locallease", 6) == 0) {
1345 vol->local_lease = 1;
1346 } else if (strnicmp(data, "sign", 4) == 0) {
1347 vol->secFlg |= CIFSSEC_MUST_SIGN;
1348 } else if (strnicmp(data, "seal", 4) == 0) {
1349 /* we do not do the following in secFlags because seal
1350 is a per tree connection (mount) not a per socket
1351 or per-smb connection option in the protocol */
1352 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1353 vol->seal = 1;
1354 } else if (strnicmp(data, "direct", 6) == 0) {
1355 vol->direct_io = 1;
1356 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1357 vol->direct_io = 1;
1358 } else if (strnicmp(data, "noac", 4) == 0) {
1359 printk(KERN_WARNING "CIFS: Mount option noac not "
1360 "supported. Instead set "
1361 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1362 } else if (strnicmp(data, "fsc", 3) == 0) {
1363 #ifndef CONFIG_CIFS_FSCACHE
1364 cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
1365 "kernel config option set");
1366 return 1;
1367 #endif
1368 vol->fsc = true;
1369 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1370 vol->mfsymlinks = true;
1371 } else if (strnicmp(data, "multiuser", 8) == 0) {
1372 vol->multiuser = true;
1373 } else
1374 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1375 data);
1377 if (vol->UNC == NULL) {
1378 if (devname == NULL) {
1379 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1380 "target\n");
1381 return 1;
1383 if ((temp_len = strnlen(devname, 300)) < 300) {
1384 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1385 if (vol->UNC == NULL)
1386 return 1;
1387 strcpy(vol->UNC, devname);
1388 if (strncmp(vol->UNC, "//", 2) == 0) {
1389 vol->UNC[0] = '\\';
1390 vol->UNC[1] = '\\';
1391 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1392 printk(KERN_WARNING "CIFS: UNC Path does not "
1393 "begin with // or \\\\ \n");
1394 return 1;
1396 value = strpbrk(vol->UNC+2, "/\\");
1397 if (value)
1398 *value = '\\';
1399 } else {
1400 printk(KERN_WARNING "CIFS: UNC name too long\n");
1401 return 1;
1405 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1406 cERROR(1, "Multiuser mounts currently require krb5 "
1407 "authentication!");
1408 return 1;
1411 if (vol->UNCip == NULL)
1412 vol->UNCip = &vol->UNC[2];
1414 if (uid_specified)
1415 vol->override_uid = override_uid;
1416 else if (override_uid == 1)
1417 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1418 "specified with no uid= option.\n");
1420 if (gid_specified)
1421 vol->override_gid = override_gid;
1422 else if (override_gid == 1)
1423 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1424 "specified with no gid= option.\n");
1426 return 0;
1429 /** Returns true if srcaddr isn't specified and rhs isn't
1430 * specified, or if srcaddr is specified and
1431 * matches the IP address of the rhs argument.
1433 static bool
1434 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1436 switch (srcaddr->sa_family) {
1437 case AF_UNSPEC:
1438 return (rhs->sa_family == AF_UNSPEC);
1439 case AF_INET: {
1440 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1441 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1442 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1444 case AF_INET6: {
1445 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1446 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1447 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1449 default:
1450 WARN_ON(1);
1451 return false; /* don't expect to be here */
1456 * If no port is specified in addr structure, we try to match with 445 port
1457 * and if it fails - with 139 ports. It should be called only if address
1458 * families of server and addr are equal.
1460 static bool
1461 match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1463 unsigned short int port, *sport;
1465 switch (addr->sa_family) {
1466 case AF_INET:
1467 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1468 port = ((struct sockaddr_in *) addr)->sin_port;
1469 break;
1470 case AF_INET6:
1471 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1472 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1473 break;
1474 default:
1475 WARN_ON(1);
1476 return false;
1479 if (!port) {
1480 port = htons(CIFS_PORT);
1481 if (port == *sport)
1482 return true;
1484 port = htons(RFC1001_PORT);
1487 return port == *sport;
1490 static bool
1491 match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1492 struct sockaddr *srcaddr)
1494 switch (addr->sa_family) {
1495 case AF_INET: {
1496 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1497 struct sockaddr_in *srv_addr4 =
1498 (struct sockaddr_in *)&server->dstaddr;
1500 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1501 return false;
1502 break;
1504 case AF_INET6: {
1505 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1506 struct sockaddr_in6 *srv_addr6 =
1507 (struct sockaddr_in6 *)&server->dstaddr;
1509 if (!ipv6_addr_equal(&addr6->sin6_addr,
1510 &srv_addr6->sin6_addr))
1511 return false;
1512 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1513 return false;
1514 break;
1516 default:
1517 WARN_ON(1);
1518 return false; /* don't expect to be here */
1521 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1522 return false;
1524 return true;
1527 static bool
1528 match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1530 unsigned int secFlags;
1532 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1533 secFlags = vol->secFlg;
1534 else
1535 secFlags = global_secflags | vol->secFlg;
1537 switch (server->secType) {
1538 case LANMAN:
1539 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1540 return false;
1541 break;
1542 case NTLMv2:
1543 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1544 return false;
1545 break;
1546 case NTLM:
1547 if (!(secFlags & CIFSSEC_MAY_NTLM))
1548 return false;
1549 break;
1550 case Kerberos:
1551 if (!(secFlags & CIFSSEC_MAY_KRB5))
1552 return false;
1553 break;
1554 case RawNTLMSSP:
1555 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1556 return false;
1557 break;
1558 default:
1559 /* shouldn't happen */
1560 return false;
1563 /* now check if signing mode is acceptible */
1564 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1565 (server->secMode & SECMODE_SIGN_REQUIRED))
1566 return false;
1567 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1568 (server->secMode &
1569 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1570 return false;
1572 return true;
1575 static struct TCP_Server_Info *
1576 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1578 struct TCP_Server_Info *server;
1580 spin_lock(&cifs_tcp_ses_lock);
1581 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1582 if (!match_address(server, addr,
1583 (struct sockaddr *)&vol->srcaddr))
1584 continue;
1586 if (!match_port(server, addr))
1587 continue;
1589 if (!match_security(server, vol))
1590 continue;
1592 ++server->srv_count;
1593 spin_unlock(&cifs_tcp_ses_lock);
1594 cFYI(1, "Existing tcp session with server found");
1595 return server;
1597 spin_unlock(&cifs_tcp_ses_lock);
1598 return NULL;
1601 static void
1602 cifs_put_tcp_session(struct TCP_Server_Info *server)
1604 struct task_struct *task;
1606 spin_lock(&cifs_tcp_ses_lock);
1607 if (--server->srv_count > 0) {
1608 spin_unlock(&cifs_tcp_ses_lock);
1609 return;
1612 list_del_init(&server->tcp_ses_list);
1613 spin_unlock(&cifs_tcp_ses_lock);
1615 spin_lock(&GlobalMid_Lock);
1616 server->tcpStatus = CifsExiting;
1617 spin_unlock(&GlobalMid_Lock);
1619 cifs_crypto_shash_release(server);
1620 cifs_fscache_release_client_cookie(server);
1622 kfree(server->session_key.response);
1623 server->session_key.response = NULL;
1624 server->session_key.len = 0;
1626 task = xchg(&server->tsk, NULL);
1627 if (task)
1628 force_sig(SIGKILL, task);
1631 static struct TCP_Server_Info *
1632 cifs_get_tcp_session(struct smb_vol *volume_info)
1634 struct TCP_Server_Info *tcp_ses = NULL;
1635 struct sockaddr_storage addr;
1636 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1637 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1638 int rc;
1640 memset(&addr, 0, sizeof(struct sockaddr_storage));
1642 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1644 if (volume_info->UNCip && volume_info->UNC) {
1645 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1646 volume_info->UNCip,
1647 strlen(volume_info->UNCip),
1648 volume_info->port);
1649 if (!rc) {
1650 /* we failed translating address */
1651 rc = -EINVAL;
1652 goto out_err;
1654 } else if (volume_info->UNCip) {
1655 /* BB using ip addr as tcp_ses name to connect to the
1656 DFS root below */
1657 cERROR(1, "Connecting to DFS root not implemented yet");
1658 rc = -EINVAL;
1659 goto out_err;
1660 } else /* which tcp_sess DFS root would we conect to */ {
1661 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1662 "unc=//192.168.1.100/public) specified");
1663 rc = -EINVAL;
1664 goto out_err;
1667 /* see if we already have a matching tcp_ses */
1668 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1669 if (tcp_ses)
1670 return tcp_ses;
1672 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1673 if (!tcp_ses) {
1674 rc = -ENOMEM;
1675 goto out_err;
1678 rc = cifs_crypto_shash_allocate(tcp_ses);
1679 if (rc) {
1680 cERROR(1, "could not setup hash structures rc %d", rc);
1681 goto out_err;
1684 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1685 if (IS_ERR(tcp_ses->hostname)) {
1686 rc = PTR_ERR(tcp_ses->hostname);
1687 goto out_err_crypto_release;
1690 tcp_ses->noblocksnd = volume_info->noblocksnd;
1691 tcp_ses->noautotune = volume_info->noautotune;
1692 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1693 atomic_set(&tcp_ses->inFlight, 0);
1694 init_waitqueue_head(&tcp_ses->response_q);
1695 init_waitqueue_head(&tcp_ses->request_q);
1696 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1697 mutex_init(&tcp_ses->srv_mutex);
1698 memcpy(tcp_ses->workstation_RFC1001_name,
1699 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1700 memcpy(tcp_ses->server_RFC1001_name,
1701 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1702 tcp_ses->session_estab = false;
1703 tcp_ses->sequence_number = 0;
1704 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1705 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1708 * at this point we are the only ones with the pointer
1709 * to the struct since the kernel thread not created yet
1710 * no need to spinlock this init of tcpStatus or srv_count
1712 tcp_ses->tcpStatus = CifsNew;
1713 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1714 sizeof(tcp_ses->srcaddr));
1715 ++tcp_ses->srv_count;
1717 if (addr.ss_family == AF_INET6) {
1718 cFYI(1, "attempting ipv6 connect");
1719 /* BB should we allow ipv6 on port 139? */
1720 /* other OS never observed in Wild doing 139 with v6 */
1721 memcpy(&tcp_ses->dstaddr, sin_server6,
1722 sizeof(struct sockaddr_in6));
1723 } else
1724 memcpy(&tcp_ses->dstaddr, sin_server,
1725 sizeof(struct sockaddr_in));
1727 rc = ip_connect(tcp_ses);
1728 if (rc < 0) {
1729 cERROR(1, "Error connecting to socket. Aborting operation");
1730 goto out_err_crypto_release;
1734 * since we're in a cifs function already, we know that
1735 * this will succeed. No need for try_module_get().
1737 __module_get(THIS_MODULE);
1738 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1739 tcp_ses, "cifsd");
1740 if (IS_ERR(tcp_ses->tsk)) {
1741 rc = PTR_ERR(tcp_ses->tsk);
1742 cERROR(1, "error %d create cifsd thread", rc);
1743 module_put(THIS_MODULE);
1744 goto out_err_crypto_release;
1747 /* thread spawned, put it on the list */
1748 spin_lock(&cifs_tcp_ses_lock);
1749 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1750 spin_unlock(&cifs_tcp_ses_lock);
1752 cifs_fscache_get_client_cookie(tcp_ses);
1754 return tcp_ses;
1756 out_err_crypto_release:
1757 cifs_crypto_shash_release(tcp_ses);
1759 out_err:
1760 if (tcp_ses) {
1761 if (!IS_ERR(tcp_ses->hostname))
1762 kfree(tcp_ses->hostname);
1763 if (tcp_ses->ssocket)
1764 sock_release(tcp_ses->ssocket);
1765 kfree(tcp_ses);
1767 return ERR_PTR(rc);
1770 static struct cifsSesInfo *
1771 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1773 struct cifsSesInfo *ses;
1775 spin_lock(&cifs_tcp_ses_lock);
1776 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1777 switch (server->secType) {
1778 case Kerberos:
1779 if (vol->cred_uid != ses->cred_uid)
1780 continue;
1781 break;
1782 default:
1783 /* anything else takes username/password */
1784 if (strncmp(ses->userName, vol->username,
1785 MAX_USERNAME_SIZE))
1786 continue;
1787 if (strlen(vol->username) != 0 &&
1788 ses->password != NULL &&
1789 strncmp(ses->password,
1790 vol->password ? vol->password : "",
1791 MAX_PASSWORD_SIZE))
1792 continue;
1794 ++ses->ses_count;
1795 spin_unlock(&cifs_tcp_ses_lock);
1796 return ses;
1798 spin_unlock(&cifs_tcp_ses_lock);
1799 return NULL;
1802 static void
1803 cifs_put_smb_ses(struct cifsSesInfo *ses)
1805 int xid;
1806 struct TCP_Server_Info *server = ses->server;
1808 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1809 spin_lock(&cifs_tcp_ses_lock);
1810 if (--ses->ses_count > 0) {
1811 spin_unlock(&cifs_tcp_ses_lock);
1812 return;
1815 list_del_init(&ses->smb_ses_list);
1816 spin_unlock(&cifs_tcp_ses_lock);
1818 if (ses->status == CifsGood) {
1819 xid = GetXid();
1820 CIFSSMBLogoff(xid, ses);
1821 _FreeXid(xid);
1823 sesInfoFree(ses);
1824 cifs_put_tcp_session(server);
1827 static struct cifsSesInfo *
1828 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1830 int rc = -ENOMEM, xid;
1831 struct cifsSesInfo *ses;
1832 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1833 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1835 xid = GetXid();
1837 ses = cifs_find_smb_ses(server, volume_info);
1838 if (ses) {
1839 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1841 mutex_lock(&ses->session_mutex);
1842 rc = cifs_negotiate_protocol(xid, ses);
1843 if (rc) {
1844 mutex_unlock(&ses->session_mutex);
1845 /* problem -- put our ses reference */
1846 cifs_put_smb_ses(ses);
1847 FreeXid(xid);
1848 return ERR_PTR(rc);
1850 if (ses->need_reconnect) {
1851 cFYI(1, "Session needs reconnect");
1852 rc = cifs_setup_session(xid, ses,
1853 volume_info->local_nls);
1854 if (rc) {
1855 mutex_unlock(&ses->session_mutex);
1856 /* problem -- put our reference */
1857 cifs_put_smb_ses(ses);
1858 FreeXid(xid);
1859 return ERR_PTR(rc);
1862 mutex_unlock(&ses->session_mutex);
1864 /* existing SMB ses has a server reference already */
1865 cifs_put_tcp_session(server);
1866 FreeXid(xid);
1867 return ses;
1870 cFYI(1, "Existing smb sess not found");
1871 ses = sesInfoAlloc();
1872 if (ses == NULL)
1873 goto get_ses_fail;
1875 /* new SMB session uses our server ref */
1876 ses->server = server;
1877 if (server->dstaddr.ss_family == AF_INET6)
1878 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1879 else
1880 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1882 if (volume_info->username)
1883 strncpy(ses->userName, volume_info->username,
1884 MAX_USERNAME_SIZE);
1886 /* volume_info->password freed at unmount */
1887 if (volume_info->password) {
1888 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1889 if (!ses->password)
1890 goto get_ses_fail;
1892 if (volume_info->domainname) {
1893 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
1894 if (!ses->domainName)
1895 goto get_ses_fail;
1897 ses->cred_uid = volume_info->cred_uid;
1898 ses->linux_uid = volume_info->linux_uid;
1899 ses->overrideSecFlg = volume_info->secFlg;
1901 mutex_lock(&ses->session_mutex);
1902 rc = cifs_negotiate_protocol(xid, ses);
1903 if (!rc)
1904 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1905 mutex_unlock(&ses->session_mutex);
1906 if (rc)
1907 goto get_ses_fail;
1909 /* success, put it on the list */
1910 spin_lock(&cifs_tcp_ses_lock);
1911 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1912 spin_unlock(&cifs_tcp_ses_lock);
1914 FreeXid(xid);
1915 return ses;
1917 get_ses_fail:
1918 sesInfoFree(ses);
1919 FreeXid(xid);
1920 return ERR_PTR(rc);
1923 static struct cifsTconInfo *
1924 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1926 struct list_head *tmp;
1927 struct cifsTconInfo *tcon;
1929 spin_lock(&cifs_tcp_ses_lock);
1930 list_for_each(tmp, &ses->tcon_list) {
1931 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1932 if (tcon->tidStatus == CifsExiting)
1933 continue;
1934 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1935 continue;
1937 ++tcon->tc_count;
1938 spin_unlock(&cifs_tcp_ses_lock);
1939 return tcon;
1941 spin_unlock(&cifs_tcp_ses_lock);
1942 return NULL;
1945 static void
1946 cifs_put_tcon(struct cifsTconInfo *tcon)
1948 int xid;
1949 struct cifsSesInfo *ses = tcon->ses;
1951 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1952 spin_lock(&cifs_tcp_ses_lock);
1953 if (--tcon->tc_count > 0) {
1954 spin_unlock(&cifs_tcp_ses_lock);
1955 return;
1958 list_del_init(&tcon->tcon_list);
1959 spin_unlock(&cifs_tcp_ses_lock);
1961 xid = GetXid();
1962 CIFSSMBTDis(xid, tcon);
1963 _FreeXid(xid);
1965 cifs_fscache_release_super_cookie(tcon);
1966 tconInfoFree(tcon);
1967 cifs_put_smb_ses(ses);
1970 static struct cifsTconInfo *
1971 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1973 int rc, xid;
1974 struct cifsTconInfo *tcon;
1976 tcon = cifs_find_tcon(ses, volume_info->UNC);
1977 if (tcon) {
1978 cFYI(1, "Found match on UNC path");
1979 /* existing tcon already has a reference */
1980 cifs_put_smb_ses(ses);
1981 if (tcon->seal != volume_info->seal)
1982 cERROR(1, "transport encryption setting "
1983 "conflicts with existing tid");
1984 return tcon;
1987 tcon = tconInfoAlloc();
1988 if (tcon == NULL) {
1989 rc = -ENOMEM;
1990 goto out_fail;
1993 tcon->ses = ses;
1994 if (volume_info->password) {
1995 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1996 if (!tcon->password) {
1997 rc = -ENOMEM;
1998 goto out_fail;
2002 if (strchr(volume_info->UNC + 3, '\\') == NULL
2003 && strchr(volume_info->UNC + 3, '/') == NULL) {
2004 cERROR(1, "Missing share name");
2005 rc = -ENODEV;
2006 goto out_fail;
2009 /* BB Do we need to wrap session_mutex around
2010 * this TCon call and Unix SetFS as
2011 * we do on SessSetup and reconnect? */
2012 xid = GetXid();
2013 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
2014 FreeXid(xid);
2015 cFYI(1, "CIFS Tcon rc = %d", rc);
2016 if (rc)
2017 goto out_fail;
2019 if (volume_info->nodfs) {
2020 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2021 cFYI(1, "DFS disabled (%d)", tcon->Flags);
2023 tcon->seal = volume_info->seal;
2024 /* we can have only one retry value for a connection
2025 to a share so for resources mounted more than once
2026 to the same server share the last value passed in
2027 for the retry flag is used */
2028 tcon->retry = volume_info->retry;
2029 tcon->nocase = volume_info->nocase;
2030 tcon->local_lease = volume_info->local_lease;
2032 spin_lock(&cifs_tcp_ses_lock);
2033 list_add(&tcon->tcon_list, &ses->tcon_list);
2034 spin_unlock(&cifs_tcp_ses_lock);
2036 cifs_fscache_get_super_cookie(tcon);
2038 return tcon;
2040 out_fail:
2041 tconInfoFree(tcon);
2042 return ERR_PTR(rc);
2045 void
2046 cifs_put_tlink(struct tcon_link *tlink)
2048 if (!tlink || IS_ERR(tlink))
2049 return;
2051 if (!atomic_dec_and_test(&tlink->tl_count) ||
2052 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
2053 tlink->tl_time = jiffies;
2054 return;
2057 if (!IS_ERR(tlink_tcon(tlink)))
2058 cifs_put_tcon(tlink_tcon(tlink));
2059 kfree(tlink);
2060 return;
2064 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
2065 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
2066 struct dfs_info3_param **preferrals, int remap)
2068 char *temp_unc;
2069 int rc = 0;
2071 *pnum_referrals = 0;
2072 *preferrals = NULL;
2074 if (pSesInfo->ipc_tid == 0) {
2075 temp_unc = kmalloc(2 /* for slashes */ +
2076 strnlen(pSesInfo->serverName,
2077 SERVER_NAME_LEN_WITH_NULL * 2)
2078 + 1 + 4 /* slash IPC$ */ + 2,
2079 GFP_KERNEL);
2080 if (temp_unc == NULL)
2081 return -ENOMEM;
2082 temp_unc[0] = '\\';
2083 temp_unc[1] = '\\';
2084 strcpy(temp_unc + 2, pSesInfo->serverName);
2085 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
2086 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
2087 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
2088 kfree(temp_unc);
2090 if (rc == 0)
2091 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
2092 pnum_referrals, nls_codepage, remap);
2093 /* BB map targetUNCs to dfs_info3 structures, here or
2094 in CIFSGetDFSRefer BB */
2096 return rc;
2099 #ifdef CONFIG_DEBUG_LOCK_ALLOC
2100 static struct lock_class_key cifs_key[2];
2101 static struct lock_class_key cifs_slock_key[2];
2103 static inline void
2104 cifs_reclassify_socket4(struct socket *sock)
2106 struct sock *sk = sock->sk;
2107 BUG_ON(sock_owned_by_user(sk));
2108 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2109 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2112 static inline void
2113 cifs_reclassify_socket6(struct socket *sock)
2115 struct sock *sk = sock->sk;
2116 BUG_ON(sock_owned_by_user(sk));
2117 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2118 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2120 #else
2121 static inline void
2122 cifs_reclassify_socket4(struct socket *sock)
2126 static inline void
2127 cifs_reclassify_socket6(struct socket *sock)
2130 #endif
2132 /* See RFC1001 section 14 on representation of Netbios names */
2133 static void rfc1002mangle(char *target, char *source, unsigned int length)
2135 unsigned int i, j;
2137 for (i = 0, j = 0; i < (length); i++) {
2138 /* mask a nibble at a time and encode */
2139 target[j] = 'A' + (0x0F & (source[i] >> 4));
2140 target[j+1] = 'A' + (0x0F & source[i]);
2141 j += 2;
2146 static int
2147 bind_socket(struct TCP_Server_Info *server)
2149 int rc = 0;
2150 if (server->srcaddr.ss_family != AF_UNSPEC) {
2151 /* Bind to the specified local IP address */
2152 struct socket *socket = server->ssocket;
2153 rc = socket->ops->bind(socket,
2154 (struct sockaddr *) &server->srcaddr,
2155 sizeof(server->srcaddr));
2156 if (rc < 0) {
2157 struct sockaddr_in *saddr4;
2158 struct sockaddr_in6 *saddr6;
2159 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2160 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2161 if (saddr6->sin6_family == AF_INET6)
2162 cERROR(1, "cifs: "
2163 "Failed to bind to: %pI6c, error: %d\n",
2164 &saddr6->sin6_addr, rc);
2165 else
2166 cERROR(1, "cifs: "
2167 "Failed to bind to: %pI4, error: %d\n",
2168 &saddr4->sin_addr.s_addr, rc);
2171 return rc;
2174 static int
2175 ip_rfc1001_connect(struct TCP_Server_Info *server)
2177 int rc = 0;
2179 * some servers require RFC1001 sessinit before sending
2180 * negprot - BB check reconnection in case where second
2181 * sessinit is sent but no second negprot
2183 struct rfc1002_session_packet *ses_init_buf;
2184 struct smb_hdr *smb_buf;
2185 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2186 GFP_KERNEL);
2187 if (ses_init_buf) {
2188 ses_init_buf->trailer.session_req.called_len = 32;
2190 if (server->server_RFC1001_name &&
2191 server->server_RFC1001_name[0] != 0)
2192 rfc1002mangle(ses_init_buf->trailer.
2193 session_req.called_name,
2194 server->server_RFC1001_name,
2195 RFC1001_NAME_LEN_WITH_NULL);
2196 else
2197 rfc1002mangle(ses_init_buf->trailer.
2198 session_req.called_name,
2199 DEFAULT_CIFS_CALLED_NAME,
2200 RFC1001_NAME_LEN_WITH_NULL);
2202 ses_init_buf->trailer.session_req.calling_len = 32;
2205 * calling name ends in null (byte 16) from old smb
2206 * convention.
2208 if (server->workstation_RFC1001_name &&
2209 server->workstation_RFC1001_name[0] != 0)
2210 rfc1002mangle(ses_init_buf->trailer.
2211 session_req.calling_name,
2212 server->workstation_RFC1001_name,
2213 RFC1001_NAME_LEN_WITH_NULL);
2214 else
2215 rfc1002mangle(ses_init_buf->trailer.
2216 session_req.calling_name,
2217 "LINUX_CIFS_CLNT",
2218 RFC1001_NAME_LEN_WITH_NULL);
2220 ses_init_buf->trailer.session_req.scope1 = 0;
2221 ses_init_buf->trailer.session_req.scope2 = 0;
2222 smb_buf = (struct smb_hdr *)ses_init_buf;
2224 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2225 smb_buf->smb_buf_length = 0x81000044;
2226 rc = smb_send(server, smb_buf, 0x44);
2227 kfree(ses_init_buf);
2229 * RFC1001 layer in at least one server
2230 * requires very short break before negprot
2231 * presumably because not expecting negprot
2232 * to follow so fast. This is a simple
2233 * solution that works without
2234 * complicating the code and causes no
2235 * significant slowing down on mount
2236 * for everyone else
2238 usleep_range(1000, 2000);
2241 * else the negprot may still work without this
2242 * even though malloc failed
2245 return rc;
2248 static int
2249 generic_ip_connect(struct TCP_Server_Info *server)
2251 int rc = 0;
2252 unsigned short int sport;
2253 int slen, sfamily;
2254 struct socket *socket = server->ssocket;
2255 struct sockaddr *saddr;
2257 saddr = (struct sockaddr *) &server->dstaddr;
2259 if (server->dstaddr.ss_family == AF_INET6) {
2260 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2261 slen = sizeof(struct sockaddr_in6);
2262 sfamily = AF_INET6;
2263 } else {
2264 sport = ((struct sockaddr_in *) saddr)->sin_port;
2265 slen = sizeof(struct sockaddr_in);
2266 sfamily = AF_INET;
2269 if (socket == NULL) {
2270 rc = sock_create_kern(sfamily, SOCK_STREAM,
2271 IPPROTO_TCP, &socket);
2272 if (rc < 0) {
2273 cERROR(1, "Error %d creating socket", rc);
2274 server->ssocket = NULL;
2275 return rc;
2278 /* BB other socket options to set KEEPALIVE, NODELAY? */
2279 cFYI(1, "Socket created");
2280 server->ssocket = socket;
2281 socket->sk->sk_allocation = GFP_NOFS;
2282 if (sfamily == AF_INET6)
2283 cifs_reclassify_socket6(socket);
2284 else
2285 cifs_reclassify_socket4(socket);
2288 rc = bind_socket(server);
2289 if (rc < 0)
2290 return rc;
2292 rc = socket->ops->connect(socket, saddr, slen, 0);
2293 if (rc < 0) {
2294 cFYI(1, "Error %d connecting to server", rc);
2295 sock_release(socket);
2296 server->ssocket = NULL;
2297 return rc;
2301 * Eventually check for other socket options to change from
2302 * the default. sock_setsockopt not used because it expects
2303 * user space buffer
2305 socket->sk->sk_rcvtimeo = 7 * HZ;
2306 socket->sk->sk_sndtimeo = 5 * HZ;
2308 /* make the bufsizes depend on wsize/rsize and max requests */
2309 if (server->noautotune) {
2310 if (socket->sk->sk_sndbuf < (200 * 1024))
2311 socket->sk->sk_sndbuf = 200 * 1024;
2312 if (socket->sk->sk_rcvbuf < (140 * 1024))
2313 socket->sk->sk_rcvbuf = 140 * 1024;
2316 if (server->tcp_nodelay) {
2317 int val = 1;
2318 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2319 (char *)&val, sizeof(val));
2320 if (rc)
2321 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2324 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
2325 socket->sk->sk_sndbuf,
2326 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2328 if (sport == htons(RFC1001_PORT))
2329 rc = ip_rfc1001_connect(server);
2331 return rc;
2334 static int
2335 ip_connect(struct TCP_Server_Info *server)
2337 unsigned short int *sport;
2338 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2339 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2341 if (server->dstaddr.ss_family == AF_INET6)
2342 sport = &addr6->sin6_port;
2343 else
2344 sport = &addr->sin_port;
2346 if (*sport == 0) {
2347 int rc;
2349 /* try with 445 port at first */
2350 *sport = htons(CIFS_PORT);
2352 rc = generic_ip_connect(server);
2353 if (rc >= 0)
2354 return rc;
2356 /* if it failed, try with 139 port */
2357 *sport = htons(RFC1001_PORT);
2360 return generic_ip_connect(server);
2363 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2364 struct super_block *sb, struct smb_vol *vol_info)
2366 /* if we are reconnecting then should we check to see if
2367 * any requested capabilities changed locally e.g. via
2368 * remount but we can not do much about it here
2369 * if they have (even if we could detect it by the following)
2370 * Perhaps we could add a backpointer to array of sb from tcon
2371 * or if we change to make all sb to same share the same
2372 * sb as NFS - then we only have one backpointer to sb.
2373 * What if we wanted to mount the server share twice once with
2374 * and once without posixacls or posix paths? */
2375 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2377 if (vol_info && vol_info->no_linux_ext) {
2378 tcon->fsUnixInfo.Capability = 0;
2379 tcon->unix_ext = 0; /* Unix Extensions disabled */
2380 cFYI(1, "Linux protocol extensions disabled");
2381 return;
2382 } else if (vol_info)
2383 tcon->unix_ext = 1; /* Unix Extensions supported */
2385 if (tcon->unix_ext == 0) {
2386 cFYI(1, "Unix extensions disabled so not set on reconnect");
2387 return;
2390 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2391 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2393 /* check for reconnect case in which we do not
2394 want to change the mount behavior if we can avoid it */
2395 if (vol_info == NULL) {
2396 /* turn off POSIX ACL and PATHNAMES if not set
2397 originally at mount time */
2398 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2399 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2400 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2401 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2402 cERROR(1, "POSIXPATH support change");
2403 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2404 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2405 cERROR(1, "possible reconnect error");
2406 cERROR(1, "server disabled POSIX path support");
2410 cap &= CIFS_UNIX_CAP_MASK;
2411 if (vol_info && vol_info->no_psx_acl)
2412 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2413 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2414 cFYI(1, "negotiated posix acl support");
2415 if (sb)
2416 sb->s_flags |= MS_POSIXACL;
2419 if (vol_info && vol_info->posix_paths == 0)
2420 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2421 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2422 cFYI(1, "negotiate posix pathnames");
2423 if (sb)
2424 CIFS_SB(sb)->mnt_cifs_flags |=
2425 CIFS_MOUNT_POSIX_PATHS;
2428 /* We might be setting the path sep back to a different
2429 form if we are reconnecting and the server switched its
2430 posix path capability for this share */
2431 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2432 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2434 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2435 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2436 CIFS_SB(sb)->rsize = 127 * 1024;
2437 cFYI(DBG2, "larger reads not supported by srv");
2442 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2443 #ifdef CONFIG_CIFS_DEBUG2
2444 if (cap & CIFS_UNIX_FCNTL_CAP)
2445 cFYI(1, "FCNTL cap");
2446 if (cap & CIFS_UNIX_EXTATTR_CAP)
2447 cFYI(1, "EXTATTR cap");
2448 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2449 cFYI(1, "POSIX path cap");
2450 if (cap & CIFS_UNIX_XATTR_CAP)
2451 cFYI(1, "XATTR cap");
2452 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2453 cFYI(1, "POSIX ACL cap");
2454 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2455 cFYI(1, "very large read cap");
2456 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2457 cFYI(1, "very large write cap");
2458 #endif /* CIFS_DEBUG2 */
2459 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2460 if (vol_info == NULL) {
2461 cFYI(1, "resetting capabilities failed");
2462 } else
2463 cERROR(1, "Negotiating Unix capabilities "
2464 "with the server failed. Consider "
2465 "mounting with the Unix Extensions\n"
2466 "disabled, if problems are found, "
2467 "by specifying the nounix mount "
2468 "option.");
2474 static void
2475 convert_delimiter(char *path, char delim)
2477 int i;
2478 char old_delim;
2480 if (path == NULL)
2481 return;
2483 if (delim == '/')
2484 old_delim = '\\';
2485 else
2486 old_delim = '/';
2488 for (i = 0; path[i] != '\0'; i++) {
2489 if (path[i] == old_delim)
2490 path[i] = delim;
2494 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2495 struct cifs_sb_info *cifs_sb)
2497 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2499 if (pvolume_info->rsize > CIFSMaxBufSize) {
2500 cERROR(1, "rsize %d too large, using MaxBufSize",
2501 pvolume_info->rsize);
2502 cifs_sb->rsize = CIFSMaxBufSize;
2503 } else if ((pvolume_info->rsize) &&
2504 (pvolume_info->rsize <= CIFSMaxBufSize))
2505 cifs_sb->rsize = pvolume_info->rsize;
2506 else /* default */
2507 cifs_sb->rsize = CIFSMaxBufSize;
2509 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2510 cERROR(1, "wsize %d too large, using 4096 instead",
2511 pvolume_info->wsize);
2512 cifs_sb->wsize = 4096;
2513 } else if (pvolume_info->wsize)
2514 cifs_sb->wsize = pvolume_info->wsize;
2515 else
2516 cifs_sb->wsize = min_t(const int,
2517 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2518 127*1024);
2519 /* old default of CIFSMaxBufSize was too small now
2520 that SMB Write2 can send multiple pages in kvec.
2521 RFC1001 does not describe what happens when frame
2522 bigger than 128K is sent so use that as max in
2523 conjunction with 52K kvec constraint on arch with 4K
2524 page size */
2526 if (cifs_sb->rsize < 2048) {
2527 cifs_sb->rsize = 2048;
2528 /* Windows ME may prefer this */
2529 cFYI(1, "readsize set to minimum: 2048");
2531 /* calculate prepath */
2532 cifs_sb->prepath = pvolume_info->prepath;
2533 if (cifs_sb->prepath) {
2534 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2535 /* we can not convert the / to \ in the path
2536 separators in the prefixpath yet because we do not
2537 know (until reset_cifs_unix_caps is called later)
2538 whether POSIX PATH CAP is available. We normalize
2539 the / to \ after reset_cifs_unix_caps is called */
2540 pvolume_info->prepath = NULL;
2541 } else
2542 cifs_sb->prepathlen = 0;
2543 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2544 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2545 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2546 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2547 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2548 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2550 cifs_sb->actimeo = pvolume_info->actimeo;
2552 if (pvolume_info->noperm)
2553 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2554 if (pvolume_info->setuids)
2555 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2556 if (pvolume_info->server_ino)
2557 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2558 if (pvolume_info->remap)
2559 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2560 if (pvolume_info->no_xattr)
2561 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2562 if (pvolume_info->sfu_emul)
2563 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2564 if (pvolume_info->nobrl)
2565 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2566 if (pvolume_info->nostrictsync)
2567 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2568 if (pvolume_info->mand_lock)
2569 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2570 if (pvolume_info->cifs_acl)
2571 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2572 if (pvolume_info->override_uid)
2573 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2574 if (pvolume_info->override_gid)
2575 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2576 if (pvolume_info->dynperm)
2577 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2578 if (pvolume_info->fsc)
2579 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2580 if (pvolume_info->multiuser)
2581 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2582 CIFS_MOUNT_NO_PERM);
2583 if (pvolume_info->direct_io) {
2584 cFYI(1, "mounting share using direct i/o");
2585 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2587 if (pvolume_info->mfsymlinks) {
2588 if (pvolume_info->sfu_emul) {
2589 cERROR(1, "mount option mfsymlinks ignored if sfu "
2590 "mount option is used");
2591 } else {
2592 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2596 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2597 cERROR(1, "mount option dynperm ignored if cifsacl "
2598 "mount option supported");
2601 static int
2602 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2603 struct cifs_sb_info *cifs_sb, const char *full_path)
2605 int rc;
2606 FILE_ALL_INFO *pfile_info;
2608 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2609 if (pfile_info == NULL)
2610 return -ENOMEM;
2612 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2613 0 /* not legacy */, cifs_sb->local_nls,
2614 cifs_sb->mnt_cifs_flags &
2615 CIFS_MOUNT_MAP_SPECIAL_CHR);
2616 kfree(pfile_info);
2617 return rc;
2620 static void
2621 cleanup_volume_info(struct smb_vol **pvolume_info)
2623 struct smb_vol *volume_info;
2625 if (!pvolume_info || !*pvolume_info)
2626 return;
2628 volume_info = *pvolume_info;
2629 kzfree(volume_info->password);
2630 kfree(volume_info->UNC);
2631 kfree(volume_info->prepath);
2632 kfree(volume_info);
2633 *pvolume_info = NULL;
2634 return;
2637 #ifdef CONFIG_CIFS_DFS_UPCALL
2638 /* build_path_to_root returns full path to root when
2639 * we do not have an exiting connection (tcon) */
2640 static char *
2641 build_unc_path_to_root(const struct smb_vol *volume_info,
2642 const struct cifs_sb_info *cifs_sb)
2644 char *full_path;
2646 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2647 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2648 if (full_path == NULL)
2649 return ERR_PTR(-ENOMEM);
2651 strncpy(full_path, volume_info->UNC, unc_len);
2652 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2653 int i;
2654 for (i = 0; i < unc_len; i++) {
2655 if (full_path[i] == '\\')
2656 full_path[i] = '/';
2660 if (cifs_sb->prepathlen)
2661 strncpy(full_path + unc_len, cifs_sb->prepath,
2662 cifs_sb->prepathlen);
2664 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2665 return full_path;
2667 #endif
2670 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2671 char *mount_data_global, const char *devname)
2673 int rc;
2674 int xid;
2675 struct smb_vol *volume_info;
2676 struct cifsSesInfo *pSesInfo;
2677 struct cifsTconInfo *tcon;
2678 struct TCP_Server_Info *srvTcp;
2679 char *full_path;
2680 char *mount_data = mount_data_global;
2681 struct tcon_link *tlink;
2682 #ifdef CONFIG_CIFS_DFS_UPCALL
2683 struct dfs_info3_param *referrals = NULL;
2684 unsigned int num_referrals = 0;
2685 int referral_walks_count = 0;
2686 try_mount_again:
2687 #endif
2688 rc = 0;
2689 tcon = NULL;
2690 pSesInfo = NULL;
2691 srvTcp = NULL;
2692 full_path = NULL;
2693 tlink = NULL;
2695 xid = GetXid();
2697 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2698 if (!volume_info) {
2699 rc = -ENOMEM;
2700 goto out;
2703 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2704 rc = -EINVAL;
2705 goto out;
2708 if (volume_info->nullauth) {
2709 cFYI(1, "null user");
2710 volume_info->username = "";
2711 } else if (volume_info->username) {
2712 /* BB fixme parse for domain name here */
2713 cFYI(1, "Username: %s", volume_info->username);
2714 } else {
2715 cifserror("No username specified");
2716 /* In userspace mount helper we can get user name from alternate
2717 locations such as env variables and files on disk */
2718 rc = -EINVAL;
2719 goto out;
2722 /* this is needed for ASCII cp to Unicode converts */
2723 if (volume_info->iocharset == NULL) {
2724 /* load_nls_default cannot return null */
2725 volume_info->local_nls = load_nls_default();
2726 } else {
2727 volume_info->local_nls = load_nls(volume_info->iocharset);
2728 if (volume_info->local_nls == NULL) {
2729 cERROR(1, "CIFS mount error: iocharset %s not found",
2730 volume_info->iocharset);
2731 rc = -ELIBACC;
2732 goto out;
2735 cifs_sb->local_nls = volume_info->local_nls;
2737 /* get a reference to a tcp session */
2738 srvTcp = cifs_get_tcp_session(volume_info);
2739 if (IS_ERR(srvTcp)) {
2740 rc = PTR_ERR(srvTcp);
2741 goto out;
2744 /* get a reference to a SMB session */
2745 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2746 if (IS_ERR(pSesInfo)) {
2747 rc = PTR_ERR(pSesInfo);
2748 pSesInfo = NULL;
2749 goto mount_fail_check;
2752 setup_cifs_sb(volume_info, cifs_sb);
2753 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2754 sb->s_maxbytes = MAX_LFS_FILESIZE;
2755 else
2756 sb->s_maxbytes = MAX_NON_LFS;
2758 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2759 sb->s_time_gran = 100;
2761 /* search for existing tcon to this server share */
2762 tcon = cifs_get_tcon(pSesInfo, volume_info);
2763 if (IS_ERR(tcon)) {
2764 rc = PTR_ERR(tcon);
2765 tcon = NULL;
2766 goto remote_path_check;
2769 /* do not care if following two calls succeed - informational */
2770 if (!tcon->ipc) {
2771 CIFSSMBQFSDeviceInfo(xid, tcon);
2772 CIFSSMBQFSAttributeInfo(xid, tcon);
2775 /* tell server which Unix caps we support */
2776 if (tcon->ses->capabilities & CAP_UNIX)
2777 /* reset of caps checks mount to see if unix extensions
2778 disabled for just this mount */
2779 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2780 else
2781 tcon->unix_ext = 0; /* server does not support them */
2783 /* convert forward to back slashes in prepath here if needed */
2784 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2785 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2787 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2788 cifs_sb->rsize = 1024 * 127;
2789 cFYI(DBG2, "no very large read support, rsize now 127K");
2791 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2792 cifs_sb->wsize = min(cifs_sb->wsize,
2793 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2794 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2795 cifs_sb->rsize = min(cifs_sb->rsize,
2796 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2798 remote_path_check:
2799 /* check if a whole path (including prepath) is not remote */
2800 if (!rc && cifs_sb->prepathlen && tcon) {
2801 /* build_path_to_root works only when we have a valid tcon */
2802 full_path = cifs_build_path_to_root(cifs_sb, tcon);
2803 if (full_path == NULL) {
2804 rc = -ENOMEM;
2805 goto mount_fail_check;
2807 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2808 if (rc != 0 && rc != -EREMOTE) {
2809 kfree(full_path);
2810 goto mount_fail_check;
2812 kfree(full_path);
2815 /* get referral if needed */
2816 if (rc == -EREMOTE) {
2817 #ifdef CONFIG_CIFS_DFS_UPCALL
2818 if (referral_walks_count > MAX_NESTED_LINKS) {
2820 * BB: when we implement proper loop detection,
2821 * we will remove this check. But now we need it
2822 * to prevent an indefinite loop if 'DFS tree' is
2823 * misconfigured (i.e. has loops).
2825 rc = -ELOOP;
2826 goto mount_fail_check;
2828 /* convert forward to back slashes in prepath here if needed */
2829 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2830 convert_delimiter(cifs_sb->prepath,
2831 CIFS_DIR_SEP(cifs_sb));
2832 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2833 if (IS_ERR(full_path)) {
2834 rc = PTR_ERR(full_path);
2835 goto mount_fail_check;
2838 cFYI(1, "Getting referral for: %s", full_path);
2839 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2840 cifs_sb->local_nls, &num_referrals, &referrals,
2841 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2842 if (!rc && num_referrals > 0) {
2843 char *fake_devname = NULL;
2845 if (mount_data != mount_data_global)
2846 kfree(mount_data);
2848 mount_data = cifs_compose_mount_options(
2849 cifs_sb->mountdata, full_path + 1,
2850 referrals, &fake_devname);
2852 free_dfs_info_array(referrals, num_referrals);
2853 kfree(fake_devname);
2854 kfree(full_path);
2856 if (IS_ERR(mount_data)) {
2857 rc = PTR_ERR(mount_data);
2858 mount_data = NULL;
2859 goto mount_fail_check;
2862 if (tcon)
2863 cifs_put_tcon(tcon);
2864 else if (pSesInfo)
2865 cifs_put_smb_ses(pSesInfo);
2867 cleanup_volume_info(&volume_info);
2868 referral_walks_count++;
2869 FreeXid(xid);
2870 goto try_mount_again;
2872 #else /* No DFS support, return error on mount */
2873 rc = -EOPNOTSUPP;
2874 #endif
2877 if (rc)
2878 goto mount_fail_check;
2880 /* now, hang the tcon off of the superblock */
2881 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2882 if (tlink == NULL) {
2883 rc = -ENOMEM;
2884 goto mount_fail_check;
2887 tlink->tl_uid = pSesInfo->linux_uid;
2888 tlink->tl_tcon = tcon;
2889 tlink->tl_time = jiffies;
2890 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2891 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2893 cifs_sb->master_tlink = tlink;
2894 spin_lock(&cifs_sb->tlink_tree_lock);
2895 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
2896 spin_unlock(&cifs_sb->tlink_tree_lock);
2898 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2899 TLINK_IDLE_EXPIRE);
2901 mount_fail_check:
2902 /* on error free sesinfo and tcon struct if needed */
2903 if (rc) {
2904 if (mount_data != mount_data_global)
2905 kfree(mount_data);
2906 /* If find_unc succeeded then rc == 0 so we can not end */
2907 /* up accidently freeing someone elses tcon struct */
2908 if (tcon)
2909 cifs_put_tcon(tcon);
2910 else if (pSesInfo)
2911 cifs_put_smb_ses(pSesInfo);
2912 else
2913 cifs_put_tcp_session(srvTcp);
2914 goto out;
2917 /* volume_info->password is freed above when existing session found
2918 (in which case it is not needed anymore) but when new sesion is created
2919 the password ptr is put in the new session structure (in which case the
2920 password will be freed at unmount time) */
2921 out:
2922 /* zero out password before freeing */
2923 cleanup_volume_info(&volume_info);
2924 FreeXid(xid);
2925 return rc;
2929 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2930 const char *tree, struct cifsTconInfo *tcon,
2931 const struct nls_table *nls_codepage)
2933 struct smb_hdr *smb_buffer;
2934 struct smb_hdr *smb_buffer_response;
2935 TCONX_REQ *pSMB;
2936 TCONX_RSP *pSMBr;
2937 unsigned char *bcc_ptr;
2938 int rc = 0;
2939 int length, bytes_left;
2940 __u16 count;
2942 if (ses == NULL)
2943 return -EIO;
2945 smb_buffer = cifs_buf_get();
2946 if (smb_buffer == NULL)
2947 return -ENOMEM;
2949 smb_buffer_response = smb_buffer;
2951 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2952 NULL /*no tid */ , 4 /*wct */ );
2954 smb_buffer->Mid = GetNextMid(ses->server);
2955 smb_buffer->Uid = ses->Suid;
2956 pSMB = (TCONX_REQ *) smb_buffer;
2957 pSMBr = (TCONX_RSP *) smb_buffer_response;
2959 pSMB->AndXCommand = 0xFF;
2960 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
2961 bcc_ptr = &pSMB->Password[0];
2962 if ((ses->server->secMode) & SECMODE_USER) {
2963 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
2964 *bcc_ptr = 0; /* password is null byte */
2965 bcc_ptr++; /* skip password */
2966 /* already aligned so no need to do it below */
2967 } else {
2968 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
2969 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2970 specified as required (when that support is added to
2971 the vfs in the future) as only NTLM or the much
2972 weaker LANMAN (which we do not send by default) is accepted
2973 by Samba (not sure whether other servers allow
2974 NTLMv2 password here) */
2975 #ifdef CONFIG_CIFS_WEAK_PW_HASH
2976 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2977 (ses->server->secType == LANMAN))
2978 calc_lanman_hash(tcon->password, ses->server->cryptkey,
2979 ses->server->secMode &
2980 SECMODE_PW_ENCRYPT ? true : false,
2981 bcc_ptr);
2982 else
2983 #endif /* CIFS_WEAK_PW_HASH */
2984 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
2986 bcc_ptr += CIFS_SESS_KEY_SIZE;
2987 if (ses->capabilities & CAP_UNICODE) {
2988 /* must align unicode strings */
2989 *bcc_ptr = 0; /* null byte password */
2990 bcc_ptr++;
2994 if (ses->server->secMode &
2995 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2996 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2998 if (ses->capabilities & CAP_STATUS32) {
2999 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3001 if (ses->capabilities & CAP_DFS) {
3002 smb_buffer->Flags2 |= SMBFLG2_DFS;
3004 if (ses->capabilities & CAP_UNICODE) {
3005 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3006 length =
3007 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3008 6 /* max utf8 char length in bytes */ *
3009 (/* server len*/ + 256 /* share len */), nls_codepage);
3010 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3011 bcc_ptr += 2; /* skip trailing null */
3012 } else { /* ASCII */
3013 strcpy(bcc_ptr, tree);
3014 bcc_ptr += strlen(tree) + 1;
3016 strcpy(bcc_ptr, "?????");
3017 bcc_ptr += strlen("?????");
3018 bcc_ptr += 1;
3019 count = bcc_ptr - &pSMB->Password[0];
3020 pSMB->hdr.smb_buf_length += count;
3021 pSMB->ByteCount = cpu_to_le16(count);
3023 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3024 CIFS_STD_OP);
3026 /* above now done in SendReceive */
3027 if ((rc == 0) && (tcon != NULL)) {
3028 bool is_unicode;
3030 tcon->tidStatus = CifsGood;
3031 tcon->need_reconnect = false;
3032 tcon->tid = smb_buffer_response->Tid;
3033 bcc_ptr = pByteArea(smb_buffer_response);
3034 bytes_left = BCC(smb_buffer_response);
3035 length = strnlen(bcc_ptr, bytes_left - 2);
3036 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3037 is_unicode = true;
3038 else
3039 is_unicode = false;
3042 /* skip service field (NB: this field is always ASCII) */
3043 if (length == 3) {
3044 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3045 (bcc_ptr[2] == 'C')) {
3046 cFYI(1, "IPC connection");
3047 tcon->ipc = 1;
3049 } else if (length == 2) {
3050 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3051 /* the most common case */
3052 cFYI(1, "disk share connection");
3055 bcc_ptr += length + 1;
3056 bytes_left -= (length + 1);
3057 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3059 /* mostly informational -- no need to fail on error here */
3060 kfree(tcon->nativeFileSystem);
3061 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3062 bytes_left, is_unicode,
3063 nls_codepage);
3065 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
3067 if ((smb_buffer_response->WordCount == 3) ||
3068 (smb_buffer_response->WordCount == 7))
3069 /* field is in same location */
3070 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3071 else
3072 tcon->Flags = 0;
3073 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
3074 } else if ((rc == 0) && tcon == NULL) {
3075 /* all we need to save for IPC$ connection */
3076 ses->ipc_tid = smb_buffer_response->Tid;
3079 cifs_buf_release(smb_buffer);
3080 return rc;
3084 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3086 struct rb_root *root = &cifs_sb->tlink_tree;
3087 struct rb_node *node;
3088 struct tcon_link *tlink;
3089 char *tmp;
3091 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3093 spin_lock(&cifs_sb->tlink_tree_lock);
3094 while ((node = rb_first(root))) {
3095 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3096 cifs_get_tlink(tlink);
3097 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3098 rb_erase(node, root);
3100 spin_unlock(&cifs_sb->tlink_tree_lock);
3101 cifs_put_tlink(tlink);
3102 spin_lock(&cifs_sb->tlink_tree_lock);
3104 spin_unlock(&cifs_sb->tlink_tree_lock);
3106 tmp = cifs_sb->prepath;
3107 cifs_sb->prepathlen = 0;
3108 cifs_sb->prepath = NULL;
3109 kfree(tmp);
3111 return 0;
3114 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3116 int rc = 0;
3117 struct TCP_Server_Info *server = ses->server;
3119 /* only send once per connect */
3120 if (server->maxBuf != 0)
3121 return 0;
3123 rc = CIFSSMBNegotiate(xid, ses);
3124 if (rc == -EAGAIN) {
3125 /* retry only once on 1st time connection */
3126 rc = CIFSSMBNegotiate(xid, ses);
3127 if (rc == -EAGAIN)
3128 rc = -EHOSTDOWN;
3130 if (rc == 0) {
3131 spin_lock(&GlobalMid_Lock);
3132 if (server->tcpStatus != CifsExiting)
3133 server->tcpStatus = CifsGood;
3134 else
3135 rc = -EHOSTDOWN;
3136 spin_unlock(&GlobalMid_Lock);
3140 return rc;
3144 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3145 struct nls_table *nls_info)
3147 int rc = 0;
3148 struct TCP_Server_Info *server = ses->server;
3150 ses->flags = 0;
3151 ses->capabilities = server->capabilities;
3152 if (linuxExtEnabled == 0)
3153 ses->capabilities &= (~CAP_UNIX);
3155 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3156 server->secMode, server->capabilities, server->timeAdj);
3158 rc = CIFS_SessSetup(xid, ses, nls_info);
3159 if (rc) {
3160 cERROR(1, "Send error in SessSetup = %d", rc);
3161 } else {
3162 mutex_lock(&ses->server->srv_mutex);
3163 if (!server->session_estab) {
3164 server->session_key.response = ses->auth_key.response;
3165 server->session_key.len = ses->auth_key.len;
3166 server->sequence_number = 0x2;
3167 server->session_estab = true;
3168 ses->auth_key.response = NULL;
3170 mutex_unlock(&server->srv_mutex);
3172 cFYI(1, "CIFS Session Established successfully");
3173 spin_lock(&GlobalMid_Lock);
3174 ses->status = CifsGood;
3175 ses->need_reconnect = false;
3176 spin_unlock(&GlobalMid_Lock);
3179 kfree(ses->auth_key.response);
3180 ses->auth_key.response = NULL;
3181 ses->auth_key.len = 0;
3182 kfree(ses->ntlmssp);
3183 ses->ntlmssp = NULL;
3185 return rc;
3188 static struct cifsTconInfo *
3189 cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3191 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3192 struct cifsSesInfo *ses;
3193 struct cifsTconInfo *tcon = NULL;
3194 struct smb_vol *vol_info;
3195 char username[MAX_USERNAME_SIZE + 1];
3197 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3198 if (vol_info == NULL) {
3199 tcon = ERR_PTR(-ENOMEM);
3200 goto out;
3203 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3204 vol_info->username = username;
3205 vol_info->local_nls = cifs_sb->local_nls;
3206 vol_info->linux_uid = fsuid;
3207 vol_info->cred_uid = fsuid;
3208 vol_info->UNC = master_tcon->treeName;
3209 vol_info->retry = master_tcon->retry;
3210 vol_info->nocase = master_tcon->nocase;
3211 vol_info->local_lease = master_tcon->local_lease;
3212 vol_info->no_linux_ext = !master_tcon->unix_ext;
3214 /* FIXME: allow for other secFlg settings */
3215 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3217 /* get a reference for the same TCP session */
3218 spin_lock(&cifs_tcp_ses_lock);
3219 ++master_tcon->ses->server->srv_count;
3220 spin_unlock(&cifs_tcp_ses_lock);
3222 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3223 if (IS_ERR(ses)) {
3224 tcon = (struct cifsTconInfo *)ses;
3225 cifs_put_tcp_session(master_tcon->ses->server);
3226 goto out;
3229 tcon = cifs_get_tcon(ses, vol_info);
3230 if (IS_ERR(tcon)) {
3231 cifs_put_smb_ses(ses);
3232 goto out;
3235 if (ses->capabilities & CAP_UNIX)
3236 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3237 out:
3238 kfree(vol_info);
3240 return tcon;
3243 static inline struct tcon_link *
3244 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3246 return cifs_sb->master_tlink;
3249 struct cifsTconInfo *
3250 cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3252 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3255 static int
3256 cifs_sb_tcon_pending_wait(void *unused)
3258 schedule();
3259 return signal_pending(current) ? -ERESTARTSYS : 0;
3262 /* find and return a tlink with given uid */
3263 static struct tcon_link *
3264 tlink_rb_search(struct rb_root *root, uid_t uid)
3266 struct rb_node *node = root->rb_node;
3267 struct tcon_link *tlink;
3269 while (node) {
3270 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3272 if (tlink->tl_uid > uid)
3273 node = node->rb_left;
3274 else if (tlink->tl_uid < uid)
3275 node = node->rb_right;
3276 else
3277 return tlink;
3279 return NULL;
3282 /* insert a tcon_link into the tree */
3283 static void
3284 tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
3286 struct rb_node **new = &(root->rb_node), *parent = NULL;
3287 struct tcon_link *tlink;
3289 while (*new) {
3290 tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
3291 parent = *new;
3293 if (tlink->tl_uid > new_tlink->tl_uid)
3294 new = &((*new)->rb_left);
3295 else
3296 new = &((*new)->rb_right);
3299 rb_link_node(&new_tlink->tl_rbnode, parent, new);
3300 rb_insert_color(&new_tlink->tl_rbnode, root);
3304 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3305 * current task.
3307 * If the superblock doesn't refer to a multiuser mount, then just return
3308 * the master tcon for the mount.
3310 * First, search the rbtree for an existing tcon for this fsuid. If one
3311 * exists, then check to see if it's pending construction. If it is then wait
3312 * for construction to complete. Once it's no longer pending, check to see if
3313 * it failed and either return an error or retry construction, depending on
3314 * the timeout.
3316 * If one doesn't exist then insert a new tcon_link struct into the tree and
3317 * try to construct a new one.
3319 struct tcon_link *
3320 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3322 int ret;
3323 uid_t fsuid = current_fsuid();
3324 struct tcon_link *tlink, *newtlink;
3326 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3327 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3329 spin_lock(&cifs_sb->tlink_tree_lock);
3330 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3331 if (tlink)
3332 cifs_get_tlink(tlink);
3333 spin_unlock(&cifs_sb->tlink_tree_lock);
3335 if (tlink == NULL) {
3336 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3337 if (newtlink == NULL)
3338 return ERR_PTR(-ENOMEM);
3339 newtlink->tl_uid = fsuid;
3340 newtlink->tl_tcon = ERR_PTR(-EACCES);
3341 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3342 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3343 cifs_get_tlink(newtlink);
3345 spin_lock(&cifs_sb->tlink_tree_lock);
3346 /* was one inserted after previous search? */
3347 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3348 if (tlink) {
3349 cifs_get_tlink(tlink);
3350 spin_unlock(&cifs_sb->tlink_tree_lock);
3351 kfree(newtlink);
3352 goto wait_for_construction;
3354 tlink = newtlink;
3355 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3356 spin_unlock(&cifs_sb->tlink_tree_lock);
3357 } else {
3358 wait_for_construction:
3359 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3360 cifs_sb_tcon_pending_wait,
3361 TASK_INTERRUPTIBLE);
3362 if (ret) {
3363 cifs_put_tlink(tlink);
3364 return ERR_PTR(ret);
3367 /* if it's good, return it */
3368 if (!IS_ERR(tlink->tl_tcon))
3369 return tlink;
3371 /* return error if we tried this already recently */
3372 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3373 cifs_put_tlink(tlink);
3374 return ERR_PTR(-EACCES);
3377 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3378 goto wait_for_construction;
3381 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3382 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3383 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3385 if (IS_ERR(tlink->tl_tcon)) {
3386 cifs_put_tlink(tlink);
3387 return ERR_PTR(-EACCES);
3390 return tlink;
3394 * periodic workqueue job that scans tcon_tree for a superblock and closes
3395 * out tcons.
3397 static void
3398 cifs_prune_tlinks(struct work_struct *work)
3400 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3401 prune_tlinks.work);
3402 struct rb_root *root = &cifs_sb->tlink_tree;
3403 struct rb_node *node = rb_first(root);
3404 struct rb_node *tmp;
3405 struct tcon_link *tlink;
3408 * Because we drop the spinlock in the loop in order to put the tlink
3409 * it's not guarded against removal of links from the tree. The only
3410 * places that remove entries from the tree are this function and
3411 * umounts. Because this function is non-reentrant and is canceled
3412 * before umount can proceed, this is safe.
3414 spin_lock(&cifs_sb->tlink_tree_lock);
3415 node = rb_first(root);
3416 while (node != NULL) {
3417 tmp = node;
3418 node = rb_next(tmp);
3419 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
3421 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
3422 atomic_read(&tlink->tl_count) != 0 ||
3423 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
3424 continue;
3426 cifs_get_tlink(tlink);
3427 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3428 rb_erase(tmp, root);
3430 spin_unlock(&cifs_sb->tlink_tree_lock);
3431 cifs_put_tlink(tlink);
3432 spin_lock(&cifs_sb->tlink_tree_lock);
3434 spin_unlock(&cifs_sb->tlink_tree_lock);
3436 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3437 TLINK_IDLE_EXPIRE);