Lines Matching +full:tcon +full:- +full:top
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44 #include <keys/user-type.h>
293 * This should be called with server->srv_mutex held.
302 if (!server->hostname) in reconn_set_ipaddr()
303 return -EINVAL; in reconn_set_ipaddr()
305 len = strlen(server->hostname) + 3; in reconn_set_ipaddr()
310 return -ENOMEM; in reconn_set_ipaddr()
312 scnprintf(unc, len, "\\\\%s", server->hostname); in reconn_set_ipaddr()
319 __func__, server->hostname, rc); in reconn_set_ipaddr()
324 rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr, in reconn_set_ipaddr()
329 return !rc ? -1 : 0; in reconn_set_ipaddr()
339 /* These functions must be called with server->srv_mutex held */
347 if (!cifs_sb || !cifs_sb->origin_fullpath) in reconn_set_next_dfs_target()
358 cifs_dbg(FYI, "%s: UNC: %s\n", __func__, cifs_sb->origin_fullpath); in reconn_set_next_dfs_target()
362 kfree(server->hostname); in reconn_set_next_dfs_target()
364 server->hostname = extract_hostname(name); in reconn_set_next_dfs_target()
365 if (IS_ERR(server->hostname)) { in reconn_set_next_dfs_target()
368 __func__, PTR_ERR(server->hostname)); in reconn_set_next_dfs_target()
375 if (!cifs_sb->origin_fullpath) in reconn_setup_dfs_targets()
376 return -EOPNOTSUPP; in reconn_setup_dfs_targets()
377 return dfs_cache_noreq_find(cifs_sb->origin_fullpath + 1, NULL, tl); in reconn_setup_dfs_targets()
387 * wake up waiters on reconnection? - (not needed currently)
395 struct cifs_tcon *tcon; in cifs_reconnect() local
406 server->nr_targets = 1; in cifs_reconnect()
420 if (rc != -EOPNOTSUPP) { in cifs_reconnect()
425 server->nr_targets = dfs_cache_get_nr_tgts(&tgt_list); in cifs_reconnect()
429 server->nr_targets); in cifs_reconnect()
432 if (server->tcpStatus == CifsExiting) { in cifs_reconnect()
440 wake_up(&server->response_q); in cifs_reconnect()
443 server->tcpStatus = CifsNeedReconnect; in cifs_reconnect()
445 server->maxBuf = 0; in cifs_reconnect()
446 server->max_read = 0; in cifs_reconnect()
449 trace_smb3_reconnect(server->CurrentMid, server->hostname); in cifs_reconnect()
456 list_for_each(tmp, &server->smb_ses_list) { in cifs_reconnect()
458 ses->need_reconnect = true; in cifs_reconnect()
459 list_for_each(tmp2, &ses->tcon_list) { in cifs_reconnect()
460 tcon = list_entry(tmp2, struct cifs_tcon, tcon_list); in cifs_reconnect()
461 tcon->need_reconnect = true; in cifs_reconnect()
463 if (ses->tcon_ipc) in cifs_reconnect()
464 ses->tcon_ipc->need_reconnect = true; in cifs_reconnect()
470 mutex_lock(&server->srv_mutex); in cifs_reconnect()
471 if (server->ssocket) { in cifs_reconnect()
473 server->ssocket->state, server->ssocket->flags); in cifs_reconnect()
474 kernel_sock_shutdown(server->ssocket, SHUT_WR); in cifs_reconnect()
476 server->ssocket->state, server->ssocket->flags); in cifs_reconnect()
477 sock_release(server->ssocket); in cifs_reconnect()
478 server->ssocket = NULL; in cifs_reconnect()
480 server->sequence_number = 0; in cifs_reconnect()
481 server->session_estab = false; in cifs_reconnect()
482 kfree(server->session_key.response); in cifs_reconnect()
483 server->session_key.response = NULL; in cifs_reconnect()
484 server->session_key.len = 0; in cifs_reconnect()
485 server->lstrp = jiffies; in cifs_reconnect()
491 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { in cifs_reconnect()
493 kref_get(&mid_entry->refcount); in cifs_reconnect()
494 if (mid_entry->mid_state == MID_REQUEST_SUBMITTED) in cifs_reconnect()
495 mid_entry->mid_state = MID_RETRY_NEEDED; in cifs_reconnect()
496 list_move(&mid_entry->qhead, &retry_list); in cifs_reconnect()
497 mid_entry->mid_flags |= MID_DELETED; in cifs_reconnect()
500 mutex_unlock(&server->srv_mutex); in cifs_reconnect()
505 list_del_init(&mid_entry->qhead); in cifs_reconnect()
506 mid_entry->callback(mid_entry); in cifs_reconnect()
511 mutex_lock(&server->srv_mutex); in cifs_reconnect()
513 mutex_unlock(&server->srv_mutex); in cifs_reconnect()
519 mutex_lock(&server->srv_mutex); in cifs_reconnect()
540 mutex_unlock(&server->srv_mutex); in cifs_reconnect()
546 if (server->tcpStatus != CifsExiting) in cifs_reconnect()
547 server->tcpStatus = CifsNeedNegotiate; in cifs_reconnect()
549 mutex_unlock(&server->srv_mutex); in cifs_reconnect()
551 } while (server->tcpStatus == CifsNeedReconnect); in cifs_reconnect()
555 rc = dfs_cache_noreq_update_tgthint(cifs_sb->origin_fullpath + 1, in cifs_reconnect()
561 rc = dfs_cache_update_vol(cifs_sb->origin_fullpath, server); in cifs_reconnect()
572 if (server->tcpStatus == CifsNeedNegotiate) in cifs_reconnect()
573 mod_delayed_work(cifsiod_wq, &server->echo, 0); in cifs_reconnect()
575 wake_up(&server->response_q); in cifs_reconnect()
591 if (server->tcpStatus == CifsNeedNegotiate) in cifs_echo_request()
594 echo_interval = server->echo_interval; in cifs_echo_request()
601 if (server->tcpStatus == CifsNeedReconnect || in cifs_echo_request()
602 server->tcpStatus == CifsExiting || in cifs_echo_request()
603 server->tcpStatus == CifsNew || in cifs_echo_request()
604 (server->ops->can_echo && !server->ops->can_echo(server)) || in cifs_echo_request()
605 time_before(jiffies, server->lstrp + echo_interval - HZ)) in cifs_echo_request()
608 rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS; in cifs_echo_request()
611 server->hostname); in cifs_echo_request()
614 queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval); in cifs_echo_request()
620 if (!server->bigbuf) { in allocate_buffers()
621 server->bigbuf = (char *)cifs_buf_get(); in allocate_buffers()
622 if (!server->bigbuf) { in allocate_buffers()
628 } else if (server->large_buf) { in allocate_buffers()
630 memset(server->bigbuf, 0, HEADER_SIZE(server)); in allocate_buffers()
633 if (!server->smallbuf) { in allocate_buffers()
634 server->smallbuf = (char *)cifs_small_buf_get(); in allocate_buffers()
635 if (!server->smallbuf) { in allocate_buffers()
644 memset(server->smallbuf, 0, HEADER_SIZE(server)); in allocate_buffers()
664 if ((server->tcpStatus == CifsGood || in server_unresponsive()
665 server->tcpStatus == CifsNeedNegotiate) && in server_unresponsive()
666 (!server->ops->can_echo || server->ops->can_echo(server)) && in server_unresponsive()
667 time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { in server_unresponsive()
669 (3 * server->echo_interval) / HZ); in server_unresponsive()
682 spin_lock(&server->req_lock); in zero_credits()
683 val = server->credits + server->echo_credits + server->oplock_credits; in zero_credits()
684 if (server->in_flight == 0 && val == 0) { in zero_credits()
685 spin_unlock(&server->req_lock); in zero_credits()
688 spin_unlock(&server->req_lock); in zero_credits()
704 return -ECONNABORTED; in cifs_readv_from_socket()
708 return -ECONNABORTED; in cifs_readv_from_socket()
709 if (cifs_rdma_enabled(server) && server->smbd_conn) in cifs_readv_from_socket()
710 length = smbd_recv(server->smbd_conn, smb_msg); in cifs_readv_from_socket()
712 length = sock_recvmsg(server->ssocket, smb_msg, 0); in cifs_readv_from_socket()
714 if (server->tcpStatus == CifsExiting) in cifs_readv_from_socket()
715 return -ESHUTDOWN; in cifs_readv_from_socket()
717 if (server->tcpStatus == CifsNeedReconnect) { in cifs_readv_from_socket()
719 return -ECONNABORTED; in cifs_readv_from_socket()
722 if (length == -ERESTARTSYS || in cifs_readv_from_socket()
723 length == -EAGAIN || in cifs_readv_from_socket()
724 length == -EINTR) { in cifs_readv_from_socket()
738 return -ECONNABORTED; in cifs_readv_from_socket()
813 cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT); in is_smb_response()
828 mid->when_received = jiffies; in dequeue_mid()
832 mid->mid_state = MID_RESPONSE_RECEIVED; in dequeue_mid()
834 mid->mid_state = MID_RESPONSE_MALFORMED; in dequeue_mid()
839 if (mid->mid_flags & MID_DELETED) in dequeue_mid()
842 list_del_init(&mid->qhead); in dequeue_mid()
843 mid->mid_flags |= MID_DELETED; in dequeue_mid()
856 if (server->vals->header_preamble_size) in smb2_get_credits_from_hdr()
859 return le16_to_cpu(shdr->CreditRequest); in smb2_get_credits_from_hdr()
866 if (server->ops->check_trans2 && in handle_mid()
867 server->ops->check_trans2(mid, server, buf, malformed)) in handle_mid()
869 mid->credits_received = smb2_get_credits_from_hdr(buf, server); in handle_mid()
870 mid->resp_buf = buf; in handle_mid()
871 mid->large_buf = server->large_buf; in handle_mid()
872 /* Was previous buf put in mpx struct for multi-rsp? */ in handle_mid()
873 if (!mid->multiRsp) { in handle_mid()
875 if (server->large_buf) in handle_mid()
876 server->bigbuf = NULL; in handle_mid()
878 server->smallbuf = NULL; in handle_mid()
889 list_del_init(&server->tcp_ses_list); in clean_demultiplex_info()
892 cancel_delayed_work_sync(&server->echo); in clean_demultiplex_info()
895 server->tcpStatus = CifsExiting; in clean_demultiplex_info()
897 wake_up_all(&server->response_q); in clean_demultiplex_info()
900 spin_lock(&server->req_lock); in clean_demultiplex_info()
901 if (server->credits <= 0) in clean_demultiplex_info()
902 server->credits = 1; in clean_demultiplex_info()
903 spin_unlock(&server->req_lock); in clean_demultiplex_info()
908 * same server - they now will see the session is in exit state and get in clean_demultiplex_info()
911 wake_up_all(&server->request_q); in clean_demultiplex_info()
916 if (server->ssocket) { in clean_demultiplex_info()
917 sock_release(server->ssocket); in clean_demultiplex_info()
918 server->ssocket = NULL; in clean_demultiplex_info()
921 if (!list_empty(&server->pending_mid_q)) { in clean_demultiplex_info()
928 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { in clean_demultiplex_info()
930 cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid); in clean_demultiplex_info()
931 kref_get(&mid_entry->refcount); in clean_demultiplex_info()
932 mid_entry->mid_state = MID_SHUTDOWN; in clean_demultiplex_info()
933 list_move(&mid_entry->qhead, &dispose_list); in clean_demultiplex_info()
934 mid_entry->mid_flags |= MID_DELETED; in clean_demultiplex_info()
941 cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid); in clean_demultiplex_info()
942 list_del_init(&mid_entry->qhead); in clean_demultiplex_info()
943 mid_entry->callback(mid_entry); in clean_demultiplex_info()
950 if (!list_empty(&server->pending_mid_q)) { in clean_demultiplex_info()
967 kfree(server->hostname); in clean_demultiplex_info()
979 char *buf = server->smallbuf; in standard_receive3()
980 unsigned int pdu_length = server->pdu_size; in standard_receive3()
983 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - in standard_receive3()
984 server->vals->header_preamble_size) { in standard_receive3()
987 return -ECONNABORTED; in standard_receive3()
991 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { in standard_receive3()
992 server->large_buf = true; in standard_receive3()
993 memcpy(server->bigbuf, buf, server->total_read); in standard_receive3()
994 buf = server->bigbuf; in standard_receive3()
998 length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, in standard_receive3()
999 pdu_length - HEADER_SIZE(server) + 1 in standard_receive3()
1000 + server->vals->header_preamble_size); in standard_receive3()
1004 server->total_read += length; in standard_receive3()
1006 dump_smb(buf, server->total_read); in standard_receive3()
1014 char *buf = server->large_buf ? server->bigbuf : server->smallbuf; in cifs_handle_standard()
1026 length = server->ops->check_message(buf, server->total_read, server); in cifs_handle_standard()
1029 min_t(unsigned int, server->total_read, 48)); in cifs_handle_standard()
1031 if (server->ops->is_session_expired && in cifs_handle_standard()
1032 server->ops->is_session_expired(buf)) { in cifs_handle_standard()
1034 return -1; in cifs_handle_standard()
1037 if (server->ops->is_status_pending && in cifs_handle_standard()
1038 server->ops->is_status_pending(buf, server)) in cifs_handle_standard()
1039 return -1; in cifs_handle_standard()
1056 if (server->vals->header_preamble_size) in smb2_add_credits_from_hdr()
1059 if (shdr->CreditRequest) { in smb2_add_credits_from_hdr()
1060 spin_lock(&server->req_lock); in smb2_add_credits_from_hdr()
1061 server->credits += le16_to_cpu(shdr->CreditRequest); in smb2_add_credits_from_hdr()
1062 spin_unlock(&server->req_lock); in smb2_add_credits_from_hdr()
1063 wake_up(&server->request_q); in smb2_add_credits_from_hdr()
1090 while (server->tcpStatus != CifsExiting) { in cifs_demultiplex_thread()
1097 server->large_buf = false; in cifs_demultiplex_thread()
1098 buf = server->smallbuf; in cifs_demultiplex_thread()
1105 if (server->vals->header_preamble_size == 0) in cifs_demultiplex_thread()
1106 server->total_read = 0; in cifs_demultiplex_thread()
1108 server->total_read = length; in cifs_demultiplex_thread()
1111 * The right amount was read from socket - 4 bytes, in cifs_demultiplex_thread()
1120 server->pdu_size = pdu_length; in cifs_demultiplex_thread()
1123 if (server->pdu_size < HEADER_SIZE(server) - 1 - in cifs_demultiplex_thread()
1124 server->vals->header_preamble_size) { in cifs_demultiplex_thread()
1126 server->pdu_size); in cifs_demultiplex_thread()
1133 buf + server->vals->header_preamble_size, in cifs_demultiplex_thread()
1134 HEADER_SIZE(server) - 1 in cifs_demultiplex_thread()
1135 - server->vals->header_preamble_size); in cifs_demultiplex_thread()
1138 server->total_read += length; in cifs_demultiplex_thread()
1140 if (server->ops->next_header) { in cifs_demultiplex_thread()
1141 next_offset = server->ops->next_header(buf); in cifs_demultiplex_thread()
1143 server->pdu_size = next_offset; in cifs_demultiplex_thread()
1150 if (server->ops->is_transform_hdr && in cifs_demultiplex_thread()
1151 server->ops->receive_transform && in cifs_demultiplex_thread()
1152 server->ops->is_transform_hdr(buf)) { in cifs_demultiplex_thread()
1153 length = server->ops->receive_transform(server, in cifs_demultiplex_thread()
1158 mids[0] = server->ops->find_mid(server, buf); in cifs_demultiplex_thread()
1162 if (!mids[0] || !mids[0]->receive) in cifs_demultiplex_thread()
1165 length = mids[0]->receive(server, mids[0]); in cifs_demultiplex_thread()
1175 if (server->ops->is_status_io_timeout && in cifs_demultiplex_thread()
1176 server->ops->is_status_io_timeout(buf)) { in cifs_demultiplex_thread()
1185 server->lstrp = jiffies; in cifs_demultiplex_thread()
1189 mids[i]->resp_buf_size = server->pdu_size; in cifs_demultiplex_thread()
1191 if (!mids[i]->multiRsp || mids[i]->multiEnd) in cifs_demultiplex_thread()
1192 mids[i]->callback(mids[i]); in cifs_demultiplex_thread()
1195 } else if (server->ops->is_oplock_break && in cifs_demultiplex_thread()
1196 server->ops->is_oplock_break(bufs[i], in cifs_demultiplex_thread()
1207 if (server->ops->dump_detail) in cifs_demultiplex_thread()
1208 server->ops->dump_detail(bufs[i], in cifs_demultiplex_thread()
1215 if (pdu_length > server->pdu_size) { in cifs_demultiplex_thread()
1218 pdu_length -= server->pdu_size; in cifs_demultiplex_thread()
1219 server->total_read = 0; in cifs_demultiplex_thread()
1220 server->large_buf = false; in cifs_demultiplex_thread()
1221 buf = server->smallbuf; in cifs_demultiplex_thread()
1226 /* buffer usually freed in free_mid - need to free it here on exit */ in cifs_demultiplex_thread()
1227 cifs_buf_release(server->bigbuf); in cifs_demultiplex_thread()
1228 if (server->smallbuf) /* no sense logging a debug message if NULL */ in cifs_demultiplex_thread()
1229 cifs_small_buf_release(server->smallbuf); in cifs_demultiplex_thread()
1231 task_to_wake = xchg(&server->tsk, NULL); in cifs_demultiplex_thread()
1234 /* if server->tsk was NULL then wait for a signal before exiting */ in cifs_demultiplex_thread()
1259 return ERR_PTR(-EINVAL); in extract_hostname()
1263 return ERR_PTR(-EINVAL); in extract_hostname()
1268 return ERR_PTR(-EINVAL); in extract_hostname()
1270 len = delim - src; in extract_hostname()
1273 return ERR_PTR(-ENOMEM); in extract_hostname()
1288 return -ENOMEM; in get_option_ul()
1307 return -EINVAL; in get_option_uid()
1325 return -EINVAL; in get_option_gid()
1332 * Parse a devname into substrings and populate the vol->UNC and vol->prepath
1344 return -EINVAL; in cifs_parse_devname()
1350 return -EINVAL; in cifs_parse_devname()
1355 return -EINVAL; in cifs_parse_devname()
1365 vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); in cifs_parse_devname()
1366 if (!vol->UNC) in cifs_parse_devname()
1367 return -ENOMEM; in cifs_parse_devname()
1369 convert_delimiter(vol->UNC, '\\'); in cifs_parse_devname()
1379 vol->prepath = kstrdup(pos, GFP_KERNEL); in cifs_parse_devname()
1380 if (!vol->prepath) in cifs_parse_devname()
1381 return -ENOMEM; in cifs_parse_devname()
1394 short int override_uid = -1; in cifs_parse_mount_options()
1395 short int override_gid = -1; in cifs_parse_mount_options()
1400 char *nodename = utsname()->nodename; in cifs_parse_mount_options()
1407 struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr; in cifs_parse_mount_options()
1413 /* ensure we always start with zeroed-out smb_vol */ in cifs_parse_mount_options()
1421 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); in cifs_parse_mount_options()
1423 vol->source_rfc1001_name[i] = toupper(nodename[i]); in cifs_parse_mount_options()
1425 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0; in cifs_parse_mount_options()
1428 vol->target_rfc1001_name[0] = 0; in cifs_parse_mount_options()
1429 vol->cred_uid = current_uid(); in cifs_parse_mount_options()
1430 vol->linux_uid = current_uid(); in cifs_parse_mount_options()
1431 vol->linux_gid = current_gid(); in cifs_parse_mount_options()
1432 vol->bsize = 1024 * 1024; /* can improve cp performance significantly */ in cifs_parse_mount_options()
1439 vol->remap = true; in cifs_parse_mount_options()
1442 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; in cifs_parse_mount_options()
1444 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ in cifs_parse_mount_options()
1446 vol->posix_paths = 1; in cifs_parse_mount_options()
1448 vol->server_ino = 1; in cifs_parse_mount_options()
1451 vol->strict_io = true; in cifs_parse_mount_options()
1453 vol->actimeo = CIFS_DEF_ACTIMEO; in cifs_parse_mount_options()
1456 vol->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ in cifs_parse_mount_options()
1459 vol->ops = &smb30_operations; in cifs_parse_mount_options()
1460 vol->vals = &smbdefault_values; in cifs_parse_mount_options()
1462 vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; in cifs_parse_mount_options()
1465 vol->multichannel = false; in cifs_parse_mount_options()
1466 vol->max_channels = 1; in cifs_parse_mount_options()
1486 vol->backupuid_specified = false; /* no backup intent for a user */ in cifs_parse_mount_options()
1487 vol->backupgid_specified = false; /* no backup intent for a group */ in cifs_parse_mount_options()
1492 case -ENOMEM: in cifs_parse_mount_options()
1495 case -EINVAL: in cifs_parse_mount_options()
1521 vol->no_xattr = 0; in cifs_parse_mount_options()
1524 vol->no_xattr = 1; in cifs_parse_mount_options()
1539 vol->noblocksnd = 1; in cifs_parse_mount_options()
1542 vol->noautotune = 1; in cifs_parse_mount_options()
1545 vol->no_lease = 1; in cifs_parse_mount_options()
1548 vol->retry = 1; in cifs_parse_mount_options()
1551 vol->retry = 0; in cifs_parse_mount_options()
1554 vol->noperm = 0; in cifs_parse_mount_options()
1557 vol->noperm = 1; in cifs_parse_mount_options()
1560 vol->nodelete = 1; in cifs_parse_mount_options()
1563 vol->sfu_remap = true; in cifs_parse_mount_options()
1564 vol->remap = false; /* disable SFM mapping */ in cifs_parse_mount_options()
1567 vol->sfu_remap = false; in cifs_parse_mount_options()
1570 vol->remap = true; in cifs_parse_mount_options()
1571 vol->sfu_remap = false; /* disable SFU mapping */ in cifs_parse_mount_options()
1574 vol->remap = false; in cifs_parse_mount_options()
1577 vol->sfu_emul = 1; in cifs_parse_mount_options()
1580 vol->sfu_emul = 0; in cifs_parse_mount_options()
1583 vol->nodfs = 1; in cifs_parse_mount_options()
1587 vol->rootfs = true; in cifs_parse_mount_options()
1591 vol->posix_paths = 1; in cifs_parse_mount_options()
1594 vol->posix_paths = 0; in cifs_parse_mount_options()
1597 if (vol->linux_ext) in cifs_parse_mount_options()
1600 vol->no_linux_ext = 1; in cifs_parse_mount_options()
1603 if (vol->no_linux_ext) in cifs_parse_mount_options()
1606 vol->linux_ext = 1; in cifs_parse_mount_options()
1609 vol->nocase = 1; in cifs_parse_mount_options()
1612 vol->nobrl = 0; in cifs_parse_mount_options()
1615 vol->nobrl = 1; in cifs_parse_mount_options()
1621 if (vol->file_mode == in cifs_parse_mount_options()
1623 vol->file_mode = S_IALLUGO; in cifs_parse_mount_options()
1626 vol->nohandlecache = 1; in cifs_parse_mount_options()
1629 vol->nohandlecache = 0; in cifs_parse_mount_options()
1632 vol->mand_lock = 1; in cifs_parse_mount_options()
1635 vol->setuids = 1; in cifs_parse_mount_options()
1638 vol->setuids = 0; in cifs_parse_mount_options()
1641 vol->setuidfromacl = 1; in cifs_parse_mount_options()
1644 vol->dynperm = true; in cifs_parse_mount_options()
1647 vol->dynperm = false; in cifs_parse_mount_options()
1650 vol->retry = 0; in cifs_parse_mount_options()
1653 vol->retry = 1; in cifs_parse_mount_options()
1656 vol->intr = 0; in cifs_parse_mount_options()
1659 vol->intr = 1; in cifs_parse_mount_options()
1662 vol->nostrictsync = 1; in cifs_parse_mount_options()
1665 vol->nostrictsync = 0; in cifs_parse_mount_options()
1668 vol->server_ino = 1; in cifs_parse_mount_options()
1671 vol->server_ino = 0; in cifs_parse_mount_options()
1674 vol->rwpidforward = 1; in cifs_parse_mount_options()
1677 vol->mode_ace = 1; in cifs_parse_mount_options()
1680 vol->cifs_acl = 1; in cifs_parse_mount_options()
1683 vol->cifs_acl = 0; in cifs_parse_mount_options()
1686 vol->no_psx_acl = 0; in cifs_parse_mount_options()
1689 vol->no_psx_acl = 1; in cifs_parse_mount_options()
1692 vol->local_lease = 1; in cifs_parse_mount_options()
1695 vol->sign = true; in cifs_parse_mount_options()
1698 vol->sign = true; in cifs_parse_mount_options()
1699 vol->ignore_signature = true; in cifs_parse_mount_options()
1704 * or per-smb connection option in the protocol in cifs_parse_mount_options()
1705 * vol->secFlg |= CIFSSEC_MUST_SEAL; in cifs_parse_mount_options()
1707 vol->seal = 1; in cifs_parse_mount_options()
1714 cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n"); in cifs_parse_mount_options()
1717 vol->fsc = true; in cifs_parse_mount_options()
1720 vol->mfsymlinks = true; in cifs_parse_mount_options()
1723 vol->multiuser = true; in cifs_parse_mount_options()
1729 vol->nosharesock = true; in cifs_parse_mount_options()
1732 vol->nopersistent = true; in cifs_parse_mount_options()
1733 if (vol->persistent) { in cifs_parse_mount_options()
1740 vol->persistent = true; in cifs_parse_mount_options()
1741 if ((vol->nopersistent) || (vol->resilient)) { in cifs_parse_mount_options()
1748 vol->resilient = true; in cifs_parse_mount_options()
1749 if (vol->persistent) { in cifs_parse_mount_options()
1756 vol->resilient = false; /* already the default */ in cifs_parse_mount_options()
1759 vol->domainauto = true; in cifs_parse_mount_options()
1762 vol->rdma = true; in cifs_parse_mount_options()
1765 vol->multichannel = true; in cifs_parse_mount_options()
1767 if (vol->max_channels < 2) in cifs_parse_mount_options()
1768 vol->max_channels = 2; in cifs_parse_mount_options()
1771 vol->multichannel = false; in cifs_parse_mount_options()
1772 vol->max_channels = 1; in cifs_parse_mount_options()
1775 vol->compression = UNKNOWN_TYPE; in cifs_parse_mount_options()
1782 if (get_option_uid(args, &vol->backupuid)) { in cifs_parse_mount_options()
1787 vol->backupuid_specified = true; in cifs_parse_mount_options()
1790 if (get_option_gid(args, &vol->backupgid)) { in cifs_parse_mount_options()
1795 vol->backupgid_specified = true; in cifs_parse_mount_options()
1798 if (get_option_uid(args, &vol->linux_uid)) { in cifs_parse_mount_options()
1806 if (get_option_uid(args, &vol->cred_uid)) { in cifs_parse_mount_options()
1813 if (get_option_gid(args, &vol->linux_gid)) { in cifs_parse_mount_options()
1826 vol->file_mode = option; in cifs_parse_mount_options()
1834 vol->dir_mode = option; in cifs_parse_mount_options()
1850 vol->min_offload = option; in cifs_parse_mount_options()
1870 vol->bsize = option; in cifs_parse_mount_options()
1878 vol->rsize = option; in cifs_parse_mount_options()
1886 vol->wsize = option; in cifs_parse_mount_options()
1894 vol->actimeo = HZ * option; in cifs_parse_mount_options()
1895 if (vol->actimeo > CIFS_MAX_ACTIMEO) { in cifs_parse_mount_options()
1906 vol->handle_timeout = option; in cifs_parse_mount_options()
1907 if (vol->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { in cifs_parse_mount_options()
1918 vol->echo_interval = option; in cifs_parse_mount_options()
1926 vol->snapshot_time = option; in cifs_parse_mount_options()
1935 vol->max_credits = option; in cifs_parse_mount_options()
1940 cifs_dbg(VFS, "%s: Invalid max_channels value, needs to be 1-%d\n", in cifs_parse_mount_options()
1944 vol->max_channels = option; in cifs_parse_mount_options()
1951 vol->nullauth = 1; in cifs_parse_mount_options()
1952 vol->username = NULL; in cifs_parse_mount_options()
1965 kfree(vol->username); in cifs_parse_mount_options()
1966 vol->username = kstrdup(string, GFP_KERNEL); in cifs_parse_mount_options()
1967 if (!vol->username) in cifs_parse_mount_options()
1984 kfree_sensitive(vol->password); in cifs_parse_mount_options()
1985 vol->password = NULL; in cifs_parse_mount_options()
2022 kfree_sensitive(vol->password); in cifs_parse_mount_options()
2025 vol->password = kzalloc(temp_len+1, GFP_KERNEL); in cifs_parse_mount_options()
2026 if (vol->password == NULL) { in cifs_parse_mount_options()
2032 vol->password[j] = value[i]; in cifs_parse_mount_options()
2038 vol->password[j] = '\0'; in cifs_parse_mount_options()
2067 kfree(vol->domainname); in cifs_parse_mount_options()
2068 vol->domainname = kstrdup(string, GFP_KERNEL); in cifs_parse_mount_options()
2069 if (!vol->domainname) { in cifs_parse_mount_options()
2081 (struct sockaddr *)&vol->srcaddr, in cifs_parse_mount_options()
2099 kfree(vol->iocharset); in cifs_parse_mount_options()
2100 vol->iocharset = kstrdup(string, in cifs_parse_mount_options()
2102 if (!vol->iocharset) { in cifs_parse_mount_options()
2117 memset(vol->source_rfc1001_name, 0x20, in cifs_parse_mount_options()
2128 vol->source_rfc1001_name[i] = string[i]; in cifs_parse_mount_options()
2131 * set at top of the function in cifs_parse_mount_options()
2143 memset(vol->target_rfc1001_name, 0x20, in cifs_parse_mount_options()
2155 vol->target_rfc1001_name[i] = string[i]; in cifs_parse_mount_options()
2158 set at top of the function */ in cifs_parse_mount_options()
2226 if (vol->rdma && vol->vals->protocol_id < SMB30_PROT_ID) { in cifs_parse_mount_options()
2233 if (vol->multiuser) { in cifs_parse_mount_options()
2238 if (!vol->UNC) { in cifs_parse_mount_options()
2244 if (!strchr(vol->UNC + 3, '\\')) { in cifs_parse_mount_options()
2255 slash = strchr(&vol->UNC[2], '\\'); in cifs_parse_mount_options()
2256 len = slash - &vol->UNC[2]; in cifs_parse_mount_options()
2257 if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) { in cifs_parse_mount_options()
2267 vol->override_uid = override_uid; in cifs_parse_mount_options()
2272 vol->override_gid = override_gid; in cifs_parse_mount_options()
2297 switch (srcaddr->sa_family) { in cifs_match_ipaddr()
2299 return (rhs->sa_family == AF_UNSPEC); in cifs_match_ipaddr()
2303 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr); in cifs_match_ipaddr()
2308 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr); in cifs_match_ipaddr()
2318 * and if it fails - with 139 ports. It should be called only if address
2327 if (server->rdma) in match_port()
2330 switch (addr->sa_family) { in match_port()
2332 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; in match_port()
2333 port = ((struct sockaddr_in *) addr)->sin_port; in match_port()
2336 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port; in match_port()
2337 port = ((struct sockaddr_in6 *) addr)->sin6_port; in match_port()
2359 switch (addr->sa_family) { in match_address()
2363 (struct sockaddr_in *)&server->dstaddr; in match_address()
2365 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr) in match_address()
2372 (struct sockaddr_in6 *)&server->dstaddr; in match_address()
2374 if (!ipv6_addr_equal(&addr6->sin6_addr, in match_address()
2375 &srv_addr6->sin6_addr)) in match_address()
2377 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id) in match_address()
2386 if (!cifs_match_ipaddr(srcaddr, (struct sockaddr *)&server->srcaddr)) in match_address()
2396 * The select_sectype function should either return the vol->sectype in match_security()
2400 if (server->ops->select_sectype(server, vol->sectype) in match_security()
2407 * the server->sign had better be too. in match_security()
2409 if (vol->sign && !server->sign) in match_security()
2417 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr; in match_server()
2419 if (vol->nosharesock) in match_server()
2423 if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { in match_server()
2424 if (server->vals->protocol_id < SMB30_PROT_ID) in match_server()
2426 } else if (strcmp(vol->vals->version_string, in match_server()
2428 if (server->vals->protocol_id < SMB21_PROT_ID) in match_server()
2430 } else if ((server->vals != vol->vals) || (server->ops != vol->ops)) in match_server()
2433 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) in match_server()
2437 (struct sockaddr *)&vol->srcaddr)) in match_server()
2446 if (server->echo_interval != vol->echo_interval * HZ) in match_server()
2449 if (server->rdma != vol->rdma) in match_server()
2452 if (server->ignore_signature != vol->ignore_signature) in match_server()
2455 if (server->min_offload != vol->min_offload) in match_server()
2472 if (server->is_channel || !match_server(server, vol)) in cifs_find_tcp_session()
2475 ++server->srv_count; in cifs_find_tcp_session()
2490 if (--server->srv_count > 0) { in cifs_put_tcp_session()
2497 list_del_init(&server->tcp_ses_list); in cifs_put_tcp_session()
2500 cancel_delayed_work_sync(&server->echo); in cifs_put_tcp_session()
2509 cancel_delayed_work(&server->reconnect); in cifs_put_tcp_session()
2511 cancel_delayed_work_sync(&server->reconnect); in cifs_put_tcp_session()
2514 server->tcpStatus = CifsExiting; in cifs_put_tcp_session()
2520 kfree(server->session_key.response); in cifs_put_tcp_session()
2521 server->session_key.response = NULL; in cifs_put_tcp_session()
2522 server->session_key.len = 0; in cifs_put_tcp_session()
2524 task = xchg(&server->tsk, NULL); in cifs_put_tcp_session()
2535 cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC); in cifs_get_tcp_session()
2544 rc = -ENOMEM; in cifs_get_tcp_session()
2548 tcp_ses->ops = volume_info->ops; in cifs_get_tcp_session()
2549 tcp_ses->vals = volume_info->vals; in cifs_get_tcp_session()
2550 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); in cifs_get_tcp_session()
2551 tcp_ses->hostname = extract_hostname(volume_info->UNC); in cifs_get_tcp_session()
2552 if (IS_ERR(tcp_ses->hostname)) { in cifs_get_tcp_session()
2553 rc = PTR_ERR(tcp_ses->hostname); in cifs_get_tcp_session()
2557 tcp_ses->noblockcnt = volume_info->rootfs; in cifs_get_tcp_session()
2558 tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs; in cifs_get_tcp_session()
2559 tcp_ses->noautotune = volume_info->noautotune; in cifs_get_tcp_session()
2560 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; in cifs_get_tcp_session()
2561 tcp_ses->rdma = volume_info->rdma; in cifs_get_tcp_session()
2562 tcp_ses->in_flight = 0; in cifs_get_tcp_session()
2563 tcp_ses->max_in_flight = 0; in cifs_get_tcp_session()
2564 tcp_ses->credits = 1; in cifs_get_tcp_session()
2565 init_waitqueue_head(&tcp_ses->response_q); in cifs_get_tcp_session()
2566 init_waitqueue_head(&tcp_ses->request_q); in cifs_get_tcp_session()
2567 INIT_LIST_HEAD(&tcp_ses->pending_mid_q); in cifs_get_tcp_session()
2568 mutex_init(&tcp_ses->srv_mutex); in cifs_get_tcp_session()
2569 memcpy(tcp_ses->workstation_RFC1001_name, in cifs_get_tcp_session()
2570 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); in cifs_get_tcp_session()
2571 memcpy(tcp_ses->server_RFC1001_name, in cifs_get_tcp_session()
2572 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); in cifs_get_tcp_session()
2573 tcp_ses->session_estab = false; in cifs_get_tcp_session()
2574 tcp_ses->sequence_number = 0; in cifs_get_tcp_session()
2575 tcp_ses->reconnect_instance = 1; in cifs_get_tcp_session()
2576 tcp_ses->lstrp = jiffies; in cifs_get_tcp_session()
2577 tcp_ses->compress_algorithm = cpu_to_le16(volume_info->compression); in cifs_get_tcp_session()
2578 spin_lock_init(&tcp_ses->req_lock); in cifs_get_tcp_session()
2579 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); in cifs_get_tcp_session()
2580 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); in cifs_get_tcp_session()
2581 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); in cifs_get_tcp_session()
2582 INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); in cifs_get_tcp_session()
2583 mutex_init(&tcp_ses->reconnect_mutex); in cifs_get_tcp_session()
2584 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, in cifs_get_tcp_session()
2585 sizeof(tcp_ses->srcaddr)); in cifs_get_tcp_session()
2586 memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, in cifs_get_tcp_session()
2587 sizeof(tcp_ses->dstaddr)); in cifs_get_tcp_session()
2588 if (volume_info->use_client_guid) in cifs_get_tcp_session()
2589 memcpy(tcp_ses->client_guid, volume_info->client_guid, in cifs_get_tcp_session()
2592 generate_random_uuid(tcp_ses->client_guid); in cifs_get_tcp_session()
2598 tcp_ses->tcpStatus = CifsNew; in cifs_get_tcp_session()
2599 ++tcp_ses->srv_count; in cifs_get_tcp_session()
2601 if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN && in cifs_get_tcp_session()
2602 volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX) in cifs_get_tcp_session()
2603 tcp_ses->echo_interval = volume_info->echo_interval * HZ; in cifs_get_tcp_session()
2605 tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ; in cifs_get_tcp_session()
2606 if (tcp_ses->rdma) { in cifs_get_tcp_session()
2609 rc = -ENOENT; in cifs_get_tcp_session()
2612 tcp_ses->smbd_conn = smbd_get_connection( in cifs_get_tcp_session()
2613 tcp_ses, (struct sockaddr *)&volume_info->dstaddr); in cifs_get_tcp_session()
2614 if (tcp_ses->smbd_conn) { in cifs_get_tcp_session()
2619 rc = -ENOENT; in cifs_get_tcp_session()
2634 tcp_ses->tsk = kthread_run(cifs_demultiplex_thread, in cifs_get_tcp_session()
2636 if (IS_ERR(tcp_ses->tsk)) { in cifs_get_tcp_session()
2637 rc = PTR_ERR(tcp_ses->tsk); in cifs_get_tcp_session()
2642 tcp_ses->min_offload = volume_info->min_offload; in cifs_get_tcp_session()
2643 tcp_ses->tcpStatus = CifsNeedNegotiate; in cifs_get_tcp_session()
2645 if ((volume_info->max_credits < 20) || (volume_info->max_credits > 60000)) in cifs_get_tcp_session()
2646 tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; in cifs_get_tcp_session()
2648 tcp_ses->max_credits = volume_info->max_credits; in cifs_get_tcp_session()
2650 tcp_ses->nr_targets = 1; in cifs_get_tcp_session()
2651 tcp_ses->ignore_signature = volume_info->ignore_signature; in cifs_get_tcp_session()
2654 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); in cifs_get_tcp_session()
2660 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); in cifs_get_tcp_session()
2671 if (!IS_ERR(tcp_ses->hostname)) in cifs_get_tcp_session()
2672 kfree(tcp_ses->hostname); in cifs_get_tcp_session()
2673 if (tcp_ses->ssocket) in cifs_get_tcp_session()
2674 sock_release(tcp_ses->ssocket); in cifs_get_tcp_session()
2682 if (vol->sectype != Unspecified && in match_session()
2683 vol->sectype != ses->sectype) in match_session()
2690 if (ses->chan_max < vol->max_channels) in match_session()
2693 switch (ses->sectype) { in match_session()
2695 if (!uid_eq(vol->cred_uid, ses->cred_uid)) in match_session()
2700 if (ses->user_name == NULL) { in match_session()
2701 if (!vol->nullauth) in match_session()
2707 if (strncmp(ses->user_name, in match_session()
2708 vol->username ? vol->username : "", in match_session()
2711 if ((vol->username && strlen(vol->username) != 0) && in match_session()
2712 ses->password != NULL && in match_session()
2713 strncmp(ses->password, in match_session()
2714 vol->password ? vol->password : "", in match_session()
2722 * cifs_setup_ipc - helper to setup the IPC tcon for the session
2725 * tcon_ipc. The IPC tcon has the same lifetime as the session.
2731 struct cifs_tcon *tcon; in cifs_setup_ipc() local
2735 struct TCP_Server_Info *server = ses->server; in cifs_setup_ipc()
2741 if (volume_info->seal) { in cifs_setup_ipc()
2742 if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) in cifs_setup_ipc()
2747 return -EOPNOTSUPP; in cifs_setup_ipc()
2751 tcon = tconInfoAlloc(); in cifs_setup_ipc()
2752 if (tcon == NULL) in cifs_setup_ipc()
2753 return -ENOMEM; in cifs_setup_ipc()
2755 scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname); in cifs_setup_ipc()
2761 tcon->ses = ses; in cifs_setup_ipc()
2762 tcon->ipc = true; in cifs_setup_ipc()
2763 tcon->seal = seal; in cifs_setup_ipc()
2764 rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); in cifs_setup_ipc()
2769 tconInfoFree(tcon); in cifs_setup_ipc()
2773 cifs_dbg(FYI, "IPC tcon rc = %d ipc tid = %d\n", rc, tcon->tid); in cifs_setup_ipc()
2775 ses->tcon_ipc = tcon; in cifs_setup_ipc()
2782 * cifs_free_ipc - helper to release the session IPC tcon
2790 struct cifs_tcon *tcon = ses->tcon_ipc; in cifs_free_ipc() local
2792 if (tcon == NULL) in cifs_free_ipc()
2795 if (ses->server->ops->tree_disconnect) { in cifs_free_ipc()
2797 rc = ses->server->ops->tree_disconnect(xid, tcon); in cifs_free_ipc()
2802 cifs_dbg(FYI, "failed to disconnect IPC tcon (rc=%d)\n", rc); in cifs_free_ipc()
2804 tconInfoFree(tcon); in cifs_free_ipc()
2805 ses->tcon_ipc = NULL; in cifs_free_ipc()
2815 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { in cifs_find_smb_ses()
2816 if (ses->status == CifsExiting) in cifs_find_smb_ses()
2820 ++ses->ses_count; in cifs_find_smb_ses()
2831 struct TCP_Server_Info *server = ses->server; in cifs_put_smb_ses()
2833 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count); in cifs_put_smb_ses()
2836 if (ses->status == CifsExiting) { in cifs_put_smb_ses()
2840 if (--ses->ses_count > 0) { in cifs_put_smb_ses()
2847 if (ses->status == CifsGood) in cifs_put_smb_ses()
2848 ses->status = CifsExiting; in cifs_put_smb_ses()
2853 if (ses->status == CifsExiting && server->ops->logoff) { in cifs_put_smb_ses()
2855 rc = server->ops->logoff(xid, ses); in cifs_put_smb_ses()
2863 list_del_init(&ses->smb_ses_list); in cifs_put_smb_ses()
2867 if (ses->chan_count > 1) { in cifs_put_smb_ses()
2870 for (i = 1; i < ses->chan_count; i++) in cifs_put_smb_ses()
2871 cifs_put_tcp_session(ses->chans[i].server, 0); in cifs_put_smb_ses()
2893 struct TCP_Server_Info *server = ses->server; in cifs_set_cifscreds()
2900 return -ENOMEM; in cifs_set_cifscreds()
2903 switch (server->dstaddr.ss_family) { in cifs_set_cifscreds()
2905 sa = (struct sockaddr_in *)&server->dstaddr; in cifs_set_cifscreds()
2906 sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr); in cifs_set_cifscreds()
2909 sa6 = (struct sockaddr_in6 *)&server->dstaddr; in cifs_set_cifscreds()
2910 sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr); in cifs_set_cifscreds()
2914 server->dstaddr.ss_family); in cifs_set_cifscreds()
2915 rc = -EINVAL; in cifs_set_cifscreds()
2922 if (!ses->domainName) { in cifs_set_cifscreds()
2929 sprintf(desc, "cifs:d:%s", ses->domainName); in cifs_set_cifscreds()
2939 down_read(&key->sem); in cifs_set_cifscreds()
2942 rc = upayload ? PTR_ERR(upayload) : -EINVAL; in cifs_set_cifscreds()
2947 payload = upayload->data; in cifs_set_cifscreds()
2948 delim = strnchr(payload, upayload->datalen, ':'); in cifs_set_cifscreds()
2952 upayload->datalen); in cifs_set_cifscreds()
2953 rc = -EINVAL; in cifs_set_cifscreds()
2957 len = delim - payload; in cifs_set_cifscreds()
2961 rc = -EINVAL; in cifs_set_cifscreds()
2965 vol->username = kstrndup(payload, len, GFP_KERNEL); in cifs_set_cifscreds()
2966 if (!vol->username) { in cifs_set_cifscreds()
2969 rc = -ENOMEM; in cifs_set_cifscreds()
2972 cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username); in cifs_set_cifscreds()
2974 len = key->datalen - (len + 1); in cifs_set_cifscreds()
2977 rc = -EINVAL; in cifs_set_cifscreds()
2978 kfree(vol->username); in cifs_set_cifscreds()
2979 vol->username = NULL; in cifs_set_cifscreds()
2984 vol->password = kstrndup(delim, len, GFP_KERNEL); in cifs_set_cifscreds()
2985 if (!vol->password) { in cifs_set_cifscreds()
2988 rc = -ENOMEM; in cifs_set_cifscreds()
2989 kfree(vol->username); in cifs_set_cifscreds()
2990 vol->username = NULL; in cifs_set_cifscreds()
2998 if (is_domain && ses->domainName) { in cifs_set_cifscreds()
2999 vol->domainname = kstrndup(ses->domainName, in cifs_set_cifscreds()
3000 strlen(ses->domainName), in cifs_set_cifscreds()
3002 if (!vol->domainname) { in cifs_set_cifscreds()
3005 rc = -ENOMEM; in cifs_set_cifscreds()
3006 kfree(vol->username); in cifs_set_cifscreds()
3007 vol->username = NULL; in cifs_set_cifscreds()
3008 kfree_sensitive(vol->password); in cifs_set_cifscreds()
3009 vol->password = NULL; in cifs_set_cifscreds()
3015 up_read(&key->sem); in cifs_set_cifscreds()
3027 return -ENOSYS; in cifs_set_cifscreds()
3032 * cifs_get_smb_ses - get a session matching @volume_info data from @server
3044 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; in cifs_get_smb_ses()
3045 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; in cifs_get_smb_ses()
3052 ses->status); in cifs_get_smb_ses()
3054 mutex_lock(&ses->session_mutex); in cifs_get_smb_ses()
3057 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3058 /* problem -- put our ses reference */ in cifs_get_smb_ses()
3063 if (ses->need_reconnect) { in cifs_get_smb_ses()
3066 volume_info->local_nls); in cifs_get_smb_ses()
3068 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3069 /* problem -- put our reference */ in cifs_get_smb_ses()
3075 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3083 rc = -ENOMEM; in cifs_get_smb_ses()
3091 ses->server = server; in cifs_get_smb_ses()
3092 if (server->dstaddr.ss_family == AF_INET6) in cifs_get_smb_ses()
3093 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr); in cifs_get_smb_ses()
3095 sprintf(ses->serverName, "%pI4", &addr->sin_addr); in cifs_get_smb_ses()
3097 if (volume_info->username) { in cifs_get_smb_ses()
3098 ses->user_name = kstrdup(volume_info->username, GFP_KERNEL); in cifs_get_smb_ses()
3099 if (!ses->user_name) in cifs_get_smb_ses()
3103 /* volume_info->password freed at unmount */ in cifs_get_smb_ses()
3104 if (volume_info->password) { in cifs_get_smb_ses()
3105 ses->password = kstrdup(volume_info->password, GFP_KERNEL); in cifs_get_smb_ses()
3106 if (!ses->password) in cifs_get_smb_ses()
3109 if (volume_info->domainname) { in cifs_get_smb_ses()
3110 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL); in cifs_get_smb_ses()
3111 if (!ses->domainName) in cifs_get_smb_ses()
3114 if (volume_info->domainauto) in cifs_get_smb_ses()
3115 ses->domainAuto = volume_info->domainauto; in cifs_get_smb_ses()
3116 ses->cred_uid = volume_info->cred_uid; in cifs_get_smb_ses()
3117 ses->linux_uid = volume_info->linux_uid; in cifs_get_smb_ses()
3119 ses->sectype = volume_info->sectype; in cifs_get_smb_ses()
3120 ses->sign = volume_info->sign; in cifs_get_smb_ses()
3121 mutex_lock(&ses->session_mutex); in cifs_get_smb_ses()
3124 ses->chans[0].server = server; in cifs_get_smb_ses()
3125 ses->chan_count = 1; in cifs_get_smb_ses()
3126 ses->chan_max = volume_info->multichannel ? volume_info->max_channels:1; in cifs_get_smb_ses()
3130 rc = cifs_setup_session(xid, ses, volume_info->local_nls); in cifs_get_smb_ses()
3133 memcpy(ses->chans[0].signkey, ses->smb3signingkey, in cifs_get_smb_ses()
3134 sizeof(ses->smb3signingkey)); in cifs_get_smb_ses()
3136 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3142 list_add(&ses->smb_ses_list, &server->smb_ses_list); in cifs_get_smb_ses()
3157 static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) in match_tcon() argument
3159 if (tcon->tidStatus == CifsExiting) in match_tcon()
3161 if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE)) in match_tcon()
3163 if (tcon->seal != volume_info->seal) in match_tcon()
3165 if (tcon->snapshot_time != volume_info->snapshot_time) in match_tcon()
3167 if (tcon->handle_timeout != volume_info->handle_timeout) in match_tcon()
3169 if (tcon->no_lease != volume_info->no_lease) in match_tcon()
3171 if (tcon->nodelete != volume_info->nodelete) in match_tcon()
3180 struct cifs_tcon *tcon; in cifs_find_tcon() local
3183 list_for_each(tmp, &ses->tcon_list) { in cifs_find_tcon()
3184 tcon = list_entry(tmp, struct cifs_tcon, tcon_list); in cifs_find_tcon()
3186 if (tcon->dfs_path) in cifs_find_tcon()
3189 if (!match_tcon(tcon, volume_info)) in cifs_find_tcon()
3191 ++tcon->tc_count; in cifs_find_tcon()
3193 return tcon; in cifs_find_tcon()
3200 cifs_put_tcon(struct cifs_tcon *tcon) in cifs_put_tcon() argument
3206 * IPC tcon share the lifetime of their session and are in cifs_put_tcon()
3209 if (tcon == NULL || tcon->ipc) in cifs_put_tcon()
3212 ses = tcon->ses; in cifs_put_tcon()
3213 cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count); in cifs_put_tcon()
3215 if (--tcon->tc_count > 0) { in cifs_put_tcon()
3220 list_del_init(&tcon->tcon_list); in cifs_put_tcon()
3224 if (ses->server->ops->tree_disconnect) in cifs_put_tcon()
3225 ses->server->ops->tree_disconnect(xid, tcon); in cifs_put_tcon()
3228 cifs_fscache_release_super_cookie(tcon); in cifs_put_tcon()
3229 tconInfoFree(tcon); in cifs_put_tcon()
3234 * cifs_get_tcon - get a tcon matching @volume_info data from @ses
3236 * - tcon refcount is the number of mount points using the tcon.
3237 * - ses refcount is the number of tcon using the session.
3245 * a) a new tcon already allocated with refcount=1 (1 mount point) and
3246 * its session refcount incremented (1 new tcon). This +1 was
3249 * b) an existing tcon with refcount+1 (add a mount point to it) and
3250 * identical ses refcount (no new tcon). Because of (1) we need to
3257 struct cifs_tcon *tcon; in cifs_get_tcon() local
3259 tcon = cifs_find_tcon(ses, volume_info); in cifs_get_tcon()
3260 if (tcon) { in cifs_get_tcon()
3262 * tcon has refcount already incremented but we need to in cifs_get_tcon()
3267 return tcon; in cifs_get_tcon()
3270 if (!ses->server->ops->tree_connect) { in cifs_get_tcon()
3271 rc = -ENOSYS; in cifs_get_tcon()
3275 tcon = tconInfoAlloc(); in cifs_get_tcon()
3276 if (tcon == NULL) { in cifs_get_tcon()
3277 rc = -ENOMEM; in cifs_get_tcon()
3281 if (volume_info->snapshot_time) { in cifs_get_tcon()
3282 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3285 rc = -EOPNOTSUPP; in cifs_get_tcon()
3288 tcon->snapshot_time = volume_info->snapshot_time; in cifs_get_tcon()
3291 if (volume_info->handle_timeout) { in cifs_get_tcon()
3292 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3295 rc = -EOPNOTSUPP; in cifs_get_tcon()
3298 tcon->handle_timeout = volume_info->handle_timeout; in cifs_get_tcon()
3301 tcon->ses = ses; in cifs_get_tcon()
3302 if (volume_info->password) { in cifs_get_tcon()
3303 tcon->password = kstrdup(volume_info->password, GFP_KERNEL); in cifs_get_tcon()
3304 if (!tcon->password) { in cifs_get_tcon()
3305 rc = -ENOMEM; in cifs_get_tcon()
3310 if (volume_info->seal) { in cifs_get_tcon()
3311 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3314 rc = -EOPNOTSUPP; in cifs_get_tcon()
3316 } else if (tcon->ses->server->capabilities & in cifs_get_tcon()
3318 tcon->seal = true; in cifs_get_tcon()
3321 rc = -EOPNOTSUPP; in cifs_get_tcon()
3326 if (volume_info->linux_ext) { in cifs_get_tcon()
3327 if (ses->server->posix_ext_supported) { in cifs_get_tcon()
3328 tcon->posix_extensions = true; in cifs_get_tcon()
3332 rc = -EOPNOTSUPP; in cifs_get_tcon()
3338 * BB Do we need to wrap session_mutex around this TCon call and Unix in cifs_get_tcon()
3342 rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon, in cifs_get_tcon()
3343 volume_info->local_nls); in cifs_get_tcon()
3345 cifs_dbg(FYI, "Tcon rc = %d\n", rc); in cifs_get_tcon()
3349 tcon->use_persistent = false; in cifs_get_tcon()
3351 if (volume_info->persistent) { in cifs_get_tcon()
3352 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3355 rc = -EOPNOTSUPP; in cifs_get_tcon()
3357 } else if (ses->server->capabilities & in cifs_get_tcon()
3359 tcon->use_persistent = true; in cifs_get_tcon()
3363 rc = -EOPNOTSUPP; in cifs_get_tcon()
3366 } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) in cifs_get_tcon()
3367 && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) in cifs_get_tcon()
3368 && (volume_info->nopersistent == false)) { in cifs_get_tcon()
3370 tcon->use_persistent = true; in cifs_get_tcon()
3371 } else if (volume_info->resilient) { in cifs_get_tcon()
3372 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3375 rc = -EOPNOTSUPP; in cifs_get_tcon()
3378 tcon->use_resilient = true; in cifs_get_tcon()
3382 if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { in cifs_get_tcon()
3383 if (volume_info->cache_ro) in cifs_get_tcon()
3385 else if (volume_info->cache_rw) in cifs_get_tcon()
3389 if (volume_info->no_lease) { in cifs_get_tcon()
3390 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3393 rc = -EOPNOTSUPP; in cifs_get_tcon()
3396 tcon->no_lease = volume_info->no_lease; in cifs_get_tcon()
3404 tcon->retry = volume_info->retry; in cifs_get_tcon()
3405 tcon->nocase = volume_info->nocase; in cifs_get_tcon()
3406 if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) in cifs_get_tcon()
3407 tcon->nohandlecache = volume_info->nohandlecache; in cifs_get_tcon()
3409 tcon->nohandlecache = 1; in cifs_get_tcon()
3410 tcon->nodelete = volume_info->nodelete; in cifs_get_tcon()
3411 tcon->local_lease = volume_info->local_lease; in cifs_get_tcon()
3412 INIT_LIST_HEAD(&tcon->pending_opens); in cifs_get_tcon()
3415 list_add(&tcon->tcon_list, &ses->tcon_list); in cifs_get_tcon()
3418 cifs_fscache_get_super_cookie(tcon); in cifs_get_tcon()
3420 return tcon; in cifs_get_tcon()
3423 tconInfoFree(tcon); in cifs_get_tcon()
3433 if (!atomic_dec_and_test(&tlink->tl_count) || in cifs_put_tlink()
3434 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) { in cifs_put_tlink()
3435 tlink->tl_time = jiffies; in cifs_put_tlink()
3449 struct cifs_sb_info *new = mnt_data->cifs_sb; in compare_mount_options()
3450 unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK; in compare_mount_options()
3451 unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK; in compare_mount_options()
3453 if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) in compare_mount_options()
3456 if (old->mnt_cifs_serverino_autodisabled) in compare_mount_options()
3466 if (new->wsize && new->wsize < old->wsize) in compare_mount_options()
3469 if (new->rsize && new->rsize < old->rsize) in compare_mount_options()
3472 if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid)) in compare_mount_options()
3475 if (old->mnt_file_mode != new->mnt_file_mode || in compare_mount_options()
3476 old->mnt_dir_mode != new->mnt_dir_mode) in compare_mount_options()
3479 if (strcmp(old->local_nls->charset, new->local_nls->charset)) in compare_mount_options()
3482 if (old->actimeo != new->actimeo) in compare_mount_options()
3492 struct cifs_sb_info *new = mnt_data->cifs_sb; in match_prepath()
3493 bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && in match_prepath()
3494 old->prepath; in match_prepath()
3495 bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && in match_prepath()
3496 new->prepath; in match_prepath()
3498 if (old_set && new_set && !strcmp(new->prepath, old->prepath)) in match_prepath()
3514 struct cifs_tcon *tcon; in cifs_match_super() local
3526 tcon = tlink_tcon(tlink); in cifs_match_super()
3527 ses = tcon->ses; in cifs_match_super()
3528 tcp_srv = ses->server; in cifs_match_super()
3530 volume_info = mnt_data->vol; in cifs_match_super()
3534 !match_tcon(tcon, volume_info) || in cifs_match_super()
3554 struct sock *sk = sock->sk; in cifs_reclassify_socket4()
3556 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS", in cifs_reclassify_socket4()
3557 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]); in cifs_reclassify_socket4()
3563 struct sock *sk = sock->sk; in cifs_reclassify_socket6()
3565 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS", in cifs_reclassify_socket6()
3566 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]); in cifs_reclassify_socket6()
3598 if (server->srcaddr.ss_family != AF_UNSPEC) { in bind_socket()
3600 struct socket *socket = server->ssocket; in bind_socket()
3601 rc = socket->ops->bind(socket, in bind_socket()
3602 (struct sockaddr *) &server->srcaddr, in bind_socket()
3603 sizeof(server->srcaddr)); in bind_socket()
3607 saddr4 = (struct sockaddr_in *)&server->srcaddr; in bind_socket()
3608 saddr6 = (struct sockaddr_in6 *)&server->srcaddr; in bind_socket()
3609 if (saddr6->sin6_family == AF_INET6) in bind_socket()
3611 &saddr6->sin6_addr, rc); in bind_socket()
3614 &saddr4->sin_addr.s_addr, rc); in bind_socket()
3626 * negprot - BB check reconnection in case where second in ip_rfc1001_connect()
3634 ses_init_buf->trailer.session_req.called_len = 32; in ip_rfc1001_connect()
3636 if (server->server_RFC1001_name[0] != 0) in ip_rfc1001_connect()
3637 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3639 server->server_RFC1001_name, in ip_rfc1001_connect()
3642 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3647 ses_init_buf->trailer.session_req.calling_len = 32; in ip_rfc1001_connect()
3653 if (server->workstation_RFC1001_name[0] != 0) in ip_rfc1001_connect()
3654 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3656 server->workstation_RFC1001_name, in ip_rfc1001_connect()
3659 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3664 ses_init_buf->trailer.session_req.scope1 = 0; in ip_rfc1001_connect()
3665 ses_init_buf->trailer.session_req.scope2 = 0; in ip_rfc1001_connect()
3669 smb_buf->smb_buf_length = cpu_to_be32(0x81000044); in ip_rfc1001_connect()
3698 struct socket *socket = server->ssocket; in generic_ip_connect()
3701 saddr = (struct sockaddr *) &server->dstaddr; in generic_ip_connect()
3703 if (server->dstaddr.ss_family == AF_INET6) { in generic_ip_connect()
3704 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr; in generic_ip_connect()
3706 sport = ipv6->sin6_port; in generic_ip_connect()
3709 cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n", __func__, &ipv6->sin6_addr, in generic_ip_connect()
3712 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr; in generic_ip_connect()
3714 sport = ipv4->sin_port; in generic_ip_connect()
3717 cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr, in generic_ip_connect()
3726 server->ssocket = NULL; in generic_ip_connect()
3732 server->ssocket = socket; in generic_ip_connect()
3733 socket->sk->sk_allocation = GFP_NOFS; in generic_ip_connect()
3749 socket->sk->sk_rcvtimeo = 7 * HZ; in generic_ip_connect()
3750 socket->sk->sk_sndtimeo = 5 * HZ; in generic_ip_connect()
3753 if (server->noautotune) { in generic_ip_connect()
3754 if (socket->sk->sk_sndbuf < (200 * 1024)) in generic_ip_connect()
3755 socket->sk->sk_sndbuf = 200 * 1024; in generic_ip_connect()
3756 if (socket->sk->sk_rcvbuf < (140 * 1024)) in generic_ip_connect()
3757 socket->sk->sk_rcvbuf = 140 * 1024; in generic_ip_connect()
3760 if (server->tcp_nodelay) in generic_ip_connect()
3761 tcp_sock_set_nodelay(socket->sk); in generic_ip_connect()
3764 socket->sk->sk_sndbuf, in generic_ip_connect()
3765 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); in generic_ip_connect()
3767 rc = socket->ops->connect(socket, saddr, slen, in generic_ip_connect()
3768 server->noblockcnt ? O_NONBLOCK : 0); in generic_ip_connect()
3772 * reconnect failover - if possible. in generic_ip_connect()
3774 if (server->noblockcnt && rc == -EINPROGRESS) in generic_ip_connect()
3779 server->ssocket = NULL; in generic_ip_connect()
3793 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; in ip_connect()
3794 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; in ip_connect()
3796 if (server->dstaddr.ss_family == AF_INET6) in ip_connect()
3797 sport = &addr6->sin6_port; in ip_connect()
3799 sport = &addr->sin_port; in ip_connect()
3818 void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, in reset_cifs_unix_caps() argument
3825 * Perhaps we could add a backpointer to array of sb from tcon in reset_cifs_unix_caps()
3827 * sb as NFS - then we only have one backpointer to sb. in reset_cifs_unix_caps()
3830 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); in reset_cifs_unix_caps()
3832 if (vol_info && vol_info->no_linux_ext) { in reset_cifs_unix_caps()
3833 tcon->fsUnixInfo.Capability = 0; in reset_cifs_unix_caps()
3834 tcon->unix_ext = 0; /* Unix Extensions disabled */ in reset_cifs_unix_caps()
3838 tcon->unix_ext = 1; /* Unix Extensions supported */ in reset_cifs_unix_caps()
3840 if (tcon->unix_ext == 0) { in reset_cifs_unix_caps()
3845 if (!CIFSSMBQFSUnixInfo(xid, tcon)) { in reset_cifs_unix_caps()
3846 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); in reset_cifs_unix_caps()
3866 cifs_dbg(VFS, "per-share encryption not supported yet\n"); in reset_cifs_unix_caps()
3869 if (vol_info && vol_info->no_psx_acl) in reset_cifs_unix_caps()
3874 cifs_sb->mnt_cifs_flags |= in reset_cifs_unix_caps()
3878 if (vol_info && vol_info->posix_paths == 0) in reset_cifs_unix_caps()
3883 cifs_sb->mnt_cifs_flags |= in reset_cifs_unix_caps()
3908 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { in reset_cifs_unix_caps()
3921 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); in cifs_setup_cifs_sb()
3923 spin_lock_init(&cifs_sb->tlink_tree_lock); in cifs_setup_cifs_sb()
3924 cifs_sb->tlink_tree = RB_ROOT; in cifs_setup_cifs_sb()
3926 cifs_sb->bsize = pvolume_info->bsize; in cifs_setup_cifs_sb()
3931 cifs_sb->rsize = pvolume_info->rsize; in cifs_setup_cifs_sb()
3932 cifs_sb->wsize = pvolume_info->wsize; in cifs_setup_cifs_sb()
3934 cifs_sb->mnt_uid = pvolume_info->linux_uid; in cifs_setup_cifs_sb()
3935 cifs_sb->mnt_gid = pvolume_info->linux_gid; in cifs_setup_cifs_sb()
3936 cifs_sb->mnt_file_mode = pvolume_info->file_mode; in cifs_setup_cifs_sb()
3937 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; in cifs_setup_cifs_sb()
3939 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); in cifs_setup_cifs_sb()
3941 cifs_sb->actimeo = pvolume_info->actimeo; in cifs_setup_cifs_sb()
3942 cifs_sb->local_nls = pvolume_info->local_nls; in cifs_setup_cifs_sb()
3944 if (pvolume_info->nodfs) in cifs_setup_cifs_sb()
3945 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS; in cifs_setup_cifs_sb()
3946 if (pvolume_info->noperm) in cifs_setup_cifs_sb()
3947 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; in cifs_setup_cifs_sb()
3948 if (pvolume_info->setuids) in cifs_setup_cifs_sb()
3949 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; in cifs_setup_cifs_sb()
3950 if (pvolume_info->setuidfromacl) in cifs_setup_cifs_sb()
3951 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL; in cifs_setup_cifs_sb()
3952 if (pvolume_info->server_ino) in cifs_setup_cifs_sb()
3953 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; in cifs_setup_cifs_sb()
3954 if (pvolume_info->remap) in cifs_setup_cifs_sb()
3955 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR; in cifs_setup_cifs_sb()
3956 if (pvolume_info->sfu_remap) in cifs_setup_cifs_sb()
3957 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; in cifs_setup_cifs_sb()
3958 if (pvolume_info->no_xattr) in cifs_setup_cifs_sb()
3959 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; in cifs_setup_cifs_sb()
3960 if (pvolume_info->sfu_emul) in cifs_setup_cifs_sb()
3961 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; in cifs_setup_cifs_sb()
3962 if (pvolume_info->nobrl) in cifs_setup_cifs_sb()
3963 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; in cifs_setup_cifs_sb()
3964 if (pvolume_info->nohandlecache) in cifs_setup_cifs_sb()
3965 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE; in cifs_setup_cifs_sb()
3966 if (pvolume_info->nostrictsync) in cifs_setup_cifs_sb()
3967 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; in cifs_setup_cifs_sb()
3968 if (pvolume_info->mand_lock) in cifs_setup_cifs_sb()
3969 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; in cifs_setup_cifs_sb()
3970 if (pvolume_info->rwpidforward) in cifs_setup_cifs_sb()
3971 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; in cifs_setup_cifs_sb()
3972 if (pvolume_info->mode_ace) in cifs_setup_cifs_sb()
3973 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID; in cifs_setup_cifs_sb()
3974 if (pvolume_info->cifs_acl) in cifs_setup_cifs_sb()
3975 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; in cifs_setup_cifs_sb()
3976 if (pvolume_info->backupuid_specified) { in cifs_setup_cifs_sb()
3977 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; in cifs_setup_cifs_sb()
3978 cifs_sb->mnt_backupuid = pvolume_info->backupuid; in cifs_setup_cifs_sb()
3980 if (pvolume_info->backupgid_specified) { in cifs_setup_cifs_sb()
3981 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; in cifs_setup_cifs_sb()
3982 cifs_sb->mnt_backupgid = pvolume_info->backupgid; in cifs_setup_cifs_sb()
3984 if (pvolume_info->override_uid) in cifs_setup_cifs_sb()
3985 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; in cifs_setup_cifs_sb()
3986 if (pvolume_info->override_gid) in cifs_setup_cifs_sb()
3987 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; in cifs_setup_cifs_sb()
3988 if (pvolume_info->dynperm) in cifs_setup_cifs_sb()
3989 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; in cifs_setup_cifs_sb()
3990 if (pvolume_info->fsc) in cifs_setup_cifs_sb()
3991 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; in cifs_setup_cifs_sb()
3992 if (pvolume_info->multiuser) in cifs_setup_cifs_sb()
3993 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | in cifs_setup_cifs_sb()
3995 if (pvolume_info->strict_io) in cifs_setup_cifs_sb()
3996 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; in cifs_setup_cifs_sb()
3997 if (pvolume_info->direct_io) { in cifs_setup_cifs_sb()
3999 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; in cifs_setup_cifs_sb()
4001 if (pvolume_info->cache_ro) { in cifs_setup_cifs_sb()
4003 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; in cifs_setup_cifs_sb()
4004 } else if (pvolume_info->cache_rw) { in cifs_setup_cifs_sb()
4006 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | in cifs_setup_cifs_sb()
4009 if (pvolume_info->mfsymlinks) { in cifs_setup_cifs_sb()
4010 if (pvolume_info->sfu_emul) { in cifs_setup_cifs_sb()
4024 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; in cifs_setup_cifs_sb()
4027 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) in cifs_setup_cifs_sb()
4030 if (pvolume_info->prepath) { in cifs_setup_cifs_sb()
4031 cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL); in cifs_setup_cifs_sb()
4032 if (cifs_sb->prepath == NULL) in cifs_setup_cifs_sb()
4033 return -ENOMEM; in cifs_setup_cifs_sb()
4034 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in cifs_setup_cifs_sb()
4043 kfree(volume_info->username); in cifs_cleanup_volume_info_contents()
4044 kfree_sensitive(volume_info->password); in cifs_cleanup_volume_info_contents()
4045 kfree(volume_info->UNC); in cifs_cleanup_volume_info_contents()
4046 kfree(volume_info->domainname); in cifs_cleanup_volume_info_contents()
4047 kfree(volume_info->iocharset); in cifs_cleanup_volume_info_contents()
4048 kfree(volume_info->prepath); in cifs_cleanup_volume_info_contents()
4064 struct cifs_ses *ses, struct cifs_tcon *tcon) in mount_put_conns() argument
4068 if (tcon) in mount_put_conns()
4069 cifs_put_tcon(tcon); in mount_put_conns()
4074 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS; in mount_put_conns()
4078 /* Get connections for tcp, ses and tcon */
4087 struct cifs_tcon *tcon; in mount_get_conns() local
4113 if ((vol->persistent == true) && (!(ses->server->capabilities & in mount_get_conns()
4116 return -EOPNOTSUPP; in mount_get_conns()
4119 /* search for existing tcon to this server share */ in mount_get_conns()
4120 tcon = cifs_get_tcon(ses, vol); in mount_get_conns()
4121 if (IS_ERR(tcon)) { in mount_get_conns()
4122 rc = PTR_ERR(tcon); in mount_get_conns()
4126 *ntcon = tcon; in mount_get_conns()
4129 if (tcon->posix_extensions) in mount_get_conns()
4130 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; in mount_get_conns()
4133 if (cap_unix(tcon->ses)) { in mount_get_conns()
4138 reset_cifs_unix_caps(*xid, tcon, cifs_sb, vol); in mount_get_conns()
4139 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && in mount_get_conns()
4140 (le64_to_cpu(tcon->fsUnixInfo.Capability) & in mount_get_conns()
4142 return -EACCES; in mount_get_conns()
4144 tcon->unix_ext = 0; /* server does not support them */ in mount_get_conns()
4146 /* do not care if a following call succeed - informational */ in mount_get_conns()
4147 if (!tcon->pipe && server->ops->qfs_tcon) { in mount_get_conns()
4148 server->ops->qfs_tcon(*xid, tcon, cifs_sb); in mount_get_conns()
4149 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { in mount_get_conns()
4150 if (tcon->fsDevInfo.DeviceCharacteristics & in mount_get_conns()
4153 else if ((cifs_sb->mnt_cifs_flags & in mount_get_conns()
4160 cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol); in mount_get_conns()
4161 cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol); in mount_get_conns()
4167 struct cifs_tcon *tcon) in mount_setup_tlink() argument
4171 /* hang the tcon off of the superblock */ in mount_setup_tlink()
4174 return -ENOMEM; in mount_setup_tlink()
4176 tlink->tl_uid = ses->linux_uid; in mount_setup_tlink()
4177 tlink->tl_tcon = tcon; in mount_setup_tlink()
4178 tlink->tl_time = jiffies; in mount_setup_tlink()
4179 set_bit(TCON_LINK_MASTER, &tlink->tl_flags); in mount_setup_tlink()
4180 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in mount_setup_tlink()
4182 cifs_sb->master_tlink = tlink; in mount_setup_tlink()
4183 spin_lock(&cifs_sb->tlink_tree_lock); in mount_setup_tlink()
4184 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); in mount_setup_tlink()
4185 spin_unlock(&cifs_sb->tlink_tree_lock); in mount_setup_tlink()
4187 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, in mount_setup_tlink()
4195 * exiting connection (tcon)
4202 unsigned int pplen = useppath && vol->prepath ? in build_unc_path_to_root()
4203 strlen(vol->prepath) + 1 : 0; in build_unc_path_to_root()
4204 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); in build_unc_path_to_root()
4207 return ERR_PTR(-EINVAL); in build_unc_path_to_root()
4211 return ERR_PTR(-ENOMEM); in build_unc_path_to_root()
4213 memcpy(full_path, vol->UNC, unc_len); in build_unc_path_to_root()
4218 memcpy(pos + 1, vol->prepath, pplen); in build_unc_path_to_root()
4229 * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
4232 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
4248 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) in expand_dfs_referral()
4249 return -EREMOTE; in expand_dfs_referral()
4255 rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), in expand_dfs_referral()
4260 mdata = cifs_compose_mount_options(cifs_sb->mountdata, in expand_dfs_referral()
4274 kfree(cifs_sb->mountdata); in expand_dfs_referral()
4275 cifs_sb->mountdata = mdata; in expand_dfs_referral()
4289 return !*tgt_it ? -EHOSTDOWN : 0; in get_next_dfs_tgt()
4301 return -ENOMEM; in update_vol_info()
4304 kfree(vol->UNC); in update_vol_info()
4305 vol->UNC = new_unc; in update_vol_info()
4307 if (fake_vol->prepath) { in update_vol_info()
4308 kfree(vol->prepath); in update_vol_info()
4309 vol->prepath = fake_vol->prepath; in update_vol_info()
4310 fake_vol->prepath = NULL; in update_vol_info()
4312 memcpy(&vol->dstaddr, &fake_vol->dstaddr, sizeof(vol->dstaddr)); in update_vol_info()
4321 struct cifs_tcon **tcon) in setup_dfs_tgt_conn() argument
4334 mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref, &fake_devname); in setup_dfs_tgt_conn()
4354 mount_put_conns(cifs_sb, *xid, *server, *ses, *tcon); in setup_dfs_tgt_conn()
4356 tcon); in setup_dfs_tgt_conn()
4372 struct cifs_tcon **tcon) in do_dfs_failover() argument
4378 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) in do_dfs_failover()
4379 return -EOPNOTSUPP; in do_dfs_failover()
4386 /* Get next DFS target server - if any */ in do_dfs_failover()
4392 tcon); in do_dfs_failover()
4402 cifs_sb->local_nls, in do_dfs_failover()
4418 return -EINVAL; in cifs_setup_volume_info()
4420 if (volume_info->nullauth) { in cifs_setup_volume_info()
4422 kfree(volume_info->username); in cifs_setup_volume_info()
4423 volume_info->username = NULL; in cifs_setup_volume_info()
4424 } else if (volume_info->username) { in cifs_setup_volume_info()
4426 cifs_dbg(FYI, "Username: %s\n", volume_info->username); in cifs_setup_volume_info()
4431 return -EINVAL; in cifs_setup_volume_info()
4435 if (volume_info->iocharset == NULL) { in cifs_setup_volume_info()
4437 volume_info->local_nls = load_nls_default(); in cifs_setup_volume_info()
4439 volume_info->local_nls = load_nls(volume_info->iocharset); in cifs_setup_volume_info()
4440 if (volume_info->local_nls == NULL) { in cifs_setup_volume_info()
4442 volume_info->iocharset); in cifs_setup_volume_info()
4443 return -ELIBACC; in cifs_setup_volume_info()
4458 return ERR_PTR(-ENOMEM); in cifs_get_volume_info()
4472 struct cifs_tcon *tcon, in cifs_are_all_path_components_accessible() argument
4485 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, ""); in cifs_are_all_path_components_accessible()
4504 * temporarily null-terminate the path at the end of in cifs_are_all_path_components_accessible()
4509 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, in cifs_are_all_path_components_accessible()
4517 * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is,
4523 struct cifs_tcon *tcon) in is_path_remote() argument
4528 if (!server->ops->is_path_accessible) in is_path_remote()
4529 return -EOPNOTSUPP; in is_path_remote()
4532 * cifs_build_path_to_root works only when we have a valid tcon in is_path_remote()
4534 full_path = cifs_build_path_to_root(vol, cifs_sb, tcon, in is_path_remote()
4535 tcon->Flags & SMB_SHARE_IS_IN_DFS); in is_path_remote()
4537 return -ENOMEM; in is_path_remote()
4541 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, in is_path_remote()
4543 if (rc != 0 && rc != -EREMOTE) { in is_path_remote()
4548 if (rc != -EREMOTE) { in is_path_remote()
4549 rc = cifs_are_all_path_components_accessible(server, xid, tcon, in is_path_remote()
4550 cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); in is_path_remote()
4553 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in is_path_remote()
4568 ses->ses_count++; in set_root_ses()
4569 if (ses->tcon_ipc) in set_root_ses()
4570 ses->tcon_ipc->remap = cifs_remap(cifs_sb); in set_root_ses()
4585 struct cifs_tcon *tcon, char **dfs_path) in check_dfs_prepath() argument
4591 int added_treename = tcon->Flags & SMB_SHARE_IS_IN_DFS; in check_dfs_prepath()
4594 path = cifs_build_path_to_root(vol, cifs_sb, tcon, added_treename); in check_dfs_prepath()
4596 return -ENOMEM; in check_dfs_prepath()
4600 * the components is -EREMOTE, then update @dfs_path with the next DFS referral request path in check_dfs_prepath()
4623 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, path); in check_dfs_prepath()
4624 if (rc && rc == -EREMOTE) { in check_dfs_prepath()
4631 rc = -EREMOTE; in check_dfs_prepath()
4635 v.UNC = vol->UNC; in check_dfs_prepath()
4659 struct cifs_tcon *tcon = NULL; in cifs_mount() local
4665 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4673 if (dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), vol->UNC + 1, NULL, in cifs_mount()
4679 rc = is_path_remote(cifs_sb, vol, xid, server, tcon); in cifs_mount()
4682 if (rc != -EREMOTE) in cifs_mount()
4686 mntdata = kstrndup(cifs_sb->mountdata, strlen(cifs_sb->mountdata), GFP_KERNEL); in cifs_mount()
4688 rc = -ENOMEM; in cifs_mount()
4710 oldmnt = cifs_sb->mountdata; in cifs_mount()
4715 if (oldmnt != cifs_sb->mountdata) { in cifs_mount()
4716 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4717 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4722 &server, &ses, &tcon); in cifs_mount()
4724 if (rc == -EACCES || rc == -EOPNOTSUPP || !server || !ses) in cifs_mount()
4726 if (!tcon) in cifs_mount()
4729 if (is_tcon_dfs(tcon)) { in cifs_mount()
4733 /* Check for remaining path components and then continue chasing them (-EREMOTE) */ in cifs_mount()
4734 rc = check_dfs_prepath(cifs_sb, vol, xid, server, tcon, &ref_path); in cifs_mount()
4736 if (rc == -EREMOTE && ++count > MAX_NESTED_LINKS) in cifs_mount()
4737 rc = -ELOOP; in cifs_mount()
4738 } while (rc == -EREMOTE); in cifs_mount()
4749 * For DFS root mounts, the prefix path (cifs_sb->prepath) is preserved during reconnect so in cifs_mount()
4750 * only the root path is set in cifs_sb->origin_fullpath and tcon->dfs_path. And for DFS in cifs_mount()
4754 cifs_sb->origin_fullpath = kstrndup(full_path, strlen(full_path), GFP_KERNEL); in cifs_mount()
4755 if (!cifs_sb->origin_fullpath) { in cifs_mount()
4756 rc = -ENOMEM; in cifs_mount()
4760 tcon->dfs_path = full_path; in cifs_mount()
4762 tcon->remap = cifs_remap(cifs_sb); in cifs_mount()
4766 rc = dfs_cache_add_vol(mntdata, vol, cifs_sb->origin_fullpath); in cifs_mount()
4779 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in cifs_mount()
4780 kfree(cifs_sb->prepath); in cifs_mount()
4781 cifs_sb->prepath = vol->prepath; in cifs_mount()
4782 vol->prepath = NULL; in cifs_mount()
4787 return mount_setup_tlink(cifs_sb, ses, tcon); in cifs_mount()
4793 kfree(cifs_sb->origin_fullpath); in cifs_mount()
4795 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4804 struct cifs_tcon *tcon; in cifs_mount() local
4807 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4811 if (tcon) { in cifs_mount()
4812 rc = is_path_remote(cifs_sb, vol, xid, server, tcon); in cifs_mount()
4813 if (rc == -EREMOTE) in cifs_mount()
4814 rc = -EOPNOTSUPP; in cifs_mount()
4821 return mount_setup_tlink(cifs_sb, ses, tcon); in cifs_mount()
4824 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4834 const char *tree, struct cifs_tcon *tcon, in CIFSTCon() argument
4847 return -EIO; in CIFSTCon()
4851 return -ENOMEM; in CIFSTCon()
4858 smb_buffer->Mid = get_next_mid(ses->server); in CIFSTCon()
4859 smb_buffer->Uid = ses->Suid; in CIFSTCon()
4863 pSMB->AndXCommand = 0xFF; in CIFSTCon()
4864 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); in CIFSTCon()
4865 bcc_ptr = &pSMB->Password[0]; in CIFSTCon()
4866 if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) { in CIFSTCon()
4867 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ in CIFSTCon()
4872 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); in CIFSTCon()
4881 (ses->sectype == LANMAN)) in CIFSTCon()
4882 calc_lanman_hash(tcon->password, ses->server->cryptkey, in CIFSTCon()
4883 ses->server->sec_mode & in CIFSTCon()
4888 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey, in CIFSTCon()
4898 if (ses->capabilities & CAP_UNICODE) { in CIFSTCon()
4905 if (ses->server->sign) in CIFSTCon()
4906 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; in CIFSTCon()
4908 if (ses->capabilities & CAP_STATUS32) { in CIFSTCon()
4909 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; in CIFSTCon()
4911 if (ses->capabilities & CAP_DFS) { in CIFSTCon()
4912 smb_buffer->Flags2 |= SMBFLG2_DFS; in CIFSTCon()
4914 if (ses->capabilities & CAP_UNICODE) { in CIFSTCon()
4915 smb_buffer->Flags2 |= SMBFLG2_UNICODE; in CIFSTCon()
4929 count = bcc_ptr - &pSMB->Password[0]; in CIFSTCon()
4930 be32_add_cpu(&pSMB->hdr.smb_buf_length, count); in CIFSTCon()
4931 pSMB->ByteCount = cpu_to_le16(count); in CIFSTCon()
4940 tcon->tidStatus = CifsGood; in CIFSTCon()
4941 tcon->need_reconnect = false; in CIFSTCon()
4942 tcon->tid = smb_buffer_response->Tid; in CIFSTCon()
4945 length = strnlen(bcc_ptr, bytes_left - 2); in CIFSTCon()
4946 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) in CIFSTCon()
4957 tcon->ipc = true; in CIFSTCon()
4958 tcon->pipe = true; in CIFSTCon()
4967 bytes_left -= (length + 1); in CIFSTCon()
4968 strlcpy(tcon->treeName, tree, sizeof(tcon->treeName)); in CIFSTCon()
4970 /* mostly informational -- no need to fail on error here */ in CIFSTCon()
4971 kfree(tcon->nativeFileSystem); in CIFSTCon()
4972 tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr, in CIFSTCon()
4976 cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem); in CIFSTCon()
4978 if ((smb_buffer_response->WordCount == 3) || in CIFSTCon()
4979 (smb_buffer_response->WordCount == 7)) in CIFSTCon()
4981 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); in CIFSTCon()
4983 tcon->Flags = 0; in CIFSTCon()
4984 cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); in CIFSTCon()
4994 unload_nls(sbi->local_nls); in delayed_free()
5001 struct rb_root *root = &cifs_sb->tlink_tree; in cifs_umount()
5005 cancel_delayed_work_sync(&cifs_sb->prune_tlinks); in cifs_umount()
5007 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5011 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in cifs_umount()
5014 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5016 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5018 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5020 kfree(cifs_sb->mountdata); in cifs_umount()
5021 kfree(cifs_sb->prepath); in cifs_umount()
5023 dfs_cache_del_vol(cifs_sb->origin_fullpath); in cifs_umount()
5024 kfree(cifs_sb->origin_fullpath); in cifs_umount()
5026 call_rcu(&cifs_sb->rcu, delayed_free); in cifs_umount()
5035 if (!server->ops->need_neg || !server->ops->negotiate) in cifs_negotiate_protocol()
5036 return -ENOSYS; in cifs_negotiate_protocol()
5039 if (!server->ops->need_neg(server)) in cifs_negotiate_protocol()
5042 rc = server->ops->negotiate(xid, ses); in cifs_negotiate_protocol()
5045 if (server->tcpStatus == CifsNeedNegotiate) in cifs_negotiate_protocol()
5046 server->tcpStatus = CifsGood; in cifs_negotiate_protocol()
5048 rc = -EHOSTDOWN; in cifs_negotiate_protocol()
5059 int rc = -ENOSYS; in cifs_setup_session()
5062 if (!ses->binding) { in cifs_setup_session()
5063 ses->capabilities = server->capabilities; in cifs_setup_session()
5065 ses->capabilities &= (~server->vals->cap_unix); in cifs_setup_session()
5067 if (ses->auth_key.response) { in cifs_setup_session()
5069 ses->auth_key.response); in cifs_setup_session()
5070 kfree(ses->auth_key.response); in cifs_setup_session()
5071 ses->auth_key.response = NULL; in cifs_setup_session()
5072 ses->auth_key.len = 0; in cifs_setup_session()
5077 server->sec_mode, server->capabilities, server->timeAdj); in cifs_setup_session()
5079 if (server->ops->sess_setup) in cifs_setup_session()
5080 rc = server->ops->sess_setup(xid, ses, nls_info); in cifs_setup_session()
5091 vol->sectype = ses->sectype; in cifs_set_vol_auth()
5094 if (vol->sectype == Kerberos) in cifs_set_vol_auth()
5106 struct cifs_tcon *tcon = NULL; in cifs_construct_tcon() local
5111 return ERR_PTR(-ENOMEM); in cifs_construct_tcon()
5113 vol_info->local_nls = cifs_sb->local_nls; in cifs_construct_tcon()
5114 vol_info->linux_uid = fsuid; in cifs_construct_tcon()
5115 vol_info->cred_uid = fsuid; in cifs_construct_tcon()
5116 vol_info->UNC = master_tcon->treeName; in cifs_construct_tcon()
5117 vol_info->retry = master_tcon->retry; in cifs_construct_tcon()
5118 vol_info->nocase = master_tcon->nocase; in cifs_construct_tcon()
5119 vol_info->nohandlecache = master_tcon->nohandlecache; in cifs_construct_tcon()
5120 vol_info->local_lease = master_tcon->local_lease; in cifs_construct_tcon()
5121 vol_info->no_lease = master_tcon->no_lease; in cifs_construct_tcon()
5122 vol_info->resilient = master_tcon->use_resilient; in cifs_construct_tcon()
5123 vol_info->persistent = master_tcon->use_persistent; in cifs_construct_tcon()
5124 vol_info->handle_timeout = master_tcon->handle_timeout; in cifs_construct_tcon()
5125 vol_info->no_linux_ext = !master_tcon->unix_ext; in cifs_construct_tcon()
5126 vol_info->linux_ext = master_tcon->posix_extensions; in cifs_construct_tcon()
5127 vol_info->sectype = master_tcon->ses->sectype; in cifs_construct_tcon()
5128 vol_info->sign = master_tcon->ses->sign; in cifs_construct_tcon()
5129 vol_info->seal = master_tcon->seal; in cifs_construct_tcon()
5131 rc = cifs_set_vol_auth(vol_info, master_tcon->ses); in cifs_construct_tcon()
5133 tcon = ERR_PTR(rc); in cifs_construct_tcon()
5139 ++master_tcon->ses->server->srv_count; in cifs_construct_tcon()
5142 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); in cifs_construct_tcon()
5144 tcon = (struct cifs_tcon *)ses; in cifs_construct_tcon()
5145 cifs_put_tcp_session(master_tcon->ses->server, 0); in cifs_construct_tcon()
5149 tcon = cifs_get_tcon(ses, vol_info); in cifs_construct_tcon()
5150 if (IS_ERR(tcon)) { in cifs_construct_tcon()
5156 reset_cifs_unix_caps(0, tcon, NULL, vol_info); in cifs_construct_tcon()
5159 kfree(vol_info->username); in cifs_construct_tcon()
5160 kfree_sensitive(vol_info->password); in cifs_construct_tcon()
5163 return tcon; in cifs_construct_tcon()
5176 struct rb_node *node = root->rb_node; in tlink_rb_search()
5182 if (uid_gt(tlink->tl_uid, uid)) in tlink_rb_search()
5183 node = node->rb_left; in tlink_rb_search()
5184 else if (uid_lt(tlink->tl_uid, uid)) in tlink_rb_search()
5185 node = node->rb_right; in tlink_rb_search()
5196 struct rb_node **new = &(root->rb_node), *parent = NULL; in tlink_rb_insert()
5203 if (uid_gt(tlink->tl_uid, new_tlink->tl_uid)) in tlink_rb_insert()
5204 new = &((*new)->rb_left); in tlink_rb_insert()
5206 new = &((*new)->rb_right); in tlink_rb_insert()
5209 rb_link_node(&new_tlink->tl_rbnode, parent, new); in tlink_rb_insert()
5210 rb_insert_color(&new_tlink->tl_rbnode, root); in tlink_rb_insert()
5214 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
5218 * the master tcon for the mount.
5220 * First, search the rbtree for an existing tcon for this fsuid. If one
5236 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) in cifs_sb_tlink()
5239 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5240 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); in cifs_sb_tlink()
5243 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5248 return ERR_PTR(-ENOMEM); in cifs_sb_tlink()
5249 newtlink->tl_uid = fsuid; in cifs_sb_tlink()
5250 newtlink->tl_tcon = ERR_PTR(-EACCES); in cifs_sb_tlink()
5251 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); in cifs_sb_tlink()
5252 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); in cifs_sb_tlink()
5255 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5257 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); in cifs_sb_tlink()
5260 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5265 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); in cifs_sb_tlink()
5266 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5269 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, in cifs_sb_tlink()
5273 return ERR_PTR(-ERESTARTSYS); in cifs_sb_tlink()
5277 if (!IS_ERR(tlink->tl_tcon)) in cifs_sb_tlink()
5281 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) { in cifs_sb_tlink()
5283 return ERR_PTR(-EACCES); in cifs_sb_tlink()
5286 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags)) in cifs_sb_tlink()
5290 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid); in cifs_sb_tlink()
5291 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags); in cifs_sb_tlink()
5292 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING); in cifs_sb_tlink()
5294 if (IS_ERR(tlink->tl_tcon)) { in cifs_sb_tlink()
5296 return ERR_PTR(-EACCES); in cifs_sb_tlink()
5311 struct rb_root *root = &cifs_sb->tlink_tree; in cifs_prune_tlinks()
5320 * umounts. Because this function is non-reentrant and is canceled in cifs_prune_tlinks()
5323 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5330 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || in cifs_prune_tlinks()
5331 atomic_read(&tlink->tl_count) != 0 || in cifs_prune_tlinks()
5332 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) in cifs_prune_tlinks()
5336 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in cifs_prune_tlinks()
5339 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5341 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5343 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5345 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, in cifs_prune_tlinks()
5350 int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) in cifs_tree_connect() argument
5353 struct TCP_Server_Info *server = tcon->ses->server; in cifs_tree_connect()
5354 const struct smb_version_operations *ops = server->ops; in cifs_tree_connect()
5368 return -ENOMEM; in cifs_tree_connect()
5371 if (!tcon->dfs_path || dfs_cache_noreq_find(tcon->dfs_path + 1, &ref, &tl)) { in cifs_tree_connect()
5372 if (tcon->ipc) { in cifs_tree_connect()
5373 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); in cifs_tree_connect()
5374 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5376 rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); in cifs_tree_connect()
5384 extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len); in cifs_tree_connect()
5394 rc = dfs_cache_get_tgt_share(tcon->dfs_path + 1, it, &share, &prefix); in cifs_tree_connect()
5420 if (tcon->ipc) { in cifs_tree_connect()
5422 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5425 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5428 rc = update_super_prepath(tcon, prefix); in cifs_tree_connect()
5432 if (rc == -EREMOTE) in cifs_tree_connect()
5441 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1, it); in cifs_tree_connect()
5443 rc = -ENOENT; in cifs_tree_connect()
5451 int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) in cifs_tree_connect() argument
5453 const struct smb_version_operations *ops = tcon->ses->server->ops; in cifs_tree_connect()
5455 return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); in cifs_tree_connect()