cifs: set up recurring workqueue job to do SMB echo requests
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / cifs / connect.c
blobf38ca084c9d2d2410be8a8e4ea423cb412e03ea1
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 /* SMB echo "timeout" -- FIXME: tunable? */
56 #define SMB_ECHO_INTERVAL (60 * HZ)
58 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
59 unsigned char *p24);
61 extern mempool_t *cifs_req_poolp;
63 struct smb_vol {
64 char *username;
65 char *password;
66 char *domainname;
67 char *UNC;
68 char *UNCip;
69 char *iocharset; /* local code page for mapping to and from Unicode */
70 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
71 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
72 uid_t cred_uid;
73 uid_t linux_uid;
74 gid_t linux_gid;
75 mode_t file_mode;
76 mode_t dir_mode;
77 unsigned secFlg;
78 bool retry:1;
79 bool intr:1;
80 bool setuids:1;
81 bool override_uid:1;
82 bool override_gid:1;
83 bool dynperm:1;
84 bool noperm:1;
85 bool no_psx_acl:1; /* set if posix acl support should be disabled */
86 bool cifs_acl:1;
87 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
88 bool server_ino:1; /* use inode numbers from server ie UniqueId */
89 bool direct_io:1;
90 bool remap:1; /* set to remap seven reserved chars in filenames */
91 bool posix_paths:1; /* unset to not ask for posix pathnames. */
92 bool no_linux_ext:1;
93 bool sfu_emul:1;
94 bool nullauth:1; /* attempt to authenticate with null user */
95 bool nocase:1; /* request case insensitive filenames */
96 bool nobrl:1; /* disable sending byte range locks to srv */
97 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
98 bool seal:1; /* request transport encryption on share */
99 bool nodfs:1; /* Do not request DFS, even if available */
100 bool local_lease:1; /* check leases only on local system, not remote */
101 bool noblocksnd:1;
102 bool noautotune:1;
103 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
104 bool fsc:1; /* enable fscache */
105 bool mfsymlinks:1; /* use Minshall+French Symlinks */
106 bool multiuser:1;
107 unsigned int rsize;
108 unsigned int wsize;
109 bool sockopt_tcp_nodelay:1;
110 unsigned short int port;
111 unsigned long actimeo; /* attribute cache timeout (jiffies) */
112 char *prepath;
113 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
114 struct nls_table *local_nls;
117 /* FIXME: should these be tunable? */
118 #define TLINK_ERROR_EXPIRE (1 * HZ)
119 #define TLINK_IDLE_EXPIRE (600 * HZ)
121 static int ip_connect(struct TCP_Server_Info *server);
122 static int generic_ip_connect(struct TCP_Server_Info *server);
123 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
124 static void cifs_prune_tlinks(struct work_struct *work);
127 * cifs tcp session reconnection
129 * mark tcp session as reconnecting so temporarily locked
130 * mark all smb sessions as reconnecting for tcp session
131 * reconnect tcp session
132 * wake up waiters on reconnection? - (not needed currently)
134 static int
135 cifs_reconnect(struct TCP_Server_Info *server)
137 int rc = 0;
138 struct list_head *tmp, *tmp2;
139 struct cifsSesInfo *ses;
140 struct cifsTconInfo *tcon;
141 struct mid_q_entry *mid_entry;
143 spin_lock(&GlobalMid_Lock);
144 if (server->tcpStatus == CifsExiting) {
145 /* the demux thread will exit normally
146 next time through the loop */
147 spin_unlock(&GlobalMid_Lock);
148 return rc;
149 } else
150 server->tcpStatus = CifsNeedReconnect;
151 spin_unlock(&GlobalMid_Lock);
152 server->maxBuf = 0;
154 cFYI(1, "Reconnecting tcp session");
156 /* before reconnecting the tcp session, mark the smb session (uid)
157 and the tid bad so they are not used until reconnected */
158 cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
159 spin_lock(&cifs_tcp_ses_lock);
160 list_for_each(tmp, &server->smb_ses_list) {
161 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
162 ses->need_reconnect = true;
163 ses->ipc_tid = 0;
164 list_for_each(tmp2, &ses->tcon_list) {
165 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
166 tcon->need_reconnect = true;
169 spin_unlock(&cifs_tcp_ses_lock);
171 /* do not want to be sending data on a socket we are freeing */
172 cFYI(1, "%s: tearing down socket", __func__);
173 mutex_lock(&server->srv_mutex);
174 if (server->ssocket) {
175 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
176 server->ssocket->flags);
177 kernel_sock_shutdown(server->ssocket, SHUT_WR);
178 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
179 server->ssocket->state,
180 server->ssocket->flags);
181 sock_release(server->ssocket);
182 server->ssocket = NULL;
184 server->sequence_number = 0;
185 server->session_estab = false;
186 kfree(server->session_key.response);
187 server->session_key.response = NULL;
188 server->session_key.len = 0;
189 mutex_unlock(&server->srv_mutex);
191 /* mark submitted MIDs for retry and issue callback */
192 cFYI(1, "%s: issuing mid callbacks", __func__);
193 spin_lock(&GlobalMid_Lock);
194 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
195 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
196 if (mid_entry->midState == MID_REQUEST_SUBMITTED)
197 mid_entry->midState = MID_RETRY_NEEDED;
198 list_del_init(&mid_entry->qhead);
199 mid_entry->callback(mid_entry);
201 spin_unlock(&GlobalMid_Lock);
203 while ((server->tcpStatus != CifsExiting) &&
204 (server->tcpStatus != CifsGood)) {
205 try_to_freeze();
207 /* we should try only the port we connected to before */
208 rc = generic_ip_connect(server);
209 if (rc) {
210 cFYI(1, "reconnect error %d", rc);
211 msleep(3000);
212 } else {
213 atomic_inc(&tcpSesReconnectCount);
214 spin_lock(&GlobalMid_Lock);
215 if (server->tcpStatus != CifsExiting)
216 server->tcpStatus = CifsGood;
217 spin_unlock(&GlobalMid_Lock);
221 return rc;
225 return codes:
226 0 not a transact2, or all data present
227 >0 transact2 with that much data missing
228 -EINVAL = invalid transact2
231 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
233 struct smb_t2_rsp *pSMBt;
234 int total_data_size;
235 int data_in_this_rsp;
236 int remaining;
238 if (pSMB->Command != SMB_COM_TRANSACTION2)
239 return 0;
241 /* check for plausible wct, bcc and t2 data and parm sizes */
242 /* check for parm and data offset going beyond end of smb */
243 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
244 cFYI(1, "invalid transact2 word count");
245 return -EINVAL;
248 pSMBt = (struct smb_t2_rsp *)pSMB;
250 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
251 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
253 remaining = total_data_size - data_in_this_rsp;
255 if (remaining == 0)
256 return 0;
257 else if (remaining < 0) {
258 cFYI(1, "total data %d smaller than data in frame %d",
259 total_data_size, data_in_this_rsp);
260 return -EINVAL;
261 } else {
262 cFYI(1, "missing %d bytes from transact2, check next response",
263 remaining);
264 if (total_data_size > maxBufSize) {
265 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
266 total_data_size, maxBufSize);
267 return -EINVAL;
269 return remaining;
273 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
275 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
276 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
277 int total_data_size;
278 int total_in_buf;
279 int remaining;
280 int total_in_buf2;
281 char *data_area_of_target;
282 char *data_area_of_buf2;
283 __u16 byte_count;
285 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
287 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
288 cFYI(1, "total data size of primary and secondary t2 differ");
291 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
293 remaining = total_data_size - total_in_buf;
295 if (remaining < 0)
296 return -EINVAL;
298 if (remaining == 0) /* nothing to do, ignore */
299 return 0;
301 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
302 if (remaining < total_in_buf2) {
303 cFYI(1, "transact2 2nd response contains too much data");
306 /* find end of first SMB data area */
307 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
308 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
309 /* validate target area */
311 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
312 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
314 data_area_of_target += total_in_buf;
316 /* copy second buffer into end of first buffer */
317 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
318 total_in_buf += total_in_buf2;
319 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
320 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
321 byte_count += total_in_buf2;
322 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
324 byte_count = pTargetSMB->smb_buf_length;
325 byte_count += total_in_buf2;
327 /* BB also add check that we are not beyond maximum buffer size */
329 pTargetSMB->smb_buf_length = byte_count;
331 if (remaining == total_in_buf2) {
332 cFYI(1, "found the last secondary response");
333 return 0; /* we are done */
334 } else /* more responses to go */
335 return 1;
339 static void
340 cifs_echo_request(struct work_struct *work)
342 int rc;
343 struct TCP_Server_Info *server = container_of(work,
344 struct TCP_Server_Info, echo.work);
346 /* no need to ping if we got a response recently */
347 if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
348 goto requeue_echo;
350 rc = CIFSSMBEcho(server);
351 if (rc)
352 cFYI(1, "Unable to send echo request to server: %s",
353 server->hostname);
355 requeue_echo:
356 queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL);
359 static int
360 cifs_demultiplex_thread(struct TCP_Server_Info *server)
362 int length;
363 unsigned int pdu_length, total_read;
364 struct smb_hdr *smb_buffer = NULL;
365 struct smb_hdr *bigbuf = NULL;
366 struct smb_hdr *smallbuf = NULL;
367 struct msghdr smb_msg;
368 struct kvec iov;
369 struct socket *csocket = server->ssocket;
370 struct list_head *tmp, *tmp2;
371 struct task_struct *task_to_wake = NULL;
372 struct mid_q_entry *mid_entry;
373 char temp;
374 bool isLargeBuf = false;
375 bool isMultiRsp;
376 int reconnect;
378 current->flags |= PF_MEMALLOC;
379 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
381 length = atomic_inc_return(&tcpSesAllocCount);
382 if (length > 1)
383 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
384 GFP_KERNEL);
386 set_freezable();
387 while (server->tcpStatus != CifsExiting) {
388 if (try_to_freeze())
389 continue;
390 if (bigbuf == NULL) {
391 bigbuf = cifs_buf_get();
392 if (!bigbuf) {
393 cERROR(1, "No memory for large SMB response");
394 msleep(3000);
395 /* retry will check if exiting */
396 continue;
398 } else if (isLargeBuf) {
399 /* we are reusing a dirty large buf, clear its start */
400 memset(bigbuf, 0, sizeof(struct smb_hdr));
403 if (smallbuf == NULL) {
404 smallbuf = cifs_small_buf_get();
405 if (!smallbuf) {
406 cERROR(1, "No memory for SMB response");
407 msleep(1000);
408 /* retry will check if exiting */
409 continue;
411 /* beginning of smb buffer is cleared in our buf_get */
412 } else /* if existing small buf clear beginning */
413 memset(smallbuf, 0, sizeof(struct smb_hdr));
415 isLargeBuf = false;
416 isMultiRsp = false;
417 smb_buffer = smallbuf;
418 iov.iov_base = smb_buffer;
419 iov.iov_len = 4;
420 smb_msg.msg_control = NULL;
421 smb_msg.msg_controllen = 0;
422 pdu_length = 4; /* enough to get RFC1001 header */
423 incomplete_rcv:
424 length =
425 kernel_recvmsg(csocket, &smb_msg,
426 &iov, 1, pdu_length, 0 /* BB other flags? */);
428 if (server->tcpStatus == CifsExiting) {
429 break;
430 } else if (server->tcpStatus == CifsNeedReconnect) {
431 cFYI(1, "Reconnect after server stopped responding");
432 cifs_reconnect(server);
433 cFYI(1, "call to reconnect done");
434 csocket = server->ssocket;
435 continue;
436 } else if (length == -ERESTARTSYS ||
437 length == -EAGAIN ||
438 length == -EINTR) {
439 msleep(1); /* minimum sleep to prevent looping
440 allowing socket to clear and app threads to set
441 tcpStatus CifsNeedReconnect if server hung */
442 if (pdu_length < 4) {
443 iov.iov_base = (4 - pdu_length) +
444 (char *)smb_buffer;
445 iov.iov_len = pdu_length;
446 smb_msg.msg_control = NULL;
447 smb_msg.msg_controllen = 0;
448 goto incomplete_rcv;
449 } else
450 continue;
451 } else if (length <= 0) {
452 cFYI(1, "Reconnect after unexpected peek error %d",
453 length);
454 cifs_reconnect(server);
455 csocket = server->ssocket;
456 wake_up(&server->response_q);
457 continue;
458 } else if (length < pdu_length) {
459 cFYI(1, "requested %d bytes but only got %d bytes",
460 pdu_length, length);
461 pdu_length -= length;
462 msleep(1);
463 goto incomplete_rcv;
466 /* The right amount was read from socket - 4 bytes */
467 /* so we can now interpret the length field */
469 /* the first byte big endian of the length field,
470 is actually not part of the length but the type
471 with the most common, zero, as regular data */
472 temp = *((char *) smb_buffer);
474 /* Note that FC 1001 length is big endian on the wire,
475 but we convert it here so it is always manipulated
476 as host byte order */
477 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
478 smb_buffer->smb_buf_length = pdu_length;
480 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
482 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
483 continue;
484 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
485 cFYI(1, "Good RFC 1002 session rsp");
486 continue;
487 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
488 /* we get this from Windows 98 instead of
489 an error on SMB negprot response */
490 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
491 pdu_length);
492 /* give server a second to clean up */
493 msleep(1000);
494 /* always try 445 first on reconnect since we get NACK
495 * on some if we ever connected to port 139 (the NACK
496 * is since we do not begin with RFC1001 session
497 * initialize frame)
499 cifs_set_port((struct sockaddr *)
500 &server->dstaddr, CIFS_PORT);
501 cifs_reconnect(server);
502 csocket = server->ssocket;
503 wake_up(&server->response_q);
504 continue;
505 } else if (temp != (char) 0) {
506 cERROR(1, "Unknown RFC 1002 frame");
507 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
508 length);
509 cifs_reconnect(server);
510 csocket = server->ssocket;
511 continue;
514 /* else we have an SMB response */
515 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
516 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
517 cERROR(1, "Invalid size SMB length %d pdu_length %d",
518 length, pdu_length+4);
519 cifs_reconnect(server);
520 csocket = server->ssocket;
521 wake_up(&server->response_q);
522 continue;
525 /* else length ok */
526 reconnect = 0;
528 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
529 isLargeBuf = true;
530 memcpy(bigbuf, smallbuf, 4);
531 smb_buffer = bigbuf;
533 length = 0;
534 iov.iov_base = 4 + (char *)smb_buffer;
535 iov.iov_len = pdu_length;
536 for (total_read = 0; total_read < pdu_length;
537 total_read += length) {
538 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
539 pdu_length - total_read, 0);
540 if (server->tcpStatus == CifsExiting) {
541 /* then will exit */
542 reconnect = 2;
543 break;
544 } else if (server->tcpStatus == CifsNeedReconnect) {
545 cifs_reconnect(server);
546 csocket = server->ssocket;
547 /* Reconnect wakes up rspns q */
548 /* Now we will reread sock */
549 reconnect = 1;
550 break;
551 } else if (length == -ERESTARTSYS ||
552 length == -EAGAIN ||
553 length == -EINTR) {
554 msleep(1); /* minimum sleep to prevent looping,
555 allowing socket to clear and app
556 threads to set tcpStatus
557 CifsNeedReconnect if server hung*/
558 length = 0;
559 continue;
560 } else if (length <= 0) {
561 cERROR(1, "Received no data, expecting %d",
562 pdu_length - total_read);
563 cifs_reconnect(server);
564 csocket = server->ssocket;
565 reconnect = 1;
566 break;
569 if (reconnect == 2)
570 break;
571 else if (reconnect == 1)
572 continue;
574 length += 4; /* account for rfc1002 hdr */
577 dump_smb(smb_buffer, length);
578 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
579 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
580 continue;
583 mid_entry = NULL;
584 spin_lock(&GlobalMid_Lock);
585 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
586 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
588 if ((mid_entry->mid == smb_buffer->Mid) &&
589 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
590 (mid_entry->command == smb_buffer->Command)) {
591 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
592 /* We have a multipart transact2 resp */
593 isMultiRsp = true;
594 if (mid_entry->resp_buf) {
595 /* merge response - fix up 1st*/
596 if (coalesce_t2(smb_buffer,
597 mid_entry->resp_buf)) {
598 mid_entry->multiRsp =
599 true;
600 break;
601 } else {
602 /* all parts received */
603 mid_entry->multiEnd =
604 true;
605 goto multi_t2_fnd;
607 } else {
608 if (!isLargeBuf) {
609 cERROR(1, "1st trans2 resp needs bigbuf");
610 /* BB maybe we can fix this up, switch
611 to already allocated large buffer? */
612 } else {
613 /* Have first buffer */
614 mid_entry->resp_buf =
615 smb_buffer;
616 mid_entry->largeBuf =
617 true;
618 bigbuf = NULL;
621 break;
623 mid_entry->resp_buf = smb_buffer;
624 mid_entry->largeBuf = isLargeBuf;
625 multi_t2_fnd:
626 mid_entry->midState = MID_RESPONSE_RECEIVED;
627 list_del_init(&mid_entry->qhead);
628 mid_entry->callback(mid_entry);
629 #ifdef CONFIG_CIFS_STATS2
630 mid_entry->when_received = jiffies;
631 #endif
632 /* so we do not time out requests to server
633 which is still responding (since server could
634 be busy but not dead) */
635 server->lstrp = jiffies;
636 break;
638 mid_entry = NULL;
640 spin_unlock(&GlobalMid_Lock);
642 if (mid_entry != NULL) {
643 /* Was previous buf put in mpx struct for multi-rsp? */
644 if (!isMultiRsp) {
645 /* smb buffer will be freed by user thread */
646 if (isLargeBuf)
647 bigbuf = NULL;
648 else
649 smallbuf = NULL;
651 } else if (!is_valid_oplock_break(smb_buffer, server) &&
652 !isMultiRsp) {
653 cERROR(1, "No task to wake, unknown frame received! "
654 "NumMids %d", atomic_read(&midCount));
655 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
656 sizeof(struct smb_hdr));
657 #ifdef CONFIG_CIFS_DEBUG2
658 cifs_dump_detail(smb_buffer);
659 cifs_dump_mids(server);
660 #endif /* CIFS_DEBUG2 */
663 } /* end while !EXITING */
665 /* take it off the list, if it's not already */
666 spin_lock(&cifs_tcp_ses_lock);
667 list_del_init(&server->tcp_ses_list);
668 spin_unlock(&cifs_tcp_ses_lock);
670 spin_lock(&GlobalMid_Lock);
671 server->tcpStatus = CifsExiting;
672 spin_unlock(&GlobalMid_Lock);
673 wake_up_all(&server->response_q);
675 /* check if we have blocked requests that need to free */
676 /* Note that cifs_max_pending is normally 50, but
677 can be set at module install time to as little as two */
678 spin_lock(&GlobalMid_Lock);
679 if (atomic_read(&server->inFlight) >= cifs_max_pending)
680 atomic_set(&server->inFlight, cifs_max_pending - 1);
681 /* We do not want to set the max_pending too low or we
682 could end up with the counter going negative */
683 spin_unlock(&GlobalMid_Lock);
684 /* Although there should not be any requests blocked on
685 this queue it can not hurt to be paranoid and try to wake up requests
686 that may haven been blocked when more than 50 at time were on the wire
687 to the same server - they now will see the session is in exit state
688 and get out of SendReceive. */
689 wake_up_all(&server->request_q);
690 /* give those requests time to exit */
691 msleep(125);
693 if (server->ssocket) {
694 sock_release(csocket);
695 server->ssocket = NULL;
697 /* buffer usuallly freed in free_mid - need to free it here on exit */
698 cifs_buf_release(bigbuf);
699 if (smallbuf) /* no sense logging a debug message if NULL */
700 cifs_small_buf_release(smallbuf);
702 if (!list_empty(&server->pending_mid_q)) {
703 spin_lock(&GlobalMid_Lock);
704 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
705 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
706 cFYI(1, "Clearing Mid 0x%x - issuing callback",
707 mid_entry->mid);
708 list_del_init(&mid_entry->qhead);
709 mid_entry->callback(mid_entry);
711 spin_unlock(&GlobalMid_Lock);
712 /* 1/8th of sec is more than enough time for them to exit */
713 msleep(125);
716 if (!list_empty(&server->pending_mid_q)) {
717 /* mpx threads have not exited yet give them
718 at least the smb send timeout time for long ops */
719 /* due to delays on oplock break requests, we need
720 to wait at least 45 seconds before giving up
721 on a request getting a response and going ahead
722 and killing cifsd */
723 cFYI(1, "Wait for exit from demultiplex thread");
724 msleep(46000);
725 /* if threads still have not exited they are probably never
726 coming home not much else we can do but free the memory */
729 kfree(server->hostname);
730 task_to_wake = xchg(&server->tsk, NULL);
731 kfree(server);
733 length = atomic_dec_return(&tcpSesAllocCount);
734 if (length > 0)
735 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
736 GFP_KERNEL);
738 /* if server->tsk was NULL then wait for a signal before exiting */
739 if (!task_to_wake) {
740 set_current_state(TASK_INTERRUPTIBLE);
741 while (!signal_pending(current)) {
742 schedule();
743 set_current_state(TASK_INTERRUPTIBLE);
745 set_current_state(TASK_RUNNING);
748 module_put_and_exit(0);
751 /* extract the host portion of the UNC string */
752 static char *
753 extract_hostname(const char *unc)
755 const char *src;
756 char *dst, *delim;
757 unsigned int len;
759 /* skip double chars at beginning of string */
760 /* BB: check validity of these bytes? */
761 src = unc + 2;
763 /* delimiter between hostname and sharename is always '\\' now */
764 delim = strchr(src, '\\');
765 if (!delim)
766 return ERR_PTR(-EINVAL);
768 len = delim - src;
769 dst = kmalloc((len + 1), GFP_KERNEL);
770 if (dst == NULL)
771 return ERR_PTR(-ENOMEM);
773 memcpy(dst, src, len);
774 dst[len] = '\0';
776 return dst;
779 static int
780 cifs_parse_mount_options(char *options, const char *devname,
781 struct smb_vol *vol)
783 char *value;
784 char *data;
785 unsigned int temp_len, i, j;
786 char separator[2];
787 short int override_uid = -1;
788 short int override_gid = -1;
789 bool uid_specified = false;
790 bool gid_specified = false;
791 char *nodename = utsname()->nodename;
793 separator[0] = ',';
794 separator[1] = 0;
797 * does not have to be perfect mapping since field is
798 * informational, only used for servers that do not support
799 * port 445 and it can be overridden at mount time
801 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
802 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
803 vol->source_rfc1001_name[i] = toupper(nodename[i]);
805 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
806 /* null target name indicates to use *SMBSERVR default called name
807 if we end up sending RFC1001 session initialize */
808 vol->target_rfc1001_name[0] = 0;
809 vol->cred_uid = current_uid();
810 vol->linux_uid = current_uid();
811 vol->linux_gid = current_gid();
813 /* default to only allowing write access to owner of the mount */
814 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
816 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
817 /* default is always to request posix paths. */
818 vol->posix_paths = 1;
819 /* default to using server inode numbers where available */
820 vol->server_ino = 1;
822 vol->actimeo = CIFS_DEF_ACTIMEO;
824 if (!options)
825 return 1;
827 if (strncmp(options, "sep=", 4) == 0) {
828 if (options[4] != 0) {
829 separator[0] = options[4];
830 options += 5;
831 } else {
832 cFYI(1, "Null separator not allowed");
836 while ((data = strsep(&options, separator)) != NULL) {
837 if (!*data)
838 continue;
839 if ((value = strchr(data, '=')) != NULL)
840 *value++ = '\0';
842 /* Have to parse this before we parse for "user" */
843 if (strnicmp(data, "user_xattr", 10) == 0) {
844 vol->no_xattr = 0;
845 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
846 vol->no_xattr = 1;
847 } else if (strnicmp(data, "user", 4) == 0) {
848 if (!value) {
849 printk(KERN_WARNING
850 "CIFS: invalid or missing username\n");
851 return 1; /* needs_arg; */
852 } else if (!*value) {
853 /* null user, ie anonymous, authentication */
854 vol->nullauth = 1;
856 if (strnlen(value, 200) < 200) {
857 vol->username = value;
858 } else {
859 printk(KERN_WARNING "CIFS: username too long\n");
860 return 1;
862 } else if (strnicmp(data, "pass", 4) == 0) {
863 if (!value) {
864 vol->password = NULL;
865 continue;
866 } else if (value[0] == 0) {
867 /* check if string begins with double comma
868 since that would mean the password really
869 does start with a comma, and would not
870 indicate an empty string */
871 if (value[1] != separator[0]) {
872 vol->password = NULL;
873 continue;
876 temp_len = strlen(value);
877 /* removed password length check, NTLM passwords
878 can be arbitrarily long */
880 /* if comma in password, the string will be
881 prematurely null terminated. Commas in password are
882 specified across the cifs mount interface by a double
883 comma ie ,, and a comma used as in other cases ie ','
884 as a parameter delimiter/separator is single and due
885 to the strsep above is temporarily zeroed. */
887 /* NB: password legally can have multiple commas and
888 the only illegal character in a password is null */
890 if ((value[temp_len] == 0) &&
891 (value[temp_len+1] == separator[0])) {
892 /* reinsert comma */
893 value[temp_len] = separator[0];
894 temp_len += 2; /* move after second comma */
895 while (value[temp_len] != 0) {
896 if (value[temp_len] == separator[0]) {
897 if (value[temp_len+1] ==
898 separator[0]) {
899 /* skip second comma */
900 temp_len++;
901 } else {
902 /* single comma indicating start
903 of next parm */
904 break;
907 temp_len++;
909 if (value[temp_len] == 0) {
910 options = NULL;
911 } else {
912 value[temp_len] = 0;
913 /* point option to start of next parm */
914 options = value + temp_len + 1;
916 /* go from value to value + temp_len condensing
917 double commas to singles. Note that this ends up
918 allocating a few bytes too many, which is ok */
919 vol->password = kzalloc(temp_len, GFP_KERNEL);
920 if (vol->password == NULL) {
921 printk(KERN_WARNING "CIFS: no memory "
922 "for password\n");
923 return 1;
925 for (i = 0, j = 0; i < temp_len; i++, j++) {
926 vol->password[j] = value[i];
927 if (value[i] == separator[0]
928 && value[i+1] == separator[0]) {
929 /* skip second comma */
930 i++;
933 vol->password[j] = 0;
934 } else {
935 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
936 if (vol->password == NULL) {
937 printk(KERN_WARNING "CIFS: no memory "
938 "for password\n");
939 return 1;
941 strcpy(vol->password, value);
943 } else if (!strnicmp(data, "ip", 2) ||
944 !strnicmp(data, "addr", 4)) {
945 if (!value || !*value) {
946 vol->UNCip = NULL;
947 } else if (strnlen(value, INET6_ADDRSTRLEN) <
948 INET6_ADDRSTRLEN) {
949 vol->UNCip = value;
950 } else {
951 printk(KERN_WARNING "CIFS: ip address "
952 "too long\n");
953 return 1;
955 } else if (strnicmp(data, "sec", 3) == 0) {
956 if (!value || !*value) {
957 cERROR(1, "no security value specified");
958 continue;
959 } else if (strnicmp(value, "krb5i", 5) == 0) {
960 vol->secFlg |= CIFSSEC_MAY_KRB5 |
961 CIFSSEC_MUST_SIGN;
962 } else if (strnicmp(value, "krb5p", 5) == 0) {
963 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
964 CIFSSEC_MAY_KRB5; */
965 cERROR(1, "Krb5 cifs privacy not supported");
966 return 1;
967 } else if (strnicmp(value, "krb5", 4) == 0) {
968 vol->secFlg |= CIFSSEC_MAY_KRB5;
969 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
970 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
971 CIFSSEC_MUST_SIGN;
972 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
973 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
974 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
975 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
976 CIFSSEC_MUST_SIGN;
977 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
978 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
979 } else if (strnicmp(value, "ntlmi", 5) == 0) {
980 vol->secFlg |= CIFSSEC_MAY_NTLM |
981 CIFSSEC_MUST_SIGN;
982 } else if (strnicmp(value, "ntlm", 4) == 0) {
983 /* ntlm is default so can be turned off too */
984 vol->secFlg |= CIFSSEC_MAY_NTLM;
985 } else if (strnicmp(value, "nontlm", 6) == 0) {
986 /* BB is there a better way to do this? */
987 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
988 #ifdef CONFIG_CIFS_WEAK_PW_HASH
989 } else if (strnicmp(value, "lanman", 6) == 0) {
990 vol->secFlg |= CIFSSEC_MAY_LANMAN;
991 #endif
992 } else if (strnicmp(value, "none", 4) == 0) {
993 vol->nullauth = 1;
994 } else {
995 cERROR(1, "bad security option: %s", value);
996 return 1;
998 } else if ((strnicmp(data, "unc", 3) == 0)
999 || (strnicmp(data, "target", 6) == 0)
1000 || (strnicmp(data, "path", 4) == 0)) {
1001 if (!value || !*value) {
1002 printk(KERN_WARNING "CIFS: invalid path to "
1003 "network resource\n");
1004 return 1; /* needs_arg; */
1006 if ((temp_len = strnlen(value, 300)) < 300) {
1007 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1008 if (vol->UNC == NULL)
1009 return 1;
1010 strcpy(vol->UNC, value);
1011 if (strncmp(vol->UNC, "//", 2) == 0) {
1012 vol->UNC[0] = '\\';
1013 vol->UNC[1] = '\\';
1014 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1015 printk(KERN_WARNING
1016 "CIFS: UNC Path does not begin "
1017 "with // or \\\\ \n");
1018 return 1;
1020 } else {
1021 printk(KERN_WARNING "CIFS: UNC name too long\n");
1022 return 1;
1024 } else if ((strnicmp(data, "domain", 3) == 0)
1025 || (strnicmp(data, "workgroup", 5) == 0)) {
1026 if (!value || !*value) {
1027 printk(KERN_WARNING "CIFS: invalid domain name\n");
1028 return 1; /* needs_arg; */
1030 /* BB are there cases in which a comma can be valid in
1031 a domain name and need special handling? */
1032 if (strnlen(value, 256) < 256) {
1033 vol->domainname = value;
1034 cFYI(1, "Domain name set");
1035 } else {
1036 printk(KERN_WARNING "CIFS: domain name too "
1037 "long\n");
1038 return 1;
1040 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1041 vol->srcaddr.ss_family = AF_UNSPEC;
1043 if (!value || !*value) {
1044 printk(KERN_WARNING "CIFS: srcaddr value"
1045 " not specified.\n");
1046 return 1; /* needs_arg; */
1048 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1049 value, strlen(value));
1050 if (i == 0) {
1051 printk(KERN_WARNING "CIFS: Could not parse"
1052 " srcaddr: %s\n",
1053 value);
1054 return 1;
1056 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1057 if (!value || !*value) {
1058 printk(KERN_WARNING
1059 "CIFS: invalid path prefix\n");
1060 return 1; /* needs_argument */
1062 if ((temp_len = strnlen(value, 1024)) < 1024) {
1063 if (value[0] != '/')
1064 temp_len++; /* missing leading slash */
1065 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1066 if (vol->prepath == NULL)
1067 return 1;
1068 if (value[0] != '/') {
1069 vol->prepath[0] = '/';
1070 strcpy(vol->prepath+1, value);
1071 } else
1072 strcpy(vol->prepath, value);
1073 cFYI(1, "prefix path %s", vol->prepath);
1074 } else {
1075 printk(KERN_WARNING "CIFS: prefix too long\n");
1076 return 1;
1078 } else if (strnicmp(data, "iocharset", 9) == 0) {
1079 if (!value || !*value) {
1080 printk(KERN_WARNING "CIFS: invalid iocharset "
1081 "specified\n");
1082 return 1; /* needs_arg; */
1084 if (strnlen(value, 65) < 65) {
1085 if (strnicmp(value, "default", 7))
1086 vol->iocharset = value;
1087 /* if iocharset not set then load_nls_default
1088 is used by caller */
1089 cFYI(1, "iocharset set to %s", value);
1090 } else {
1091 printk(KERN_WARNING "CIFS: iocharset name "
1092 "too long.\n");
1093 return 1;
1095 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1096 vol->linux_uid = simple_strtoul(value, &value, 0);
1097 uid_specified = true;
1098 } else if (!strnicmp(data, "cruid", 5) && value && *value) {
1099 vol->cred_uid = simple_strtoul(value, &value, 0);
1100 } else if (!strnicmp(data, "forceuid", 8)) {
1101 override_uid = 1;
1102 } else if (!strnicmp(data, "noforceuid", 10)) {
1103 override_uid = 0;
1104 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1105 vol->linux_gid = simple_strtoul(value, &value, 0);
1106 gid_specified = true;
1107 } else if (!strnicmp(data, "forcegid", 8)) {
1108 override_gid = 1;
1109 } else if (!strnicmp(data, "noforcegid", 10)) {
1110 override_gid = 0;
1111 } else if (strnicmp(data, "file_mode", 4) == 0) {
1112 if (value && *value) {
1113 vol->file_mode =
1114 simple_strtoul(value, &value, 0);
1116 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1117 if (value && *value) {
1118 vol->dir_mode =
1119 simple_strtoul(value, &value, 0);
1121 } else if (strnicmp(data, "dirmode", 4) == 0) {
1122 if (value && *value) {
1123 vol->dir_mode =
1124 simple_strtoul(value, &value, 0);
1126 } else if (strnicmp(data, "port", 4) == 0) {
1127 if (value && *value) {
1128 vol->port =
1129 simple_strtoul(value, &value, 0);
1131 } else if (strnicmp(data, "rsize", 5) == 0) {
1132 if (value && *value) {
1133 vol->rsize =
1134 simple_strtoul(value, &value, 0);
1136 } else if (strnicmp(data, "wsize", 5) == 0) {
1137 if (value && *value) {
1138 vol->wsize =
1139 simple_strtoul(value, &value, 0);
1141 } else if (strnicmp(data, "sockopt", 5) == 0) {
1142 if (!value || !*value) {
1143 cERROR(1, "no socket option specified");
1144 continue;
1145 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1146 vol->sockopt_tcp_nodelay = 1;
1148 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1149 if (!value || !*value || (*value == ' ')) {
1150 cFYI(1, "invalid (empty) netbiosname");
1151 } else {
1152 memset(vol->source_rfc1001_name, 0x20,
1153 RFC1001_NAME_LEN);
1155 * FIXME: are there cases in which a comma can
1156 * be valid in workstation netbios name (and
1157 * need special handling)?
1159 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1160 /* don't ucase netbiosname for user */
1161 if (value[i] == 0)
1162 break;
1163 vol->source_rfc1001_name[i] = value[i];
1165 /* The string has 16th byte zero still from
1166 set at top of the function */
1167 if (i == RFC1001_NAME_LEN && value[i] != 0)
1168 printk(KERN_WARNING "CIFS: netbiosname"
1169 " longer than 15 truncated.\n");
1171 } else if (strnicmp(data, "servern", 7) == 0) {
1172 /* servernetbiosname specified override *SMBSERVER */
1173 if (!value || !*value || (*value == ' ')) {
1174 cFYI(1, "empty server netbiosname specified");
1175 } else {
1176 /* last byte, type, is 0x20 for servr type */
1177 memset(vol->target_rfc1001_name, 0x20,
1178 RFC1001_NAME_LEN_WITH_NULL);
1180 for (i = 0; i < 15; i++) {
1181 /* BB are there cases in which a comma can be
1182 valid in this workstation netbios name
1183 (and need special handling)? */
1185 /* user or mount helper must uppercase
1186 the netbiosname */
1187 if (value[i] == 0)
1188 break;
1189 else
1190 vol->target_rfc1001_name[i] =
1191 value[i];
1193 /* The string has 16th byte zero still from
1194 set at top of the function */
1195 if (i == RFC1001_NAME_LEN && value[i] != 0)
1196 printk(KERN_WARNING "CIFS: server net"
1197 "biosname longer than 15 truncated.\n");
1199 } else if (strnicmp(data, "actimeo", 7) == 0) {
1200 if (value && *value) {
1201 vol->actimeo = HZ * simple_strtoul(value,
1202 &value, 0);
1203 if (vol->actimeo > CIFS_MAX_ACTIMEO) {
1204 cERROR(1, "CIFS: attribute cache"
1205 "timeout too large");
1206 return 1;
1209 } else if (strnicmp(data, "credentials", 4) == 0) {
1210 /* ignore */
1211 } else if (strnicmp(data, "version", 3) == 0) {
1212 /* ignore */
1213 } else if (strnicmp(data, "guest", 5) == 0) {
1214 /* ignore */
1215 } else if (strnicmp(data, "rw", 2) == 0) {
1216 /* ignore */
1217 } else if (strnicmp(data, "ro", 2) == 0) {
1218 /* ignore */
1219 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1220 vol->noblocksnd = 1;
1221 } else if (strnicmp(data, "noautotune", 10) == 0) {
1222 vol->noautotune = 1;
1223 } else if ((strnicmp(data, "suid", 4) == 0) ||
1224 (strnicmp(data, "nosuid", 6) == 0) ||
1225 (strnicmp(data, "exec", 4) == 0) ||
1226 (strnicmp(data, "noexec", 6) == 0) ||
1227 (strnicmp(data, "nodev", 5) == 0) ||
1228 (strnicmp(data, "noauto", 6) == 0) ||
1229 (strnicmp(data, "dev", 3) == 0)) {
1230 /* The mount tool or mount.cifs helper (if present)
1231 uses these opts to set flags, and the flags are read
1232 by the kernel vfs layer before we get here (ie
1233 before read super) so there is no point trying to
1234 parse these options again and set anything and it
1235 is ok to just ignore them */
1236 continue;
1237 } else if (strnicmp(data, "hard", 4) == 0) {
1238 vol->retry = 1;
1239 } else if (strnicmp(data, "soft", 4) == 0) {
1240 vol->retry = 0;
1241 } else if (strnicmp(data, "perm", 4) == 0) {
1242 vol->noperm = 0;
1243 } else if (strnicmp(data, "noperm", 6) == 0) {
1244 vol->noperm = 1;
1245 } else if (strnicmp(data, "mapchars", 8) == 0) {
1246 vol->remap = 1;
1247 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1248 vol->remap = 0;
1249 } else if (strnicmp(data, "sfu", 3) == 0) {
1250 vol->sfu_emul = 1;
1251 } else if (strnicmp(data, "nosfu", 5) == 0) {
1252 vol->sfu_emul = 0;
1253 } else if (strnicmp(data, "nodfs", 5) == 0) {
1254 vol->nodfs = 1;
1255 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1256 vol->posix_paths = 1;
1257 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1258 vol->posix_paths = 0;
1259 } else if (strnicmp(data, "nounix", 6) == 0) {
1260 vol->no_linux_ext = 1;
1261 } else if (strnicmp(data, "nolinux", 7) == 0) {
1262 vol->no_linux_ext = 1;
1263 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1264 (strnicmp(data, "ignorecase", 10) == 0)) {
1265 vol->nocase = 1;
1266 } else if (strnicmp(data, "mand", 4) == 0) {
1267 /* ignore */
1268 } else if (strnicmp(data, "nomand", 6) == 0) {
1269 /* ignore */
1270 } else if (strnicmp(data, "_netdev", 7) == 0) {
1271 /* ignore */
1272 } else if (strnicmp(data, "brl", 3) == 0) {
1273 vol->nobrl = 0;
1274 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1275 (strnicmp(data, "nolock", 6) == 0)) {
1276 vol->nobrl = 1;
1277 /* turn off mandatory locking in mode
1278 if remote locking is turned off since the
1279 local vfs will do advisory */
1280 if (vol->file_mode ==
1281 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1282 vol->file_mode = S_IALLUGO;
1283 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1284 /* will take the shorter form "forcemand" as well */
1285 /* This mount option will force use of mandatory
1286 (DOS/Windows style) byte range locks, instead of
1287 using posix advisory byte range locks, even if the
1288 Unix extensions are available and posix locks would
1289 be supported otherwise. If Unix extensions are not
1290 negotiated this has no effect since mandatory locks
1291 would be used (mandatory locks is all that those
1292 those servers support) */
1293 vol->mand_lock = 1;
1294 } else if (strnicmp(data, "setuids", 7) == 0) {
1295 vol->setuids = 1;
1296 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1297 vol->setuids = 0;
1298 } else if (strnicmp(data, "dynperm", 7) == 0) {
1299 vol->dynperm = true;
1300 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1301 vol->dynperm = false;
1302 } else if (strnicmp(data, "nohard", 6) == 0) {
1303 vol->retry = 0;
1304 } else if (strnicmp(data, "nosoft", 6) == 0) {
1305 vol->retry = 1;
1306 } else if (strnicmp(data, "nointr", 6) == 0) {
1307 vol->intr = 0;
1308 } else if (strnicmp(data, "intr", 4) == 0) {
1309 vol->intr = 1;
1310 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1311 vol->nostrictsync = 1;
1312 } else if (strnicmp(data, "strictsync", 10) == 0) {
1313 vol->nostrictsync = 0;
1314 } else if (strnicmp(data, "serverino", 7) == 0) {
1315 vol->server_ino = 1;
1316 } else if (strnicmp(data, "noserverino", 9) == 0) {
1317 vol->server_ino = 0;
1318 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1319 vol->cifs_acl = 1;
1320 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1321 vol->cifs_acl = 0;
1322 } else if (strnicmp(data, "acl", 3) == 0) {
1323 vol->no_psx_acl = 0;
1324 } else if (strnicmp(data, "noacl", 5) == 0) {
1325 vol->no_psx_acl = 1;
1326 } else if (strnicmp(data, "locallease", 6) == 0) {
1327 vol->local_lease = 1;
1328 } else if (strnicmp(data, "sign", 4) == 0) {
1329 vol->secFlg |= CIFSSEC_MUST_SIGN;
1330 } else if (strnicmp(data, "seal", 4) == 0) {
1331 /* we do not do the following in secFlags because seal
1332 is a per tree connection (mount) not a per socket
1333 or per-smb connection option in the protocol */
1334 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1335 vol->seal = 1;
1336 } else if (strnicmp(data, "direct", 6) == 0) {
1337 vol->direct_io = 1;
1338 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1339 vol->direct_io = 1;
1340 } else if (strnicmp(data, "noac", 4) == 0) {
1341 printk(KERN_WARNING "CIFS: Mount option noac not "
1342 "supported. Instead set "
1343 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1344 } else if (strnicmp(data, "fsc", 3) == 0) {
1345 #ifndef CONFIG_CIFS_FSCACHE
1346 cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE"
1347 "kernel config option set");
1348 return 1;
1349 #endif
1350 vol->fsc = true;
1351 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1352 vol->mfsymlinks = true;
1353 } else if (strnicmp(data, "multiuser", 8) == 0) {
1354 vol->multiuser = true;
1355 } else
1356 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1357 data);
1359 if (vol->UNC == NULL) {
1360 if (devname == NULL) {
1361 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1362 "target\n");
1363 return 1;
1365 if ((temp_len = strnlen(devname, 300)) < 300) {
1366 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1367 if (vol->UNC == NULL)
1368 return 1;
1369 strcpy(vol->UNC, devname);
1370 if (strncmp(vol->UNC, "//", 2) == 0) {
1371 vol->UNC[0] = '\\';
1372 vol->UNC[1] = '\\';
1373 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1374 printk(KERN_WARNING "CIFS: UNC Path does not "
1375 "begin with // or \\\\ \n");
1376 return 1;
1378 value = strpbrk(vol->UNC+2, "/\\");
1379 if (value)
1380 *value = '\\';
1381 } else {
1382 printk(KERN_WARNING "CIFS: UNC name too long\n");
1383 return 1;
1387 if (vol->multiuser && !(vol->secFlg & CIFSSEC_MAY_KRB5)) {
1388 cERROR(1, "Multiuser mounts currently require krb5 "
1389 "authentication!");
1390 return 1;
1393 if (vol->UNCip == NULL)
1394 vol->UNCip = &vol->UNC[2];
1396 if (uid_specified)
1397 vol->override_uid = override_uid;
1398 else if (override_uid == 1)
1399 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1400 "specified with no uid= option.\n");
1402 if (gid_specified)
1403 vol->override_gid = override_gid;
1404 else if (override_gid == 1)
1405 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1406 "specified with no gid= option.\n");
1408 return 0;
1411 /** Returns true if srcaddr isn't specified and rhs isn't
1412 * specified, or if srcaddr is specified and
1413 * matches the IP address of the rhs argument.
1415 static bool
1416 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1418 switch (srcaddr->sa_family) {
1419 case AF_UNSPEC:
1420 return (rhs->sa_family == AF_UNSPEC);
1421 case AF_INET: {
1422 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1423 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1424 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1426 case AF_INET6: {
1427 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1428 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1429 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1431 default:
1432 WARN_ON(1);
1433 return false; /* don't expect to be here */
1438 * If no port is specified in addr structure, we try to match with 445 port
1439 * and if it fails - with 139 ports. It should be called only if address
1440 * families of server and addr are equal.
1442 static bool
1443 match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1445 unsigned short int port, *sport;
1447 switch (addr->sa_family) {
1448 case AF_INET:
1449 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1450 port = ((struct sockaddr_in *) addr)->sin_port;
1451 break;
1452 case AF_INET6:
1453 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1454 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1455 break;
1456 default:
1457 WARN_ON(1);
1458 return false;
1461 if (!port) {
1462 port = htons(CIFS_PORT);
1463 if (port == *sport)
1464 return true;
1466 port = htons(RFC1001_PORT);
1469 return port == *sport;
1472 static bool
1473 match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1474 struct sockaddr *srcaddr)
1476 switch (addr->sa_family) {
1477 case AF_INET: {
1478 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1479 struct sockaddr_in *srv_addr4 =
1480 (struct sockaddr_in *)&server->dstaddr;
1482 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1483 return false;
1484 break;
1486 case AF_INET6: {
1487 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1488 struct sockaddr_in6 *srv_addr6 =
1489 (struct sockaddr_in6 *)&server->dstaddr;
1491 if (!ipv6_addr_equal(&addr6->sin6_addr,
1492 &srv_addr6->sin6_addr))
1493 return false;
1494 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1495 return false;
1496 break;
1498 default:
1499 WARN_ON(1);
1500 return false; /* don't expect to be here */
1503 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1504 return false;
1506 return true;
1509 static bool
1510 match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1512 unsigned int secFlags;
1514 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1515 secFlags = vol->secFlg;
1516 else
1517 secFlags = global_secflags | vol->secFlg;
1519 switch (server->secType) {
1520 case LANMAN:
1521 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1522 return false;
1523 break;
1524 case NTLMv2:
1525 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1526 return false;
1527 break;
1528 case NTLM:
1529 if (!(secFlags & CIFSSEC_MAY_NTLM))
1530 return false;
1531 break;
1532 case Kerberos:
1533 if (!(secFlags & CIFSSEC_MAY_KRB5))
1534 return false;
1535 break;
1536 case RawNTLMSSP:
1537 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1538 return false;
1539 break;
1540 default:
1541 /* shouldn't happen */
1542 return false;
1545 /* now check if signing mode is acceptible */
1546 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1547 (server->secMode & SECMODE_SIGN_REQUIRED))
1548 return false;
1549 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1550 (server->secMode &
1551 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1552 return false;
1554 return true;
1557 static struct TCP_Server_Info *
1558 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1560 struct TCP_Server_Info *server;
1562 spin_lock(&cifs_tcp_ses_lock);
1563 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1564 if (!match_address(server, addr,
1565 (struct sockaddr *)&vol->srcaddr))
1566 continue;
1568 if (!match_port(server, addr))
1569 continue;
1571 if (!match_security(server, vol))
1572 continue;
1574 ++server->srv_count;
1575 spin_unlock(&cifs_tcp_ses_lock);
1576 cFYI(1, "Existing tcp session with server found");
1577 return server;
1579 spin_unlock(&cifs_tcp_ses_lock);
1580 return NULL;
1583 static void
1584 cifs_put_tcp_session(struct TCP_Server_Info *server)
1586 struct task_struct *task;
1588 spin_lock(&cifs_tcp_ses_lock);
1589 if (--server->srv_count > 0) {
1590 spin_unlock(&cifs_tcp_ses_lock);
1591 return;
1594 list_del_init(&server->tcp_ses_list);
1595 spin_unlock(&cifs_tcp_ses_lock);
1597 cancel_delayed_work_sync(&server->echo);
1599 spin_lock(&GlobalMid_Lock);
1600 server->tcpStatus = CifsExiting;
1601 spin_unlock(&GlobalMid_Lock);
1603 cifs_crypto_shash_release(server);
1604 cifs_fscache_release_client_cookie(server);
1606 kfree(server->session_key.response);
1607 server->session_key.response = NULL;
1608 server->session_key.len = 0;
1610 task = xchg(&server->tsk, NULL);
1611 if (task)
1612 force_sig(SIGKILL, task);
1615 static struct TCP_Server_Info *
1616 cifs_get_tcp_session(struct smb_vol *volume_info)
1618 struct TCP_Server_Info *tcp_ses = NULL;
1619 struct sockaddr_storage addr;
1620 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1621 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1622 int rc;
1624 memset(&addr, 0, sizeof(struct sockaddr_storage));
1626 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1628 if (volume_info->UNCip && volume_info->UNC) {
1629 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1630 volume_info->UNCip,
1631 strlen(volume_info->UNCip),
1632 volume_info->port);
1633 if (!rc) {
1634 /* we failed translating address */
1635 rc = -EINVAL;
1636 goto out_err;
1638 } else if (volume_info->UNCip) {
1639 /* BB using ip addr as tcp_ses name to connect to the
1640 DFS root below */
1641 cERROR(1, "Connecting to DFS root not implemented yet");
1642 rc = -EINVAL;
1643 goto out_err;
1644 } else /* which tcp_sess DFS root would we conect to */ {
1645 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1646 "unc=//192.168.1.100/public) specified");
1647 rc = -EINVAL;
1648 goto out_err;
1651 /* see if we already have a matching tcp_ses */
1652 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1653 if (tcp_ses)
1654 return tcp_ses;
1656 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1657 if (!tcp_ses) {
1658 rc = -ENOMEM;
1659 goto out_err;
1662 rc = cifs_crypto_shash_allocate(tcp_ses);
1663 if (rc) {
1664 cERROR(1, "could not setup hash structures rc %d", rc);
1665 goto out_err;
1668 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1669 if (IS_ERR(tcp_ses->hostname)) {
1670 rc = PTR_ERR(tcp_ses->hostname);
1671 goto out_err_crypto_release;
1674 tcp_ses->noblocksnd = volume_info->noblocksnd;
1675 tcp_ses->noautotune = volume_info->noautotune;
1676 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1677 atomic_set(&tcp_ses->inFlight, 0);
1678 init_waitqueue_head(&tcp_ses->response_q);
1679 init_waitqueue_head(&tcp_ses->request_q);
1680 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1681 mutex_init(&tcp_ses->srv_mutex);
1682 memcpy(tcp_ses->workstation_RFC1001_name,
1683 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1684 memcpy(tcp_ses->server_RFC1001_name,
1685 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1686 tcp_ses->session_estab = false;
1687 tcp_ses->sequence_number = 0;
1688 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1689 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1690 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
1693 * at this point we are the only ones with the pointer
1694 * to the struct since the kernel thread not created yet
1695 * no need to spinlock this init of tcpStatus or srv_count
1697 tcp_ses->tcpStatus = CifsNew;
1698 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1699 sizeof(tcp_ses->srcaddr));
1700 ++tcp_ses->srv_count;
1702 if (addr.ss_family == AF_INET6) {
1703 cFYI(1, "attempting ipv6 connect");
1704 /* BB should we allow ipv6 on port 139? */
1705 /* other OS never observed in Wild doing 139 with v6 */
1706 memcpy(&tcp_ses->dstaddr, sin_server6,
1707 sizeof(struct sockaddr_in6));
1708 } else
1709 memcpy(&tcp_ses->dstaddr, sin_server,
1710 sizeof(struct sockaddr_in));
1712 rc = ip_connect(tcp_ses);
1713 if (rc < 0) {
1714 cERROR(1, "Error connecting to socket. Aborting operation");
1715 goto out_err_crypto_release;
1719 * since we're in a cifs function already, we know that
1720 * this will succeed. No need for try_module_get().
1722 __module_get(THIS_MODULE);
1723 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1724 tcp_ses, "cifsd");
1725 if (IS_ERR(tcp_ses->tsk)) {
1726 rc = PTR_ERR(tcp_ses->tsk);
1727 cERROR(1, "error %d create cifsd thread", rc);
1728 module_put(THIS_MODULE);
1729 goto out_err_crypto_release;
1732 /* thread spawned, put it on the list */
1733 spin_lock(&cifs_tcp_ses_lock);
1734 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1735 spin_unlock(&cifs_tcp_ses_lock);
1737 cifs_fscache_get_client_cookie(tcp_ses);
1739 /* queue echo request delayed work */
1740 queue_delayed_work(system_nrt_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
1742 return tcp_ses;
1744 out_err_crypto_release:
1745 cifs_crypto_shash_release(tcp_ses);
1747 out_err:
1748 if (tcp_ses) {
1749 if (!IS_ERR(tcp_ses->hostname))
1750 kfree(tcp_ses->hostname);
1751 if (tcp_ses->ssocket)
1752 sock_release(tcp_ses->ssocket);
1753 kfree(tcp_ses);
1755 return ERR_PTR(rc);
1758 static struct cifsSesInfo *
1759 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1761 struct cifsSesInfo *ses;
1763 spin_lock(&cifs_tcp_ses_lock);
1764 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1765 switch (server->secType) {
1766 case Kerberos:
1767 if (vol->cred_uid != ses->cred_uid)
1768 continue;
1769 break;
1770 default:
1771 /* anything else takes username/password */
1772 if (strncmp(ses->userName, vol->username,
1773 MAX_USERNAME_SIZE))
1774 continue;
1775 if (strlen(vol->username) != 0 &&
1776 ses->password != NULL &&
1777 strncmp(ses->password,
1778 vol->password ? vol->password : "",
1779 MAX_PASSWORD_SIZE))
1780 continue;
1782 ++ses->ses_count;
1783 spin_unlock(&cifs_tcp_ses_lock);
1784 return ses;
1786 spin_unlock(&cifs_tcp_ses_lock);
1787 return NULL;
1790 static void
1791 cifs_put_smb_ses(struct cifsSesInfo *ses)
1793 int xid;
1794 struct TCP_Server_Info *server = ses->server;
1796 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1797 spin_lock(&cifs_tcp_ses_lock);
1798 if (--ses->ses_count > 0) {
1799 spin_unlock(&cifs_tcp_ses_lock);
1800 return;
1803 list_del_init(&ses->smb_ses_list);
1804 spin_unlock(&cifs_tcp_ses_lock);
1806 if (ses->status == CifsGood) {
1807 xid = GetXid();
1808 CIFSSMBLogoff(xid, ses);
1809 _FreeXid(xid);
1811 sesInfoFree(ses);
1812 cifs_put_tcp_session(server);
1815 static struct cifsSesInfo *
1816 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1818 int rc = -ENOMEM, xid;
1819 struct cifsSesInfo *ses;
1820 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1821 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1823 xid = GetXid();
1825 ses = cifs_find_smb_ses(server, volume_info);
1826 if (ses) {
1827 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1829 mutex_lock(&ses->session_mutex);
1830 rc = cifs_negotiate_protocol(xid, ses);
1831 if (rc) {
1832 mutex_unlock(&ses->session_mutex);
1833 /* problem -- put our ses reference */
1834 cifs_put_smb_ses(ses);
1835 FreeXid(xid);
1836 return ERR_PTR(rc);
1838 if (ses->need_reconnect) {
1839 cFYI(1, "Session needs reconnect");
1840 rc = cifs_setup_session(xid, ses,
1841 volume_info->local_nls);
1842 if (rc) {
1843 mutex_unlock(&ses->session_mutex);
1844 /* problem -- put our reference */
1845 cifs_put_smb_ses(ses);
1846 FreeXid(xid);
1847 return ERR_PTR(rc);
1850 mutex_unlock(&ses->session_mutex);
1852 /* existing SMB ses has a server reference already */
1853 cifs_put_tcp_session(server);
1854 FreeXid(xid);
1855 return ses;
1858 cFYI(1, "Existing smb sess not found");
1859 ses = sesInfoAlloc();
1860 if (ses == NULL)
1861 goto get_ses_fail;
1863 /* new SMB session uses our server ref */
1864 ses->server = server;
1865 if (server->dstaddr.ss_family == AF_INET6)
1866 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1867 else
1868 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1870 if (volume_info->username)
1871 strncpy(ses->userName, volume_info->username,
1872 MAX_USERNAME_SIZE);
1874 /* volume_info->password freed at unmount */
1875 if (volume_info->password) {
1876 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1877 if (!ses->password)
1878 goto get_ses_fail;
1880 if (volume_info->domainname) {
1881 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
1882 if (!ses->domainName)
1883 goto get_ses_fail;
1885 ses->cred_uid = volume_info->cred_uid;
1886 ses->linux_uid = volume_info->linux_uid;
1887 ses->overrideSecFlg = volume_info->secFlg;
1889 mutex_lock(&ses->session_mutex);
1890 rc = cifs_negotiate_protocol(xid, ses);
1891 if (!rc)
1892 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1893 mutex_unlock(&ses->session_mutex);
1894 if (rc)
1895 goto get_ses_fail;
1897 /* success, put it on the list */
1898 spin_lock(&cifs_tcp_ses_lock);
1899 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1900 spin_unlock(&cifs_tcp_ses_lock);
1902 FreeXid(xid);
1903 return ses;
1905 get_ses_fail:
1906 sesInfoFree(ses);
1907 FreeXid(xid);
1908 return ERR_PTR(rc);
1911 static struct cifsTconInfo *
1912 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1914 struct list_head *tmp;
1915 struct cifsTconInfo *tcon;
1917 spin_lock(&cifs_tcp_ses_lock);
1918 list_for_each(tmp, &ses->tcon_list) {
1919 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1920 if (tcon->tidStatus == CifsExiting)
1921 continue;
1922 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1923 continue;
1925 ++tcon->tc_count;
1926 spin_unlock(&cifs_tcp_ses_lock);
1927 return tcon;
1929 spin_unlock(&cifs_tcp_ses_lock);
1930 return NULL;
1933 static void
1934 cifs_put_tcon(struct cifsTconInfo *tcon)
1936 int xid;
1937 struct cifsSesInfo *ses = tcon->ses;
1939 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1940 spin_lock(&cifs_tcp_ses_lock);
1941 if (--tcon->tc_count > 0) {
1942 spin_unlock(&cifs_tcp_ses_lock);
1943 return;
1946 list_del_init(&tcon->tcon_list);
1947 spin_unlock(&cifs_tcp_ses_lock);
1949 xid = GetXid();
1950 CIFSSMBTDis(xid, tcon);
1951 _FreeXid(xid);
1953 cifs_fscache_release_super_cookie(tcon);
1954 tconInfoFree(tcon);
1955 cifs_put_smb_ses(ses);
1958 static struct cifsTconInfo *
1959 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1961 int rc, xid;
1962 struct cifsTconInfo *tcon;
1964 tcon = cifs_find_tcon(ses, volume_info->UNC);
1965 if (tcon) {
1966 cFYI(1, "Found match on UNC path");
1967 /* existing tcon already has a reference */
1968 cifs_put_smb_ses(ses);
1969 if (tcon->seal != volume_info->seal)
1970 cERROR(1, "transport encryption setting "
1971 "conflicts with existing tid");
1972 return tcon;
1975 tcon = tconInfoAlloc();
1976 if (tcon == NULL) {
1977 rc = -ENOMEM;
1978 goto out_fail;
1981 tcon->ses = ses;
1982 if (volume_info->password) {
1983 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1984 if (!tcon->password) {
1985 rc = -ENOMEM;
1986 goto out_fail;
1990 if (strchr(volume_info->UNC + 3, '\\') == NULL
1991 && strchr(volume_info->UNC + 3, '/') == NULL) {
1992 cERROR(1, "Missing share name");
1993 rc = -ENODEV;
1994 goto out_fail;
1997 /* BB Do we need to wrap session_mutex around
1998 * this TCon call and Unix SetFS as
1999 * we do on SessSetup and reconnect? */
2000 xid = GetXid();
2001 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
2002 FreeXid(xid);
2003 cFYI(1, "CIFS Tcon rc = %d", rc);
2004 if (rc)
2005 goto out_fail;
2007 if (volume_info->nodfs) {
2008 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2009 cFYI(1, "DFS disabled (%d)", tcon->Flags);
2011 tcon->seal = volume_info->seal;
2012 /* we can have only one retry value for a connection
2013 to a share so for resources mounted more than once
2014 to the same server share the last value passed in
2015 for the retry flag is used */
2016 tcon->retry = volume_info->retry;
2017 tcon->nocase = volume_info->nocase;
2018 tcon->local_lease = volume_info->local_lease;
2020 spin_lock(&cifs_tcp_ses_lock);
2021 list_add(&tcon->tcon_list, &ses->tcon_list);
2022 spin_unlock(&cifs_tcp_ses_lock);
2024 cifs_fscache_get_super_cookie(tcon);
2026 return tcon;
2028 out_fail:
2029 tconInfoFree(tcon);
2030 return ERR_PTR(rc);
2033 void
2034 cifs_put_tlink(struct tcon_link *tlink)
2036 if (!tlink || IS_ERR(tlink))
2037 return;
2039 if (!atomic_dec_and_test(&tlink->tl_count) ||
2040 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
2041 tlink->tl_time = jiffies;
2042 return;
2045 if (!IS_ERR(tlink_tcon(tlink)))
2046 cifs_put_tcon(tlink_tcon(tlink));
2047 kfree(tlink);
2048 return;
2052 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
2053 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
2054 struct dfs_info3_param **preferrals, int remap)
2056 char *temp_unc;
2057 int rc = 0;
2059 *pnum_referrals = 0;
2060 *preferrals = NULL;
2062 if (pSesInfo->ipc_tid == 0) {
2063 temp_unc = kmalloc(2 /* for slashes */ +
2064 strnlen(pSesInfo->serverName,
2065 SERVER_NAME_LEN_WITH_NULL * 2)
2066 + 1 + 4 /* slash IPC$ */ + 2,
2067 GFP_KERNEL);
2068 if (temp_unc == NULL)
2069 return -ENOMEM;
2070 temp_unc[0] = '\\';
2071 temp_unc[1] = '\\';
2072 strcpy(temp_unc + 2, pSesInfo->serverName);
2073 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
2074 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
2075 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
2076 kfree(temp_unc);
2078 if (rc == 0)
2079 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
2080 pnum_referrals, nls_codepage, remap);
2081 /* BB map targetUNCs to dfs_info3 structures, here or
2082 in CIFSGetDFSRefer BB */
2084 return rc;
2087 #ifdef CONFIG_DEBUG_LOCK_ALLOC
2088 static struct lock_class_key cifs_key[2];
2089 static struct lock_class_key cifs_slock_key[2];
2091 static inline void
2092 cifs_reclassify_socket4(struct socket *sock)
2094 struct sock *sk = sock->sk;
2095 BUG_ON(sock_owned_by_user(sk));
2096 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2097 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2100 static inline void
2101 cifs_reclassify_socket6(struct socket *sock)
2103 struct sock *sk = sock->sk;
2104 BUG_ON(sock_owned_by_user(sk));
2105 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2106 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2108 #else
2109 static inline void
2110 cifs_reclassify_socket4(struct socket *sock)
2114 static inline void
2115 cifs_reclassify_socket6(struct socket *sock)
2118 #endif
2120 /* See RFC1001 section 14 on representation of Netbios names */
2121 static void rfc1002mangle(char *target, char *source, unsigned int length)
2123 unsigned int i, j;
2125 for (i = 0, j = 0; i < (length); i++) {
2126 /* mask a nibble at a time and encode */
2127 target[j] = 'A' + (0x0F & (source[i] >> 4));
2128 target[j+1] = 'A' + (0x0F & source[i]);
2129 j += 2;
2134 static int
2135 bind_socket(struct TCP_Server_Info *server)
2137 int rc = 0;
2138 if (server->srcaddr.ss_family != AF_UNSPEC) {
2139 /* Bind to the specified local IP address */
2140 struct socket *socket = server->ssocket;
2141 rc = socket->ops->bind(socket,
2142 (struct sockaddr *) &server->srcaddr,
2143 sizeof(server->srcaddr));
2144 if (rc < 0) {
2145 struct sockaddr_in *saddr4;
2146 struct sockaddr_in6 *saddr6;
2147 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2148 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2149 if (saddr6->sin6_family == AF_INET6)
2150 cERROR(1, "cifs: "
2151 "Failed to bind to: %pI6c, error: %d\n",
2152 &saddr6->sin6_addr, rc);
2153 else
2154 cERROR(1, "cifs: "
2155 "Failed to bind to: %pI4, error: %d\n",
2156 &saddr4->sin_addr.s_addr, rc);
2159 return rc;
2162 static int
2163 ip_rfc1001_connect(struct TCP_Server_Info *server)
2165 int rc = 0;
2167 * some servers require RFC1001 sessinit before sending
2168 * negprot - BB check reconnection in case where second
2169 * sessinit is sent but no second negprot
2171 struct rfc1002_session_packet *ses_init_buf;
2172 struct smb_hdr *smb_buf;
2173 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2174 GFP_KERNEL);
2175 if (ses_init_buf) {
2176 ses_init_buf->trailer.session_req.called_len = 32;
2178 if (server->server_RFC1001_name &&
2179 server->server_RFC1001_name[0] != 0)
2180 rfc1002mangle(ses_init_buf->trailer.
2181 session_req.called_name,
2182 server->server_RFC1001_name,
2183 RFC1001_NAME_LEN_WITH_NULL);
2184 else
2185 rfc1002mangle(ses_init_buf->trailer.
2186 session_req.called_name,
2187 DEFAULT_CIFS_CALLED_NAME,
2188 RFC1001_NAME_LEN_WITH_NULL);
2190 ses_init_buf->trailer.session_req.calling_len = 32;
2193 * calling name ends in null (byte 16) from old smb
2194 * convention.
2196 if (server->workstation_RFC1001_name &&
2197 server->workstation_RFC1001_name[0] != 0)
2198 rfc1002mangle(ses_init_buf->trailer.
2199 session_req.calling_name,
2200 server->workstation_RFC1001_name,
2201 RFC1001_NAME_LEN_WITH_NULL);
2202 else
2203 rfc1002mangle(ses_init_buf->trailer.
2204 session_req.calling_name,
2205 "LINUX_CIFS_CLNT",
2206 RFC1001_NAME_LEN_WITH_NULL);
2208 ses_init_buf->trailer.session_req.scope1 = 0;
2209 ses_init_buf->trailer.session_req.scope2 = 0;
2210 smb_buf = (struct smb_hdr *)ses_init_buf;
2212 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2213 smb_buf->smb_buf_length = 0x81000044;
2214 rc = smb_send(server, smb_buf, 0x44);
2215 kfree(ses_init_buf);
2217 * RFC1001 layer in at least one server
2218 * requires very short break before negprot
2219 * presumably because not expecting negprot
2220 * to follow so fast. This is a simple
2221 * solution that works without
2222 * complicating the code and causes no
2223 * significant slowing down on mount
2224 * for everyone else
2226 usleep_range(1000, 2000);
2229 * else the negprot may still work without this
2230 * even though malloc failed
2233 return rc;
2236 static int
2237 generic_ip_connect(struct TCP_Server_Info *server)
2239 int rc = 0;
2240 unsigned short int sport;
2241 int slen, sfamily;
2242 struct socket *socket = server->ssocket;
2243 struct sockaddr *saddr;
2245 saddr = (struct sockaddr *) &server->dstaddr;
2247 if (server->dstaddr.ss_family == AF_INET6) {
2248 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2249 slen = sizeof(struct sockaddr_in6);
2250 sfamily = AF_INET6;
2251 } else {
2252 sport = ((struct sockaddr_in *) saddr)->sin_port;
2253 slen = sizeof(struct sockaddr_in);
2254 sfamily = AF_INET;
2257 if (socket == NULL) {
2258 rc = sock_create_kern(sfamily, SOCK_STREAM,
2259 IPPROTO_TCP, &socket);
2260 if (rc < 0) {
2261 cERROR(1, "Error %d creating socket", rc);
2262 server->ssocket = NULL;
2263 return rc;
2266 /* BB other socket options to set KEEPALIVE, NODELAY? */
2267 cFYI(1, "Socket created");
2268 server->ssocket = socket;
2269 socket->sk->sk_allocation = GFP_NOFS;
2270 if (sfamily == AF_INET6)
2271 cifs_reclassify_socket6(socket);
2272 else
2273 cifs_reclassify_socket4(socket);
2276 rc = bind_socket(server);
2277 if (rc < 0)
2278 return rc;
2280 rc = socket->ops->connect(socket, saddr, slen, 0);
2281 if (rc < 0) {
2282 cFYI(1, "Error %d connecting to server", rc);
2283 sock_release(socket);
2284 server->ssocket = NULL;
2285 return rc;
2289 * Eventually check for other socket options to change from
2290 * the default. sock_setsockopt not used because it expects
2291 * user space buffer
2293 socket->sk->sk_rcvtimeo = 7 * HZ;
2294 socket->sk->sk_sndtimeo = 5 * HZ;
2296 /* make the bufsizes depend on wsize/rsize and max requests */
2297 if (server->noautotune) {
2298 if (socket->sk->sk_sndbuf < (200 * 1024))
2299 socket->sk->sk_sndbuf = 200 * 1024;
2300 if (socket->sk->sk_rcvbuf < (140 * 1024))
2301 socket->sk->sk_rcvbuf = 140 * 1024;
2304 if (server->tcp_nodelay) {
2305 int val = 1;
2306 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2307 (char *)&val, sizeof(val));
2308 if (rc)
2309 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2312 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
2313 socket->sk->sk_sndbuf,
2314 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2316 if (sport == htons(RFC1001_PORT))
2317 rc = ip_rfc1001_connect(server);
2319 return rc;
2322 static int
2323 ip_connect(struct TCP_Server_Info *server)
2325 unsigned short int *sport;
2326 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2327 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2329 if (server->dstaddr.ss_family == AF_INET6)
2330 sport = &addr6->sin6_port;
2331 else
2332 sport = &addr->sin_port;
2334 if (*sport == 0) {
2335 int rc;
2337 /* try with 445 port at first */
2338 *sport = htons(CIFS_PORT);
2340 rc = generic_ip_connect(server);
2341 if (rc >= 0)
2342 return rc;
2344 /* if it failed, try with 139 port */
2345 *sport = htons(RFC1001_PORT);
2348 return generic_ip_connect(server);
2351 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2352 struct super_block *sb, struct smb_vol *vol_info)
2354 /* if we are reconnecting then should we check to see if
2355 * any requested capabilities changed locally e.g. via
2356 * remount but we can not do much about it here
2357 * if they have (even if we could detect it by the following)
2358 * Perhaps we could add a backpointer to array of sb from tcon
2359 * or if we change to make all sb to same share the same
2360 * sb as NFS - then we only have one backpointer to sb.
2361 * What if we wanted to mount the server share twice once with
2362 * and once without posixacls or posix paths? */
2363 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2365 if (vol_info && vol_info->no_linux_ext) {
2366 tcon->fsUnixInfo.Capability = 0;
2367 tcon->unix_ext = 0; /* Unix Extensions disabled */
2368 cFYI(1, "Linux protocol extensions disabled");
2369 return;
2370 } else if (vol_info)
2371 tcon->unix_ext = 1; /* Unix Extensions supported */
2373 if (tcon->unix_ext == 0) {
2374 cFYI(1, "Unix extensions disabled so not set on reconnect");
2375 return;
2378 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2379 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2381 /* check for reconnect case in which we do not
2382 want to change the mount behavior if we can avoid it */
2383 if (vol_info == NULL) {
2384 /* turn off POSIX ACL and PATHNAMES if not set
2385 originally at mount time */
2386 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2387 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2388 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2389 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2390 cERROR(1, "POSIXPATH support change");
2391 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2392 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2393 cERROR(1, "possible reconnect error");
2394 cERROR(1, "server disabled POSIX path support");
2398 cap &= CIFS_UNIX_CAP_MASK;
2399 if (vol_info && vol_info->no_psx_acl)
2400 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2401 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2402 cFYI(1, "negotiated posix acl support");
2403 if (sb)
2404 sb->s_flags |= MS_POSIXACL;
2407 if (vol_info && vol_info->posix_paths == 0)
2408 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2409 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2410 cFYI(1, "negotiate posix pathnames");
2411 if (sb)
2412 CIFS_SB(sb)->mnt_cifs_flags |=
2413 CIFS_MOUNT_POSIX_PATHS;
2416 /* We might be setting the path sep back to a different
2417 form if we are reconnecting and the server switched its
2418 posix path capability for this share */
2419 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2420 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2422 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2423 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2424 CIFS_SB(sb)->rsize = 127 * 1024;
2425 cFYI(DBG2, "larger reads not supported by srv");
2430 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2431 #ifdef CONFIG_CIFS_DEBUG2
2432 if (cap & CIFS_UNIX_FCNTL_CAP)
2433 cFYI(1, "FCNTL cap");
2434 if (cap & CIFS_UNIX_EXTATTR_CAP)
2435 cFYI(1, "EXTATTR cap");
2436 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2437 cFYI(1, "POSIX path cap");
2438 if (cap & CIFS_UNIX_XATTR_CAP)
2439 cFYI(1, "XATTR cap");
2440 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2441 cFYI(1, "POSIX ACL cap");
2442 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2443 cFYI(1, "very large read cap");
2444 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2445 cFYI(1, "very large write cap");
2446 #endif /* CIFS_DEBUG2 */
2447 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2448 if (vol_info == NULL) {
2449 cFYI(1, "resetting capabilities failed");
2450 } else
2451 cERROR(1, "Negotiating Unix capabilities "
2452 "with the server failed. Consider "
2453 "mounting with the Unix Extensions\n"
2454 "disabled, if problems are found, "
2455 "by specifying the nounix mount "
2456 "option.");
2462 static void
2463 convert_delimiter(char *path, char delim)
2465 int i;
2466 char old_delim;
2468 if (path == NULL)
2469 return;
2471 if (delim == '/')
2472 old_delim = '\\';
2473 else
2474 old_delim = '/';
2476 for (i = 0; path[i] != '\0'; i++) {
2477 if (path[i] == old_delim)
2478 path[i] = delim;
2482 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2483 struct cifs_sb_info *cifs_sb)
2485 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2487 if (pvolume_info->rsize > CIFSMaxBufSize) {
2488 cERROR(1, "rsize %d too large, using MaxBufSize",
2489 pvolume_info->rsize);
2490 cifs_sb->rsize = CIFSMaxBufSize;
2491 } else if ((pvolume_info->rsize) &&
2492 (pvolume_info->rsize <= CIFSMaxBufSize))
2493 cifs_sb->rsize = pvolume_info->rsize;
2494 else /* default */
2495 cifs_sb->rsize = CIFSMaxBufSize;
2497 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2498 cERROR(1, "wsize %d too large, using 4096 instead",
2499 pvolume_info->wsize);
2500 cifs_sb->wsize = 4096;
2501 } else if (pvolume_info->wsize)
2502 cifs_sb->wsize = pvolume_info->wsize;
2503 else
2504 cifs_sb->wsize = min_t(const int,
2505 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2506 127*1024);
2507 /* old default of CIFSMaxBufSize was too small now
2508 that SMB Write2 can send multiple pages in kvec.
2509 RFC1001 does not describe what happens when frame
2510 bigger than 128K is sent so use that as max in
2511 conjunction with 52K kvec constraint on arch with 4K
2512 page size */
2514 if (cifs_sb->rsize < 2048) {
2515 cifs_sb->rsize = 2048;
2516 /* Windows ME may prefer this */
2517 cFYI(1, "readsize set to minimum: 2048");
2519 /* calculate prepath */
2520 cifs_sb->prepath = pvolume_info->prepath;
2521 if (cifs_sb->prepath) {
2522 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2523 /* we can not convert the / to \ in the path
2524 separators in the prefixpath yet because we do not
2525 know (until reset_cifs_unix_caps is called later)
2526 whether POSIX PATH CAP is available. We normalize
2527 the / to \ after reset_cifs_unix_caps is called */
2528 pvolume_info->prepath = NULL;
2529 } else
2530 cifs_sb->prepathlen = 0;
2531 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2532 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2533 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2534 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2535 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2536 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2538 cifs_sb->actimeo = pvolume_info->actimeo;
2540 if (pvolume_info->noperm)
2541 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2542 if (pvolume_info->setuids)
2543 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2544 if (pvolume_info->server_ino)
2545 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2546 if (pvolume_info->remap)
2547 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2548 if (pvolume_info->no_xattr)
2549 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2550 if (pvolume_info->sfu_emul)
2551 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2552 if (pvolume_info->nobrl)
2553 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2554 if (pvolume_info->nostrictsync)
2555 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2556 if (pvolume_info->mand_lock)
2557 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2558 if (pvolume_info->cifs_acl)
2559 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2560 if (pvolume_info->override_uid)
2561 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2562 if (pvolume_info->override_gid)
2563 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2564 if (pvolume_info->dynperm)
2565 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2566 if (pvolume_info->fsc)
2567 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2568 if (pvolume_info->multiuser)
2569 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2570 CIFS_MOUNT_NO_PERM);
2571 if (pvolume_info->direct_io) {
2572 cFYI(1, "mounting share using direct i/o");
2573 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2575 if (pvolume_info->mfsymlinks) {
2576 if (pvolume_info->sfu_emul) {
2577 cERROR(1, "mount option mfsymlinks ignored if sfu "
2578 "mount option is used");
2579 } else {
2580 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2584 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2585 cERROR(1, "mount option dynperm ignored if cifsacl "
2586 "mount option supported");
2589 static int
2590 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2591 struct cifs_sb_info *cifs_sb, const char *full_path)
2593 int rc;
2594 FILE_ALL_INFO *pfile_info;
2596 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2597 if (pfile_info == NULL)
2598 return -ENOMEM;
2600 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2601 0 /* not legacy */, cifs_sb->local_nls,
2602 cifs_sb->mnt_cifs_flags &
2603 CIFS_MOUNT_MAP_SPECIAL_CHR);
2604 kfree(pfile_info);
2605 return rc;
2608 static void
2609 cleanup_volume_info(struct smb_vol **pvolume_info)
2611 struct smb_vol *volume_info;
2613 if (!pvolume_info || !*pvolume_info)
2614 return;
2616 volume_info = *pvolume_info;
2617 kzfree(volume_info->password);
2618 kfree(volume_info->UNC);
2619 kfree(volume_info->prepath);
2620 kfree(volume_info);
2621 *pvolume_info = NULL;
2622 return;
2625 #ifdef CONFIG_CIFS_DFS_UPCALL
2626 /* build_path_to_root returns full path to root when
2627 * we do not have an exiting connection (tcon) */
2628 static char *
2629 build_unc_path_to_root(const struct smb_vol *volume_info,
2630 const struct cifs_sb_info *cifs_sb)
2632 char *full_path;
2634 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2635 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2636 if (full_path == NULL)
2637 return ERR_PTR(-ENOMEM);
2639 strncpy(full_path, volume_info->UNC, unc_len);
2640 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2641 int i;
2642 for (i = 0; i < unc_len; i++) {
2643 if (full_path[i] == '\\')
2644 full_path[i] = '/';
2648 if (cifs_sb->prepathlen)
2649 strncpy(full_path + unc_len, cifs_sb->prepath,
2650 cifs_sb->prepathlen);
2652 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2653 return full_path;
2655 #endif
2658 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2659 char *mount_data_global, const char *devname)
2661 int rc;
2662 int xid;
2663 struct smb_vol *volume_info;
2664 struct cifsSesInfo *pSesInfo;
2665 struct cifsTconInfo *tcon;
2666 struct TCP_Server_Info *srvTcp;
2667 char *full_path;
2668 char *mount_data = mount_data_global;
2669 struct tcon_link *tlink;
2670 #ifdef CONFIG_CIFS_DFS_UPCALL
2671 struct dfs_info3_param *referrals = NULL;
2672 unsigned int num_referrals = 0;
2673 int referral_walks_count = 0;
2674 try_mount_again:
2675 #endif
2676 rc = 0;
2677 tcon = NULL;
2678 pSesInfo = NULL;
2679 srvTcp = NULL;
2680 full_path = NULL;
2681 tlink = NULL;
2683 xid = GetXid();
2685 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2686 if (!volume_info) {
2687 rc = -ENOMEM;
2688 goto out;
2691 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2692 rc = -EINVAL;
2693 goto out;
2696 if (volume_info->nullauth) {
2697 cFYI(1, "null user");
2698 volume_info->username = "";
2699 } else if (volume_info->username) {
2700 /* BB fixme parse for domain name here */
2701 cFYI(1, "Username: %s", volume_info->username);
2702 } else {
2703 cifserror("No username specified");
2704 /* In userspace mount helper we can get user name from alternate
2705 locations such as env variables and files on disk */
2706 rc = -EINVAL;
2707 goto out;
2710 /* this is needed for ASCII cp to Unicode converts */
2711 if (volume_info->iocharset == NULL) {
2712 /* load_nls_default cannot return null */
2713 volume_info->local_nls = load_nls_default();
2714 } else {
2715 volume_info->local_nls = load_nls(volume_info->iocharset);
2716 if (volume_info->local_nls == NULL) {
2717 cERROR(1, "CIFS mount error: iocharset %s not found",
2718 volume_info->iocharset);
2719 rc = -ELIBACC;
2720 goto out;
2723 cifs_sb->local_nls = volume_info->local_nls;
2725 /* get a reference to a tcp session */
2726 srvTcp = cifs_get_tcp_session(volume_info);
2727 if (IS_ERR(srvTcp)) {
2728 rc = PTR_ERR(srvTcp);
2729 goto out;
2732 /* get a reference to a SMB session */
2733 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2734 if (IS_ERR(pSesInfo)) {
2735 rc = PTR_ERR(pSesInfo);
2736 pSesInfo = NULL;
2737 goto mount_fail_check;
2740 setup_cifs_sb(volume_info, cifs_sb);
2741 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2742 sb->s_maxbytes = MAX_LFS_FILESIZE;
2743 else
2744 sb->s_maxbytes = MAX_NON_LFS;
2746 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2747 sb->s_time_gran = 100;
2749 /* search for existing tcon to this server share */
2750 tcon = cifs_get_tcon(pSesInfo, volume_info);
2751 if (IS_ERR(tcon)) {
2752 rc = PTR_ERR(tcon);
2753 tcon = NULL;
2754 goto remote_path_check;
2757 /* do not care if following two calls succeed - informational */
2758 if (!tcon->ipc) {
2759 CIFSSMBQFSDeviceInfo(xid, tcon);
2760 CIFSSMBQFSAttributeInfo(xid, tcon);
2763 /* tell server which Unix caps we support */
2764 if (tcon->ses->capabilities & CAP_UNIX)
2765 /* reset of caps checks mount to see if unix extensions
2766 disabled for just this mount */
2767 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2768 else
2769 tcon->unix_ext = 0; /* server does not support them */
2771 /* convert forward to back slashes in prepath here if needed */
2772 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2773 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2775 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2776 cifs_sb->rsize = 1024 * 127;
2777 cFYI(DBG2, "no very large read support, rsize now 127K");
2779 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2780 cifs_sb->wsize = min(cifs_sb->wsize,
2781 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2782 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2783 cifs_sb->rsize = min(cifs_sb->rsize,
2784 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2786 remote_path_check:
2787 /* check if a whole path (including prepath) is not remote */
2788 if (!rc && cifs_sb->prepathlen && tcon) {
2789 /* build_path_to_root works only when we have a valid tcon */
2790 full_path = cifs_build_path_to_root(cifs_sb, tcon);
2791 if (full_path == NULL) {
2792 rc = -ENOMEM;
2793 goto mount_fail_check;
2795 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2796 if (rc != 0 && rc != -EREMOTE) {
2797 kfree(full_path);
2798 goto mount_fail_check;
2800 kfree(full_path);
2803 /* get referral if needed */
2804 if (rc == -EREMOTE) {
2805 #ifdef CONFIG_CIFS_DFS_UPCALL
2806 if (referral_walks_count > MAX_NESTED_LINKS) {
2808 * BB: when we implement proper loop detection,
2809 * we will remove this check. But now we need it
2810 * to prevent an indefinite loop if 'DFS tree' is
2811 * misconfigured (i.e. has loops).
2813 rc = -ELOOP;
2814 goto mount_fail_check;
2816 /* convert forward to back slashes in prepath here if needed */
2817 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2818 convert_delimiter(cifs_sb->prepath,
2819 CIFS_DIR_SEP(cifs_sb));
2820 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2821 if (IS_ERR(full_path)) {
2822 rc = PTR_ERR(full_path);
2823 goto mount_fail_check;
2826 cFYI(1, "Getting referral for: %s", full_path);
2827 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2828 cifs_sb->local_nls, &num_referrals, &referrals,
2829 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2830 if (!rc && num_referrals > 0) {
2831 char *fake_devname = NULL;
2833 if (mount_data != mount_data_global)
2834 kfree(mount_data);
2836 mount_data = cifs_compose_mount_options(
2837 cifs_sb->mountdata, full_path + 1,
2838 referrals, &fake_devname);
2840 free_dfs_info_array(referrals, num_referrals);
2841 kfree(fake_devname);
2842 kfree(full_path);
2844 if (IS_ERR(mount_data)) {
2845 rc = PTR_ERR(mount_data);
2846 mount_data = NULL;
2847 goto mount_fail_check;
2850 if (tcon)
2851 cifs_put_tcon(tcon);
2852 else if (pSesInfo)
2853 cifs_put_smb_ses(pSesInfo);
2855 cleanup_volume_info(&volume_info);
2856 referral_walks_count++;
2857 FreeXid(xid);
2858 goto try_mount_again;
2860 #else /* No DFS support, return error on mount */
2861 rc = -EOPNOTSUPP;
2862 #endif
2865 if (rc)
2866 goto mount_fail_check;
2868 /* now, hang the tcon off of the superblock */
2869 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2870 if (tlink == NULL) {
2871 rc = -ENOMEM;
2872 goto mount_fail_check;
2875 tlink->tl_uid = pSesInfo->linux_uid;
2876 tlink->tl_tcon = tcon;
2877 tlink->tl_time = jiffies;
2878 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2879 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2881 cifs_sb->master_tlink = tlink;
2882 spin_lock(&cifs_sb->tlink_tree_lock);
2883 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
2884 spin_unlock(&cifs_sb->tlink_tree_lock);
2886 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
2887 TLINK_IDLE_EXPIRE);
2889 mount_fail_check:
2890 /* on error free sesinfo and tcon struct if needed */
2891 if (rc) {
2892 if (mount_data != mount_data_global)
2893 kfree(mount_data);
2894 /* If find_unc succeeded then rc == 0 so we can not end */
2895 /* up accidently freeing someone elses tcon struct */
2896 if (tcon)
2897 cifs_put_tcon(tcon);
2898 else if (pSesInfo)
2899 cifs_put_smb_ses(pSesInfo);
2900 else
2901 cifs_put_tcp_session(srvTcp);
2902 goto out;
2905 /* volume_info->password is freed above when existing session found
2906 (in which case it is not needed anymore) but when new sesion is created
2907 the password ptr is put in the new session structure (in which case the
2908 password will be freed at unmount time) */
2909 out:
2910 /* zero out password before freeing */
2911 cleanup_volume_info(&volume_info);
2912 FreeXid(xid);
2913 return rc;
2917 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2918 const char *tree, struct cifsTconInfo *tcon,
2919 const struct nls_table *nls_codepage)
2921 struct smb_hdr *smb_buffer;
2922 struct smb_hdr *smb_buffer_response;
2923 TCONX_REQ *pSMB;
2924 TCONX_RSP *pSMBr;
2925 unsigned char *bcc_ptr;
2926 int rc = 0;
2927 int length, bytes_left;
2928 __u16 count;
2930 if (ses == NULL)
2931 return -EIO;
2933 smb_buffer = cifs_buf_get();
2934 if (smb_buffer == NULL)
2935 return -ENOMEM;
2937 smb_buffer_response = smb_buffer;
2939 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2940 NULL /*no tid */ , 4 /*wct */ );
2942 smb_buffer->Mid = GetNextMid(ses->server);
2943 smb_buffer->Uid = ses->Suid;
2944 pSMB = (TCONX_REQ *) smb_buffer;
2945 pSMBr = (TCONX_RSP *) smb_buffer_response;
2947 pSMB->AndXCommand = 0xFF;
2948 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
2949 bcc_ptr = &pSMB->Password[0];
2950 if ((ses->server->secMode) & SECMODE_USER) {
2951 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
2952 *bcc_ptr = 0; /* password is null byte */
2953 bcc_ptr++; /* skip password */
2954 /* already aligned so no need to do it below */
2955 } else {
2956 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
2957 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2958 specified as required (when that support is added to
2959 the vfs in the future) as only NTLM or the much
2960 weaker LANMAN (which we do not send by default) is accepted
2961 by Samba (not sure whether other servers allow
2962 NTLMv2 password here) */
2963 #ifdef CONFIG_CIFS_WEAK_PW_HASH
2964 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2965 (ses->server->secType == LANMAN))
2966 calc_lanman_hash(tcon->password, ses->server->cryptkey,
2967 ses->server->secMode &
2968 SECMODE_PW_ENCRYPT ? true : false,
2969 bcc_ptr);
2970 else
2971 #endif /* CIFS_WEAK_PW_HASH */
2972 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
2974 bcc_ptr += CIFS_AUTH_RESP_SIZE;
2975 if (ses->capabilities & CAP_UNICODE) {
2976 /* must align unicode strings */
2977 *bcc_ptr = 0; /* null byte password */
2978 bcc_ptr++;
2982 if (ses->server->secMode &
2983 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2984 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2986 if (ses->capabilities & CAP_STATUS32) {
2987 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2989 if (ses->capabilities & CAP_DFS) {
2990 smb_buffer->Flags2 |= SMBFLG2_DFS;
2992 if (ses->capabilities & CAP_UNICODE) {
2993 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2994 length =
2995 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
2996 6 /* max utf8 char length in bytes */ *
2997 (/* server len*/ + 256 /* share len */), nls_codepage);
2998 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
2999 bcc_ptr += 2; /* skip trailing null */
3000 } else { /* ASCII */
3001 strcpy(bcc_ptr, tree);
3002 bcc_ptr += strlen(tree) + 1;
3004 strcpy(bcc_ptr, "?????");
3005 bcc_ptr += strlen("?????");
3006 bcc_ptr += 1;
3007 count = bcc_ptr - &pSMB->Password[0];
3008 pSMB->hdr.smb_buf_length += count;
3009 pSMB->ByteCount = cpu_to_le16(count);
3011 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3012 CIFS_STD_OP);
3014 /* above now done in SendReceive */
3015 if ((rc == 0) && (tcon != NULL)) {
3016 bool is_unicode;
3018 tcon->tidStatus = CifsGood;
3019 tcon->need_reconnect = false;
3020 tcon->tid = smb_buffer_response->Tid;
3021 bcc_ptr = pByteArea(smb_buffer_response);
3022 bytes_left = BCC(smb_buffer_response);
3023 length = strnlen(bcc_ptr, bytes_left - 2);
3024 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3025 is_unicode = true;
3026 else
3027 is_unicode = false;
3030 /* skip service field (NB: this field is always ASCII) */
3031 if (length == 3) {
3032 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3033 (bcc_ptr[2] == 'C')) {
3034 cFYI(1, "IPC connection");
3035 tcon->ipc = 1;
3037 } else if (length == 2) {
3038 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3039 /* the most common case */
3040 cFYI(1, "disk share connection");
3043 bcc_ptr += length + 1;
3044 bytes_left -= (length + 1);
3045 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3047 /* mostly informational -- no need to fail on error here */
3048 kfree(tcon->nativeFileSystem);
3049 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3050 bytes_left, is_unicode,
3051 nls_codepage);
3053 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
3055 if ((smb_buffer_response->WordCount == 3) ||
3056 (smb_buffer_response->WordCount == 7))
3057 /* field is in same location */
3058 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3059 else
3060 tcon->Flags = 0;
3061 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
3062 } else if ((rc == 0) && tcon == NULL) {
3063 /* all we need to save for IPC$ connection */
3064 ses->ipc_tid = smb_buffer_response->Tid;
3067 cifs_buf_release(smb_buffer);
3068 return rc;
3072 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3074 struct rb_root *root = &cifs_sb->tlink_tree;
3075 struct rb_node *node;
3076 struct tcon_link *tlink;
3077 char *tmp;
3079 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3081 spin_lock(&cifs_sb->tlink_tree_lock);
3082 while ((node = rb_first(root))) {
3083 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3084 cifs_get_tlink(tlink);
3085 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3086 rb_erase(node, root);
3088 spin_unlock(&cifs_sb->tlink_tree_lock);
3089 cifs_put_tlink(tlink);
3090 spin_lock(&cifs_sb->tlink_tree_lock);
3092 spin_unlock(&cifs_sb->tlink_tree_lock);
3094 tmp = cifs_sb->prepath;
3095 cifs_sb->prepathlen = 0;
3096 cifs_sb->prepath = NULL;
3097 kfree(tmp);
3099 return 0;
3102 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3104 int rc = 0;
3105 struct TCP_Server_Info *server = ses->server;
3107 /* only send once per connect */
3108 if (server->maxBuf != 0)
3109 return 0;
3111 rc = CIFSSMBNegotiate(xid, ses);
3112 if (rc == -EAGAIN) {
3113 /* retry only once on 1st time connection */
3114 rc = CIFSSMBNegotiate(xid, ses);
3115 if (rc == -EAGAIN)
3116 rc = -EHOSTDOWN;
3118 if (rc == 0) {
3119 spin_lock(&GlobalMid_Lock);
3120 if (server->tcpStatus != CifsExiting)
3121 server->tcpStatus = CifsGood;
3122 else
3123 rc = -EHOSTDOWN;
3124 spin_unlock(&GlobalMid_Lock);
3128 return rc;
3132 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3133 struct nls_table *nls_info)
3135 int rc = 0;
3136 struct TCP_Server_Info *server = ses->server;
3138 ses->flags = 0;
3139 ses->capabilities = server->capabilities;
3140 if (linuxExtEnabled == 0)
3141 ses->capabilities &= (~CAP_UNIX);
3143 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3144 server->secMode, server->capabilities, server->timeAdj);
3146 rc = CIFS_SessSetup(xid, ses, nls_info);
3147 if (rc) {
3148 cERROR(1, "Send error in SessSetup = %d", rc);
3149 } else {
3150 mutex_lock(&ses->server->srv_mutex);
3151 if (!server->session_estab) {
3152 server->session_key.response = ses->auth_key.response;
3153 server->session_key.len = ses->auth_key.len;
3154 server->sequence_number = 0x2;
3155 server->session_estab = true;
3156 ses->auth_key.response = NULL;
3158 mutex_unlock(&server->srv_mutex);
3160 cFYI(1, "CIFS Session Established successfully");
3161 spin_lock(&GlobalMid_Lock);
3162 ses->status = CifsGood;
3163 ses->need_reconnect = false;
3164 spin_unlock(&GlobalMid_Lock);
3167 kfree(ses->auth_key.response);
3168 ses->auth_key.response = NULL;
3169 ses->auth_key.len = 0;
3170 kfree(ses->ntlmssp);
3171 ses->ntlmssp = NULL;
3173 return rc;
3176 static struct cifsTconInfo *
3177 cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3179 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3180 struct cifsSesInfo *ses;
3181 struct cifsTconInfo *tcon = NULL;
3182 struct smb_vol *vol_info;
3183 char username[MAX_USERNAME_SIZE + 1];
3185 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3186 if (vol_info == NULL) {
3187 tcon = ERR_PTR(-ENOMEM);
3188 goto out;
3191 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3192 vol_info->username = username;
3193 vol_info->local_nls = cifs_sb->local_nls;
3194 vol_info->linux_uid = fsuid;
3195 vol_info->cred_uid = fsuid;
3196 vol_info->UNC = master_tcon->treeName;
3197 vol_info->retry = master_tcon->retry;
3198 vol_info->nocase = master_tcon->nocase;
3199 vol_info->local_lease = master_tcon->local_lease;
3200 vol_info->no_linux_ext = !master_tcon->unix_ext;
3202 /* FIXME: allow for other secFlg settings */
3203 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3205 /* get a reference for the same TCP session */
3206 spin_lock(&cifs_tcp_ses_lock);
3207 ++master_tcon->ses->server->srv_count;
3208 spin_unlock(&cifs_tcp_ses_lock);
3210 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3211 if (IS_ERR(ses)) {
3212 tcon = (struct cifsTconInfo *)ses;
3213 cifs_put_tcp_session(master_tcon->ses->server);
3214 goto out;
3217 tcon = cifs_get_tcon(ses, vol_info);
3218 if (IS_ERR(tcon)) {
3219 cifs_put_smb_ses(ses);
3220 goto out;
3223 if (ses->capabilities & CAP_UNIX)
3224 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3225 out:
3226 kfree(vol_info);
3228 return tcon;
3231 static inline struct tcon_link *
3232 cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3234 return cifs_sb->master_tlink;
3237 struct cifsTconInfo *
3238 cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3240 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3243 static int
3244 cifs_sb_tcon_pending_wait(void *unused)
3246 schedule();
3247 return signal_pending(current) ? -ERESTARTSYS : 0;
3250 /* find and return a tlink with given uid */
3251 static struct tcon_link *
3252 tlink_rb_search(struct rb_root *root, uid_t uid)
3254 struct rb_node *node = root->rb_node;
3255 struct tcon_link *tlink;
3257 while (node) {
3258 tlink = rb_entry(node, struct tcon_link, tl_rbnode);
3260 if (tlink->tl_uid > uid)
3261 node = node->rb_left;
3262 else if (tlink->tl_uid < uid)
3263 node = node->rb_right;
3264 else
3265 return tlink;
3267 return NULL;
3270 /* insert a tcon_link into the tree */
3271 static void
3272 tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
3274 struct rb_node **new = &(root->rb_node), *parent = NULL;
3275 struct tcon_link *tlink;
3277 while (*new) {
3278 tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
3279 parent = *new;
3281 if (tlink->tl_uid > new_tlink->tl_uid)
3282 new = &((*new)->rb_left);
3283 else
3284 new = &((*new)->rb_right);
3287 rb_link_node(&new_tlink->tl_rbnode, parent, new);
3288 rb_insert_color(&new_tlink->tl_rbnode, root);
3292 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3293 * current task.
3295 * If the superblock doesn't refer to a multiuser mount, then just return
3296 * the master tcon for the mount.
3298 * First, search the rbtree for an existing tcon for this fsuid. If one
3299 * exists, then check to see if it's pending construction. If it is then wait
3300 * for construction to complete. Once it's no longer pending, check to see if
3301 * it failed and either return an error or retry construction, depending on
3302 * the timeout.
3304 * If one doesn't exist then insert a new tcon_link struct into the tree and
3305 * try to construct a new one.
3307 struct tcon_link *
3308 cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3310 int ret;
3311 uid_t fsuid = current_fsuid();
3312 struct tcon_link *tlink, *newtlink;
3314 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3315 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3317 spin_lock(&cifs_sb->tlink_tree_lock);
3318 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3319 if (tlink)
3320 cifs_get_tlink(tlink);
3321 spin_unlock(&cifs_sb->tlink_tree_lock);
3323 if (tlink == NULL) {
3324 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3325 if (newtlink == NULL)
3326 return ERR_PTR(-ENOMEM);
3327 newtlink->tl_uid = fsuid;
3328 newtlink->tl_tcon = ERR_PTR(-EACCES);
3329 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3330 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3331 cifs_get_tlink(newtlink);
3333 spin_lock(&cifs_sb->tlink_tree_lock);
3334 /* was one inserted after previous search? */
3335 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
3336 if (tlink) {
3337 cifs_get_tlink(tlink);
3338 spin_unlock(&cifs_sb->tlink_tree_lock);
3339 kfree(newtlink);
3340 goto wait_for_construction;
3342 tlink = newtlink;
3343 tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
3344 spin_unlock(&cifs_sb->tlink_tree_lock);
3345 } else {
3346 wait_for_construction:
3347 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3348 cifs_sb_tcon_pending_wait,
3349 TASK_INTERRUPTIBLE);
3350 if (ret) {
3351 cifs_put_tlink(tlink);
3352 return ERR_PTR(ret);
3355 /* if it's good, return it */
3356 if (!IS_ERR(tlink->tl_tcon))
3357 return tlink;
3359 /* return error if we tried this already recently */
3360 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3361 cifs_put_tlink(tlink);
3362 return ERR_PTR(-EACCES);
3365 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3366 goto wait_for_construction;
3369 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3370 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3371 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3373 if (IS_ERR(tlink->tl_tcon)) {
3374 cifs_put_tlink(tlink);
3375 return ERR_PTR(-EACCES);
3378 return tlink;
3382 * periodic workqueue job that scans tcon_tree for a superblock and closes
3383 * out tcons.
3385 static void
3386 cifs_prune_tlinks(struct work_struct *work)
3388 struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
3389 prune_tlinks.work);
3390 struct rb_root *root = &cifs_sb->tlink_tree;
3391 struct rb_node *node = rb_first(root);
3392 struct rb_node *tmp;
3393 struct tcon_link *tlink;
3396 * Because we drop the spinlock in the loop in order to put the tlink
3397 * it's not guarded against removal of links from the tree. The only
3398 * places that remove entries from the tree are this function and
3399 * umounts. Because this function is non-reentrant and is canceled
3400 * before umount can proceed, this is safe.
3402 spin_lock(&cifs_sb->tlink_tree_lock);
3403 node = rb_first(root);
3404 while (node != NULL) {
3405 tmp = node;
3406 node = rb_next(tmp);
3407 tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
3409 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
3410 atomic_read(&tlink->tl_count) != 0 ||
3411 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
3412 continue;
3414 cifs_get_tlink(tlink);
3415 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
3416 rb_erase(tmp, root);
3418 spin_unlock(&cifs_sb->tlink_tree_lock);
3419 cifs_put_tlink(tlink);
3420 spin_lock(&cifs_sb->tlink_tree_lock);
3422 spin_unlock(&cifs_sb->tlink_tree_lock);
3424 queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks,
3425 TLINK_IDLE_EXPIRE);