• Home
  • Raw
  • Download

Lines Matching +full:tcon +full:- +full:channel

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()
698 smb_msg->msg_control = NULL; in cifs_readv_from_socket()
699 smb_msg->msg_controllen = 0; in cifs_readv_from_socket()
707 return -ECONNABORTED; in cifs_readv_from_socket()
711 return -ECONNABORTED; in cifs_readv_from_socket()
712 if (cifs_rdma_enabled(server) && server->smbd_conn) in cifs_readv_from_socket()
713 length = smbd_recv(server->smbd_conn, smb_msg); in cifs_readv_from_socket()
715 length = sock_recvmsg(server->ssocket, smb_msg, 0); in cifs_readv_from_socket()
717 if (server->tcpStatus == CifsExiting) in cifs_readv_from_socket()
718 return -ESHUTDOWN; in cifs_readv_from_socket()
720 if (server->tcpStatus == CifsNeedReconnect) { in cifs_readv_from_socket()
722 return -ECONNABORTED; in cifs_readv_from_socket()
725 if (length == -ERESTARTSYS || in cifs_readv_from_socket()
726 length == -EAGAIN || in cifs_readv_from_socket()
727 length == -EINTR) { in cifs_readv_from_socket()
741 return -ECONNABORTED; in cifs_readv_from_socket()
801 cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT); in is_smb_response()
816 mid->when_received = jiffies; in dequeue_mid()
820 mid->mid_state = MID_RESPONSE_RECEIVED; in dequeue_mid()
822 mid->mid_state = MID_RESPONSE_MALFORMED; in dequeue_mid()
827 if (mid->mid_flags & MID_DELETED) in dequeue_mid()
830 list_del_init(&mid->qhead); in dequeue_mid()
831 mid->mid_flags |= MID_DELETED; in dequeue_mid()
844 if (server->vals->header_preamble_size) in smb2_get_credits_from_hdr()
847 return le16_to_cpu(shdr->CreditRequest); in smb2_get_credits_from_hdr()
854 if (server->ops->check_trans2 && in handle_mid()
855 server->ops->check_trans2(mid, server, buf, malformed)) in handle_mid()
857 mid->credits_received = smb2_get_credits_from_hdr(buf, server); in handle_mid()
858 mid->resp_buf = buf; in handle_mid()
859 mid->large_buf = server->large_buf; in handle_mid()
860 /* Was previous buf put in mpx struct for multi-rsp? */ in handle_mid()
861 if (!mid->multiRsp) { in handle_mid()
863 if (server->large_buf) in handle_mid()
864 server->bigbuf = NULL; in handle_mid()
866 server->smallbuf = NULL; in handle_mid()
877 list_del_init(&server->tcp_ses_list); in clean_demultiplex_info()
880 cancel_delayed_work_sync(&server->echo); in clean_demultiplex_info()
883 server->tcpStatus = CifsExiting; in clean_demultiplex_info()
885 wake_up_all(&server->response_q); in clean_demultiplex_info()
888 spin_lock(&server->req_lock); in clean_demultiplex_info()
889 if (server->credits <= 0) in clean_demultiplex_info()
890 server->credits = 1; in clean_demultiplex_info()
891 spin_unlock(&server->req_lock); in clean_demultiplex_info()
896 * same server - they now will see the session is in exit state and get in clean_demultiplex_info()
899 wake_up_all(&server->request_q); in clean_demultiplex_info()
904 if (server->ssocket) { in clean_demultiplex_info()
905 sock_release(server->ssocket); in clean_demultiplex_info()
906 server->ssocket = NULL; in clean_demultiplex_info()
909 if (!list_empty(&server->pending_mid_q)) { in clean_demultiplex_info()
916 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { in clean_demultiplex_info()
918 cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid); in clean_demultiplex_info()
919 kref_get(&mid_entry->refcount); in clean_demultiplex_info()
920 mid_entry->mid_state = MID_SHUTDOWN; in clean_demultiplex_info()
921 list_move(&mid_entry->qhead, &dispose_list); in clean_demultiplex_info()
922 mid_entry->mid_flags |= MID_DELETED; in clean_demultiplex_info()
929 cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid); in clean_demultiplex_info()
930 list_del_init(&mid_entry->qhead); in clean_demultiplex_info()
931 mid_entry->callback(mid_entry); in clean_demultiplex_info()
938 if (!list_empty(&server->pending_mid_q)) { in clean_demultiplex_info()
955 kfree(server->hostname); in clean_demultiplex_info()
967 char *buf = server->smallbuf; in standard_receive3()
968 unsigned int pdu_length = server->pdu_size; in standard_receive3()
971 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - in standard_receive3()
972 server->vals->header_preamble_size) { in standard_receive3()
975 return -ECONNABORTED; in standard_receive3()
979 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { in standard_receive3()
980 server->large_buf = true; in standard_receive3()
981 memcpy(server->bigbuf, buf, server->total_read); in standard_receive3()
982 buf = server->bigbuf; in standard_receive3()
986 length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1, in standard_receive3()
987 pdu_length - HEADER_SIZE(server) + 1 in standard_receive3()
988 + server->vals->header_preamble_size); in standard_receive3()
992 server->total_read += length; in standard_receive3()
994 dump_smb(buf, server->total_read); in standard_receive3()
1002 char *buf = server->large_buf ? server->bigbuf : server->smallbuf; in cifs_handle_standard()
1014 length = server->ops->check_message(buf, server->total_read, server); in cifs_handle_standard()
1017 min_t(unsigned int, server->total_read, 48)); in cifs_handle_standard()
1019 if (server->ops->is_session_expired && in cifs_handle_standard()
1020 server->ops->is_session_expired(buf)) { in cifs_handle_standard()
1022 return -1; in cifs_handle_standard()
1025 if (server->ops->is_status_pending && in cifs_handle_standard()
1026 server->ops->is_status_pending(buf, server)) in cifs_handle_standard()
1027 return -1; in cifs_handle_standard()
1044 if (server->vals->header_preamble_size) in smb2_add_credits_from_hdr()
1047 if (shdr->CreditRequest) { in smb2_add_credits_from_hdr()
1048 spin_lock(&server->req_lock); in smb2_add_credits_from_hdr()
1049 server->credits += le16_to_cpu(shdr->CreditRequest); in smb2_add_credits_from_hdr()
1050 spin_unlock(&server->req_lock); in smb2_add_credits_from_hdr()
1051 wake_up(&server->request_q); in smb2_add_credits_from_hdr()
1078 while (server->tcpStatus != CifsExiting) { in cifs_demultiplex_thread()
1085 server->large_buf = false; in cifs_demultiplex_thread()
1086 buf = server->smallbuf; in cifs_demultiplex_thread()
1093 if (server->vals->header_preamble_size == 0) in cifs_demultiplex_thread()
1094 server->total_read = 0; in cifs_demultiplex_thread()
1096 server->total_read = length; in cifs_demultiplex_thread()
1099 * The right amount was read from socket - 4 bytes, in cifs_demultiplex_thread()
1108 server->pdu_size = pdu_length; in cifs_demultiplex_thread()
1111 if (server->pdu_size < HEADER_SIZE(server) - 1 - in cifs_demultiplex_thread()
1112 server->vals->header_preamble_size) { in cifs_demultiplex_thread()
1114 server->pdu_size); in cifs_demultiplex_thread()
1121 buf + server->vals->header_preamble_size, in cifs_demultiplex_thread()
1122 HEADER_SIZE(server) - 1 in cifs_demultiplex_thread()
1123 - server->vals->header_preamble_size); in cifs_demultiplex_thread()
1126 server->total_read += length; in cifs_demultiplex_thread()
1128 if (server->ops->next_header) { in cifs_demultiplex_thread()
1129 next_offset = server->ops->next_header(buf); in cifs_demultiplex_thread()
1131 server->pdu_size = next_offset; in cifs_demultiplex_thread()
1138 if (server->ops->is_transform_hdr && in cifs_demultiplex_thread()
1139 server->ops->receive_transform && in cifs_demultiplex_thread()
1140 server->ops->is_transform_hdr(buf)) { in cifs_demultiplex_thread()
1141 length = server->ops->receive_transform(server, in cifs_demultiplex_thread()
1146 mids[0] = server->ops->find_mid(server, buf); in cifs_demultiplex_thread()
1150 if (!mids[0] || !mids[0]->receive) in cifs_demultiplex_thread()
1153 length = mids[0]->receive(server, mids[0]); in cifs_demultiplex_thread()
1163 if (server->ops->is_status_io_timeout && in cifs_demultiplex_thread()
1164 server->ops->is_status_io_timeout(buf)) { in cifs_demultiplex_thread()
1173 server->lstrp = jiffies; in cifs_demultiplex_thread()
1177 mids[i]->resp_buf_size = server->pdu_size; in cifs_demultiplex_thread()
1179 if (!mids[i]->multiRsp || mids[i]->multiEnd) in cifs_demultiplex_thread()
1180 mids[i]->callback(mids[i]); in cifs_demultiplex_thread()
1183 } else if (server->ops->is_oplock_break && in cifs_demultiplex_thread()
1184 server->ops->is_oplock_break(bufs[i], in cifs_demultiplex_thread()
1195 if (server->ops->dump_detail) in cifs_demultiplex_thread()
1196 server->ops->dump_detail(bufs[i], in cifs_demultiplex_thread()
1203 if (pdu_length > server->pdu_size) { in cifs_demultiplex_thread()
1206 pdu_length -= server->pdu_size; in cifs_demultiplex_thread()
1207 server->total_read = 0; in cifs_demultiplex_thread()
1208 server->large_buf = false; in cifs_demultiplex_thread()
1209 buf = server->smallbuf; in cifs_demultiplex_thread()
1214 /* buffer usually freed in free_mid - need to free it here on exit */ in cifs_demultiplex_thread()
1215 cifs_buf_release(server->bigbuf); in cifs_demultiplex_thread()
1216 if (server->smallbuf) /* no sense logging a debug message if NULL */ in cifs_demultiplex_thread()
1217 cifs_small_buf_release(server->smallbuf); in cifs_demultiplex_thread()
1219 task_to_wake = xchg(&server->tsk, NULL); in cifs_demultiplex_thread()
1222 /* if server->tsk was NULL then wait for a signal before exiting */ in cifs_demultiplex_thread()
1247 return ERR_PTR(-EINVAL); in extract_hostname()
1251 return ERR_PTR(-EINVAL); in extract_hostname()
1256 return ERR_PTR(-EINVAL); in extract_hostname()
1258 len = delim - src; in extract_hostname()
1261 return ERR_PTR(-ENOMEM); in extract_hostname()
1276 return -ENOMEM; in get_option_ul()
1295 return -EINVAL; in get_option_uid()
1313 return -EINVAL; in get_option_gid()
1320 * Parse a devname into substrings and populate the vol->UNC and vol->prepath
1332 return -EINVAL; in cifs_parse_devname()
1338 return -EINVAL; in cifs_parse_devname()
1343 return -EINVAL; in cifs_parse_devname()
1353 vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); in cifs_parse_devname()
1354 if (!vol->UNC) in cifs_parse_devname()
1355 return -ENOMEM; in cifs_parse_devname()
1357 convert_delimiter(vol->UNC, '\\'); in cifs_parse_devname()
1367 vol->prepath = kstrdup(pos, GFP_KERNEL); in cifs_parse_devname()
1368 if (!vol->prepath) in cifs_parse_devname()
1369 return -ENOMEM; in cifs_parse_devname()
1382 short int override_uid = -1; in cifs_parse_mount_options()
1383 short int override_gid = -1; in cifs_parse_mount_options()
1388 char *nodename = utsname()->nodename; in cifs_parse_mount_options()
1395 struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr; in cifs_parse_mount_options()
1401 /* ensure we always start with zeroed-out smb_vol */ in cifs_parse_mount_options()
1409 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); in cifs_parse_mount_options()
1411 vol->source_rfc1001_name[i] = toupper(nodename[i]); in cifs_parse_mount_options()
1413 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0; in cifs_parse_mount_options()
1416 vol->target_rfc1001_name[0] = 0; in cifs_parse_mount_options()
1417 vol->cred_uid = current_uid(); in cifs_parse_mount_options()
1418 vol->linux_uid = current_uid(); in cifs_parse_mount_options()
1419 vol->linux_gid = current_gid(); in cifs_parse_mount_options()
1420 vol->bsize = 1024 * 1024; /* can improve cp performance significantly */ in cifs_parse_mount_options()
1427 vol->remap = true; in cifs_parse_mount_options()
1430 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; in cifs_parse_mount_options()
1432 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ in cifs_parse_mount_options()
1434 vol->posix_paths = 1; in cifs_parse_mount_options()
1436 vol->server_ino = 1; in cifs_parse_mount_options()
1439 vol->strict_io = true; in cifs_parse_mount_options()
1441 vol->actimeo = CIFS_DEF_ACTIMEO; in cifs_parse_mount_options()
1444 vol->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ in cifs_parse_mount_options()
1447 vol->ops = &smb30_operations; in cifs_parse_mount_options()
1448 vol->vals = &smbdefault_values; in cifs_parse_mount_options()
1450 vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; in cifs_parse_mount_options()
1453 vol->multichannel = false; in cifs_parse_mount_options()
1454 vol->max_channels = 1; in cifs_parse_mount_options()
1474 vol->backupuid_specified = false; /* no backup intent for a user */ in cifs_parse_mount_options()
1475 vol->backupgid_specified = false; /* no backup intent for a group */ in cifs_parse_mount_options()
1480 case -ENOMEM: in cifs_parse_mount_options()
1483 case -EINVAL: in cifs_parse_mount_options()
1509 vol->no_xattr = 0; in cifs_parse_mount_options()
1512 vol->no_xattr = 1; in cifs_parse_mount_options()
1527 vol->noblocksnd = 1; in cifs_parse_mount_options()
1530 vol->noautotune = 1; in cifs_parse_mount_options()
1533 vol->no_lease = 1; in cifs_parse_mount_options()
1536 vol->retry = 1; in cifs_parse_mount_options()
1539 vol->retry = 0; in cifs_parse_mount_options()
1542 vol->noperm = 0; in cifs_parse_mount_options()
1545 vol->noperm = 1; in cifs_parse_mount_options()
1548 vol->nodelete = 1; in cifs_parse_mount_options()
1551 vol->sfu_remap = true; in cifs_parse_mount_options()
1552 vol->remap = false; /* disable SFM mapping */ in cifs_parse_mount_options()
1555 vol->sfu_remap = false; in cifs_parse_mount_options()
1558 vol->remap = true; in cifs_parse_mount_options()
1559 vol->sfu_remap = false; /* disable SFU mapping */ in cifs_parse_mount_options()
1562 vol->remap = false; in cifs_parse_mount_options()
1565 vol->sfu_emul = 1; in cifs_parse_mount_options()
1568 vol->sfu_emul = 0; in cifs_parse_mount_options()
1571 vol->nodfs = 1; in cifs_parse_mount_options()
1575 vol->rootfs = true; in cifs_parse_mount_options()
1579 vol->posix_paths = 1; in cifs_parse_mount_options()
1582 vol->posix_paths = 0; in cifs_parse_mount_options()
1585 if (vol->linux_ext) in cifs_parse_mount_options()
1588 vol->no_linux_ext = 1; in cifs_parse_mount_options()
1591 if (vol->no_linux_ext) in cifs_parse_mount_options()
1594 vol->linux_ext = 1; in cifs_parse_mount_options()
1597 vol->nocase = 1; in cifs_parse_mount_options()
1600 vol->nobrl = 0; in cifs_parse_mount_options()
1603 vol->nobrl = 1; in cifs_parse_mount_options()
1609 if (vol->file_mode == in cifs_parse_mount_options()
1611 vol->file_mode = S_IALLUGO; in cifs_parse_mount_options()
1614 vol->nohandlecache = 1; in cifs_parse_mount_options()
1617 vol->nohandlecache = 0; in cifs_parse_mount_options()
1620 vol->mand_lock = 1; in cifs_parse_mount_options()
1623 vol->setuids = 1; in cifs_parse_mount_options()
1626 vol->setuids = 0; in cifs_parse_mount_options()
1629 vol->setuidfromacl = 1; in cifs_parse_mount_options()
1632 vol->dynperm = true; in cifs_parse_mount_options()
1635 vol->dynperm = false; in cifs_parse_mount_options()
1638 vol->retry = 0; in cifs_parse_mount_options()
1641 vol->retry = 1; in cifs_parse_mount_options()
1644 vol->intr = 0; in cifs_parse_mount_options()
1647 vol->intr = 1; in cifs_parse_mount_options()
1650 vol->nostrictsync = 1; in cifs_parse_mount_options()
1653 vol->nostrictsync = 0; in cifs_parse_mount_options()
1656 vol->server_ino = 1; in cifs_parse_mount_options()
1659 vol->server_ino = 0; in cifs_parse_mount_options()
1662 vol->rwpidforward = 1; in cifs_parse_mount_options()
1665 vol->mode_ace = 1; in cifs_parse_mount_options()
1668 vol->cifs_acl = 1; in cifs_parse_mount_options()
1671 vol->cifs_acl = 0; in cifs_parse_mount_options()
1674 vol->no_psx_acl = 0; in cifs_parse_mount_options()
1677 vol->no_psx_acl = 1; in cifs_parse_mount_options()
1680 vol->local_lease = 1; in cifs_parse_mount_options()
1683 vol->sign = true; in cifs_parse_mount_options()
1686 vol->sign = true; in cifs_parse_mount_options()
1687 vol->ignore_signature = true; in cifs_parse_mount_options()
1692 * or per-smb connection option in the protocol in cifs_parse_mount_options()
1693 * vol->secFlg |= CIFSSEC_MUST_SEAL; in cifs_parse_mount_options()
1695 vol->seal = 1; in cifs_parse_mount_options()
1702 cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n"); in cifs_parse_mount_options()
1705 vol->fsc = true; in cifs_parse_mount_options()
1708 vol->mfsymlinks = true; in cifs_parse_mount_options()
1711 vol->multiuser = true; in cifs_parse_mount_options()
1717 vol->nosharesock = true; in cifs_parse_mount_options()
1720 vol->nopersistent = true; in cifs_parse_mount_options()
1721 if (vol->persistent) { in cifs_parse_mount_options()
1728 vol->persistent = true; in cifs_parse_mount_options()
1729 if ((vol->nopersistent) || (vol->resilient)) { in cifs_parse_mount_options()
1736 vol->resilient = true; in cifs_parse_mount_options()
1737 if (vol->persistent) { in cifs_parse_mount_options()
1744 vol->resilient = false; /* already the default */ in cifs_parse_mount_options()
1747 vol->domainauto = true; in cifs_parse_mount_options()
1750 vol->rdma = true; in cifs_parse_mount_options()
1753 vol->multichannel = true; in cifs_parse_mount_options()
1755 if (vol->max_channels < 2) in cifs_parse_mount_options()
1756 vol->max_channels = 2; in cifs_parse_mount_options()
1759 vol->multichannel = false; in cifs_parse_mount_options()
1760 vol->max_channels = 1; in cifs_parse_mount_options()
1763 vol->compression = UNKNOWN_TYPE; in cifs_parse_mount_options()
1770 if (get_option_uid(args, &vol->backupuid)) { in cifs_parse_mount_options()
1775 vol->backupuid_specified = true; in cifs_parse_mount_options()
1778 if (get_option_gid(args, &vol->backupgid)) { in cifs_parse_mount_options()
1783 vol->backupgid_specified = true; in cifs_parse_mount_options()
1786 if (get_option_uid(args, &vol->linux_uid)) { in cifs_parse_mount_options()
1794 if (get_option_uid(args, &vol->cred_uid)) { in cifs_parse_mount_options()
1801 if (get_option_gid(args, &vol->linux_gid)) { in cifs_parse_mount_options()
1814 vol->file_mode = option; in cifs_parse_mount_options()
1822 vol->dir_mode = option; in cifs_parse_mount_options()
1838 vol->min_offload = option; in cifs_parse_mount_options()
1858 vol->bsize = option; in cifs_parse_mount_options()
1866 vol->rsize = option; in cifs_parse_mount_options()
1874 vol->wsize = option; in cifs_parse_mount_options()
1882 vol->actimeo = HZ * option; in cifs_parse_mount_options()
1883 if (vol->actimeo > CIFS_MAX_ACTIMEO) { in cifs_parse_mount_options()
1894 vol->handle_timeout = option; in cifs_parse_mount_options()
1895 if (vol->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { in cifs_parse_mount_options()
1906 vol->echo_interval = option; in cifs_parse_mount_options()
1914 vol->snapshot_time = option; in cifs_parse_mount_options()
1923 vol->max_credits = option; in cifs_parse_mount_options()
1928 cifs_dbg(VFS, "%s: Invalid max_channels value, needs to be 1-%d\n", in cifs_parse_mount_options()
1932 vol->max_channels = option; in cifs_parse_mount_options()
1939 vol->nullauth = 1; in cifs_parse_mount_options()
1940 vol->username = NULL; in cifs_parse_mount_options()
1953 kfree(vol->username); in cifs_parse_mount_options()
1954 vol->username = kstrdup(string, GFP_KERNEL); in cifs_parse_mount_options()
1955 if (!vol->username) in cifs_parse_mount_options()
1972 kfree_sensitive(vol->password); in cifs_parse_mount_options()
1973 vol->password = NULL; in cifs_parse_mount_options()
2010 kfree_sensitive(vol->password); in cifs_parse_mount_options()
2013 vol->password = kzalloc(temp_len+1, GFP_KERNEL); in cifs_parse_mount_options()
2014 if (vol->password == NULL) { in cifs_parse_mount_options()
2020 vol->password[j] = value[i]; in cifs_parse_mount_options()
2026 vol->password[j] = '\0'; in cifs_parse_mount_options()
2055 kfree(vol->domainname); in cifs_parse_mount_options()
2056 vol->domainname = kstrdup(string, GFP_KERNEL); in cifs_parse_mount_options()
2057 if (!vol->domainname) { in cifs_parse_mount_options()
2069 (struct sockaddr *)&vol->srcaddr, in cifs_parse_mount_options()
2087 kfree(vol->iocharset); in cifs_parse_mount_options()
2088 vol->iocharset = kstrdup(string, in cifs_parse_mount_options()
2090 if (!vol->iocharset) { in cifs_parse_mount_options()
2105 memset(vol->source_rfc1001_name, 0x20, in cifs_parse_mount_options()
2116 vol->source_rfc1001_name[i] = string[i]; in cifs_parse_mount_options()
2131 memset(vol->target_rfc1001_name, 0x20, in cifs_parse_mount_options()
2143 vol->target_rfc1001_name[i] = string[i]; in cifs_parse_mount_options()
2214 if (vol->rdma && vol->vals->protocol_id < SMB30_PROT_ID) { in cifs_parse_mount_options()
2221 if (vol->multiuser) { in cifs_parse_mount_options()
2226 if (!vol->UNC) { in cifs_parse_mount_options()
2232 if (!strchr(vol->UNC + 3, '\\')) { in cifs_parse_mount_options()
2243 slash = strchr(&vol->UNC[2], '\\'); in cifs_parse_mount_options()
2244 len = slash - &vol->UNC[2]; in cifs_parse_mount_options()
2245 if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) { in cifs_parse_mount_options()
2255 vol->override_uid = override_uid; in cifs_parse_mount_options()
2260 vol->override_gid = override_gid; in cifs_parse_mount_options()
2285 switch (srcaddr->sa_family) { in cifs_match_ipaddr()
2287 return (rhs->sa_family == AF_UNSPEC); in cifs_match_ipaddr()
2291 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr); in cifs_match_ipaddr()
2296 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr); in cifs_match_ipaddr()
2306 * and if it fails - with 139 ports. It should be called only if address
2315 if (server->rdma) in match_port()
2318 switch (addr->sa_family) { in match_port()
2320 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port; in match_port()
2321 port = ((struct sockaddr_in *) addr)->sin_port; in match_port()
2324 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port; in match_port()
2325 port = ((struct sockaddr_in6 *) addr)->sin6_port; in match_port()
2347 switch (addr->sa_family) { in match_address()
2351 (struct sockaddr_in *)&server->dstaddr; in match_address()
2353 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr) in match_address()
2360 (struct sockaddr_in6 *)&server->dstaddr; in match_address()
2362 if (!ipv6_addr_equal(&addr6->sin6_addr, in match_address()
2363 &srv_addr6->sin6_addr)) in match_address()
2365 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id) in match_address()
2374 if (!cifs_match_ipaddr(srcaddr, (struct sockaddr *)&server->srcaddr)) in match_address()
2384 * The select_sectype function should either return the vol->sectype in match_security()
2388 if (server->ops->select_sectype(server, vol->sectype) in match_security()
2395 * the server->sign had better be too. in match_security()
2397 if (vol->sign && !server->sign) in match_security()
2405 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr; in match_server()
2407 if (vol->nosharesock) in match_server()
2411 if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { in match_server()
2412 if (server->vals->protocol_id < SMB30_PROT_ID) in match_server()
2414 } else if (strcmp(vol->vals->version_string, in match_server()
2416 if (server->vals->protocol_id < SMB21_PROT_ID) in match_server()
2418 } else if ((server->vals != vol->vals) || (server->ops != vol->ops)) in match_server()
2421 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) in match_server()
2425 (struct sockaddr *)&vol->srcaddr)) in match_server()
2434 if (server->echo_interval != vol->echo_interval * HZ) in match_server()
2437 if (server->rdma != vol->rdma) in match_server()
2440 if (server->ignore_signature != vol->ignore_signature) in match_server()
2443 if (server->min_offload != vol->min_offload) in match_server()
2460 if (server->is_channel || !match_server(server, vol)) in cifs_find_tcp_session()
2463 ++server->srv_count; in cifs_find_tcp_session()
2478 if (--server->srv_count > 0) { in cifs_put_tcp_session()
2485 list_del_init(&server->tcp_ses_list); in cifs_put_tcp_session()
2488 cancel_delayed_work_sync(&server->echo); in cifs_put_tcp_session()
2497 cancel_delayed_work(&server->reconnect); in cifs_put_tcp_session()
2499 cancel_delayed_work_sync(&server->reconnect); in cifs_put_tcp_session()
2502 server->tcpStatus = CifsExiting; in cifs_put_tcp_session()
2508 kfree(server->session_key.response); in cifs_put_tcp_session()
2509 server->session_key.response = NULL; in cifs_put_tcp_session()
2510 server->session_key.len = 0; in cifs_put_tcp_session()
2512 task = xchg(&server->tsk, NULL); in cifs_put_tcp_session()
2523 cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC); in cifs_get_tcp_session()
2532 rc = -ENOMEM; in cifs_get_tcp_session()
2536 tcp_ses->ops = volume_info->ops; in cifs_get_tcp_session()
2537 tcp_ses->vals = volume_info->vals; in cifs_get_tcp_session()
2538 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); in cifs_get_tcp_session()
2539 tcp_ses->hostname = extract_hostname(volume_info->UNC); in cifs_get_tcp_session()
2540 if (IS_ERR(tcp_ses->hostname)) { in cifs_get_tcp_session()
2541 rc = PTR_ERR(tcp_ses->hostname); in cifs_get_tcp_session()
2545 tcp_ses->noblockcnt = volume_info->rootfs; in cifs_get_tcp_session()
2546 tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs; in cifs_get_tcp_session()
2547 tcp_ses->noautotune = volume_info->noautotune; in cifs_get_tcp_session()
2548 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; in cifs_get_tcp_session()
2549 tcp_ses->rdma = volume_info->rdma; in cifs_get_tcp_session()
2550 tcp_ses->in_flight = 0; in cifs_get_tcp_session()
2551 tcp_ses->max_in_flight = 0; in cifs_get_tcp_session()
2552 tcp_ses->credits = 1; in cifs_get_tcp_session()
2553 init_waitqueue_head(&tcp_ses->response_q); in cifs_get_tcp_session()
2554 init_waitqueue_head(&tcp_ses->request_q); in cifs_get_tcp_session()
2555 INIT_LIST_HEAD(&tcp_ses->pending_mid_q); in cifs_get_tcp_session()
2556 mutex_init(&tcp_ses->srv_mutex); in cifs_get_tcp_session()
2557 memcpy(tcp_ses->workstation_RFC1001_name, in cifs_get_tcp_session()
2558 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); in cifs_get_tcp_session()
2559 memcpy(tcp_ses->server_RFC1001_name, in cifs_get_tcp_session()
2560 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); in cifs_get_tcp_session()
2561 tcp_ses->session_estab = false; in cifs_get_tcp_session()
2562 tcp_ses->sequence_number = 0; in cifs_get_tcp_session()
2563 tcp_ses->reconnect_instance = 1; in cifs_get_tcp_session()
2564 tcp_ses->lstrp = jiffies; in cifs_get_tcp_session()
2565 tcp_ses->compress_algorithm = cpu_to_le16(volume_info->compression); in cifs_get_tcp_session()
2566 spin_lock_init(&tcp_ses->req_lock); in cifs_get_tcp_session()
2567 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); in cifs_get_tcp_session()
2568 INIT_LIST_HEAD(&tcp_ses->smb_ses_list); in cifs_get_tcp_session()
2569 INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); in cifs_get_tcp_session()
2570 INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); in cifs_get_tcp_session()
2571 mutex_init(&tcp_ses->reconnect_mutex); in cifs_get_tcp_session()
2572 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, in cifs_get_tcp_session()
2573 sizeof(tcp_ses->srcaddr)); in cifs_get_tcp_session()
2574 memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, in cifs_get_tcp_session()
2575 sizeof(tcp_ses->dstaddr)); in cifs_get_tcp_session()
2576 if (volume_info->use_client_guid) in cifs_get_tcp_session()
2577 memcpy(tcp_ses->client_guid, volume_info->client_guid, in cifs_get_tcp_session()
2580 generate_random_uuid(tcp_ses->client_guid); in cifs_get_tcp_session()
2586 tcp_ses->tcpStatus = CifsNew; in cifs_get_tcp_session()
2587 ++tcp_ses->srv_count; in cifs_get_tcp_session()
2589 if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN && in cifs_get_tcp_session()
2590 volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX) in cifs_get_tcp_session()
2591 tcp_ses->echo_interval = volume_info->echo_interval * HZ; in cifs_get_tcp_session()
2593 tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ; in cifs_get_tcp_session()
2594 if (tcp_ses->rdma) { in cifs_get_tcp_session()
2597 rc = -ENOENT; in cifs_get_tcp_session()
2600 tcp_ses->smbd_conn = smbd_get_connection( in cifs_get_tcp_session()
2601 tcp_ses, (struct sockaddr *)&volume_info->dstaddr); in cifs_get_tcp_session()
2602 if (tcp_ses->smbd_conn) { in cifs_get_tcp_session()
2607 rc = -ENOENT; in cifs_get_tcp_session()
2622 tcp_ses->tsk = kthread_run(cifs_demultiplex_thread, in cifs_get_tcp_session()
2624 if (IS_ERR(tcp_ses->tsk)) { in cifs_get_tcp_session()
2625 rc = PTR_ERR(tcp_ses->tsk); in cifs_get_tcp_session()
2630 tcp_ses->min_offload = volume_info->min_offload; in cifs_get_tcp_session()
2631 tcp_ses->tcpStatus = CifsNeedNegotiate; in cifs_get_tcp_session()
2633 if ((volume_info->max_credits < 20) || (volume_info->max_credits > 60000)) in cifs_get_tcp_session()
2634 tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE; in cifs_get_tcp_session()
2636 tcp_ses->max_credits = volume_info->max_credits; in cifs_get_tcp_session()
2638 tcp_ses->nr_targets = 1; in cifs_get_tcp_session()
2639 tcp_ses->ignore_signature = volume_info->ignore_signature; in cifs_get_tcp_session()
2642 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); in cifs_get_tcp_session()
2648 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval); in cifs_get_tcp_session()
2659 if (!IS_ERR(tcp_ses->hostname)) in cifs_get_tcp_session()
2660 kfree(tcp_ses->hostname); in cifs_get_tcp_session()
2661 if (tcp_ses->ssocket) in cifs_get_tcp_session()
2662 sock_release(tcp_ses->ssocket); in cifs_get_tcp_session()
2670 if (vol->sectype != Unspecified && in match_session()
2671 vol->sectype != ses->sectype) in match_session()
2678 if (ses->chan_max < vol->max_channels) in match_session()
2681 switch (ses->sectype) { in match_session()
2683 if (!uid_eq(vol->cred_uid, ses->cred_uid)) in match_session()
2688 if (ses->user_name == NULL) { in match_session()
2689 if (!vol->nullauth) in match_session()
2695 if (strncmp(ses->user_name, in match_session()
2696 vol->username ? vol->username : "", in match_session()
2699 if ((vol->username && strlen(vol->username) != 0) && in match_session()
2700 ses->password != NULL && in match_session()
2701 strncmp(ses->password, in match_session()
2702 vol->password ? vol->password : "", in match_session()
2710 * cifs_setup_ipc - helper to setup the IPC tcon for the session
2713 * tcon_ipc. The IPC tcon has the same lifetime as the session.
2719 struct cifs_tcon *tcon; in cifs_setup_ipc() local
2723 struct TCP_Server_Info *server = ses->server; in cifs_setup_ipc()
2729 if (volume_info->seal) { in cifs_setup_ipc()
2730 if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) in cifs_setup_ipc()
2735 return -EOPNOTSUPP; in cifs_setup_ipc()
2739 tcon = tconInfoAlloc(); in cifs_setup_ipc()
2740 if (tcon == NULL) in cifs_setup_ipc()
2741 return -ENOMEM; in cifs_setup_ipc()
2743 scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname); in cifs_setup_ipc()
2749 tcon->ses = ses; in cifs_setup_ipc()
2750 tcon->ipc = true; in cifs_setup_ipc()
2751 tcon->seal = seal; in cifs_setup_ipc()
2752 rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); in cifs_setup_ipc()
2757 tconInfoFree(tcon); in cifs_setup_ipc()
2761 cifs_dbg(FYI, "IPC tcon rc = %d ipc tid = %d\n", rc, tcon->tid); in cifs_setup_ipc()
2763 ses->tcon_ipc = tcon; in cifs_setup_ipc()
2770 * cifs_free_ipc - helper to release the session IPC tcon
2778 struct cifs_tcon *tcon = ses->tcon_ipc; in cifs_free_ipc() local
2780 if (tcon == NULL) in cifs_free_ipc()
2783 if (ses->server->ops->tree_disconnect) { in cifs_free_ipc()
2785 rc = ses->server->ops->tree_disconnect(xid, tcon); in cifs_free_ipc()
2790 cifs_dbg(FYI, "failed to disconnect IPC tcon (rc=%d)\n", rc); in cifs_free_ipc()
2792 tconInfoFree(tcon); in cifs_free_ipc()
2793 ses->tcon_ipc = NULL; in cifs_free_ipc()
2803 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { in cifs_find_smb_ses()
2804 if (ses->status == CifsExiting) in cifs_find_smb_ses()
2808 ++ses->ses_count; in cifs_find_smb_ses()
2819 struct TCP_Server_Info *server = ses->server; in cifs_put_smb_ses()
2821 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count); in cifs_put_smb_ses()
2824 if (ses->status == CifsExiting) { in cifs_put_smb_ses()
2828 if (--ses->ses_count > 0) { in cifs_put_smb_ses()
2835 if (ses->status == CifsGood) in cifs_put_smb_ses()
2836 ses->status = CifsExiting; in cifs_put_smb_ses()
2841 if (ses->status == CifsExiting && server->ops->logoff) { in cifs_put_smb_ses()
2843 rc = server->ops->logoff(xid, ses); in cifs_put_smb_ses()
2851 list_del_init(&ses->smb_ses_list); in cifs_put_smb_ses()
2855 if (ses->chan_count > 1) { in cifs_put_smb_ses()
2858 for (i = 1; i < ses->chan_count; i++) in cifs_put_smb_ses()
2859 cifs_put_tcp_session(ses->chans[i].server, 0); in cifs_put_smb_ses()
2881 struct TCP_Server_Info *server = ses->server; in cifs_set_cifscreds()
2888 return -ENOMEM; in cifs_set_cifscreds()
2891 switch (server->dstaddr.ss_family) { in cifs_set_cifscreds()
2893 sa = (struct sockaddr_in *)&server->dstaddr; in cifs_set_cifscreds()
2894 sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr); in cifs_set_cifscreds()
2897 sa6 = (struct sockaddr_in6 *)&server->dstaddr; in cifs_set_cifscreds()
2898 sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr); in cifs_set_cifscreds()
2902 server->dstaddr.ss_family); in cifs_set_cifscreds()
2903 rc = -EINVAL; in cifs_set_cifscreds()
2910 if (!ses->domainName) { in cifs_set_cifscreds()
2917 sprintf(desc, "cifs:d:%s", ses->domainName); in cifs_set_cifscreds()
2927 down_read(&key->sem); in cifs_set_cifscreds()
2930 rc = upayload ? PTR_ERR(upayload) : -EINVAL; in cifs_set_cifscreds()
2935 payload = upayload->data; in cifs_set_cifscreds()
2936 delim = strnchr(payload, upayload->datalen, ':'); in cifs_set_cifscreds()
2940 upayload->datalen); in cifs_set_cifscreds()
2941 rc = -EINVAL; in cifs_set_cifscreds()
2945 len = delim - payload; in cifs_set_cifscreds()
2949 rc = -EINVAL; in cifs_set_cifscreds()
2953 vol->username = kstrndup(payload, len, GFP_KERNEL); in cifs_set_cifscreds()
2954 if (!vol->username) { in cifs_set_cifscreds()
2957 rc = -ENOMEM; in cifs_set_cifscreds()
2960 cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username); in cifs_set_cifscreds()
2962 len = key->datalen - (len + 1); in cifs_set_cifscreds()
2965 rc = -EINVAL; in cifs_set_cifscreds()
2966 kfree(vol->username); in cifs_set_cifscreds()
2967 vol->username = NULL; in cifs_set_cifscreds()
2972 vol->password = kstrndup(delim, len, GFP_KERNEL); in cifs_set_cifscreds()
2973 if (!vol->password) { in cifs_set_cifscreds()
2976 rc = -ENOMEM; in cifs_set_cifscreds()
2977 kfree(vol->username); in cifs_set_cifscreds()
2978 vol->username = NULL; in cifs_set_cifscreds()
2986 if (is_domain && ses->domainName) { in cifs_set_cifscreds()
2987 vol->domainname = kstrndup(ses->domainName, in cifs_set_cifscreds()
2988 strlen(ses->domainName), in cifs_set_cifscreds()
2990 if (!vol->domainname) { in cifs_set_cifscreds()
2993 rc = -ENOMEM; in cifs_set_cifscreds()
2994 kfree(vol->username); in cifs_set_cifscreds()
2995 vol->username = NULL; in cifs_set_cifscreds()
2996 kfree_sensitive(vol->password); in cifs_set_cifscreds()
2997 vol->password = NULL; in cifs_set_cifscreds()
3003 up_read(&key->sem); in cifs_set_cifscreds()
3015 return -ENOSYS; in cifs_set_cifscreds()
3020 * cifs_get_smb_ses - get a session matching @volume_info data from @server
3029 int rc = -ENOMEM; in cifs_get_smb_ses()
3032 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; in cifs_get_smb_ses()
3033 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; in cifs_get_smb_ses()
3040 ses->status); in cifs_get_smb_ses()
3042 mutex_lock(&ses->session_mutex); in cifs_get_smb_ses()
3045 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3046 /* problem -- put our ses reference */ in cifs_get_smb_ses()
3051 if (ses->need_reconnect) { in cifs_get_smb_ses()
3054 volume_info->local_nls); in cifs_get_smb_ses()
3056 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3057 /* problem -- put our reference */ in cifs_get_smb_ses()
3063 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3077 ses->server = server; in cifs_get_smb_ses()
3078 if (server->dstaddr.ss_family == AF_INET6) in cifs_get_smb_ses()
3079 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr); in cifs_get_smb_ses()
3081 sprintf(ses->serverName, "%pI4", &addr->sin_addr); in cifs_get_smb_ses()
3083 if (volume_info->username) { in cifs_get_smb_ses()
3084 ses->user_name = kstrdup(volume_info->username, GFP_KERNEL); in cifs_get_smb_ses()
3085 if (!ses->user_name) in cifs_get_smb_ses()
3089 /* volume_info->password freed at unmount */ in cifs_get_smb_ses()
3090 if (volume_info->password) { in cifs_get_smb_ses()
3091 ses->password = kstrdup(volume_info->password, GFP_KERNEL); in cifs_get_smb_ses()
3092 if (!ses->password) in cifs_get_smb_ses()
3095 if (volume_info->domainname) { in cifs_get_smb_ses()
3096 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL); in cifs_get_smb_ses()
3097 if (!ses->domainName) in cifs_get_smb_ses()
3100 if (volume_info->domainauto) in cifs_get_smb_ses()
3101 ses->domainAuto = volume_info->domainauto; in cifs_get_smb_ses()
3102 ses->cred_uid = volume_info->cred_uid; in cifs_get_smb_ses()
3103 ses->linux_uid = volume_info->linux_uid; in cifs_get_smb_ses()
3105 ses->sectype = volume_info->sectype; in cifs_get_smb_ses()
3106 ses->sign = volume_info->sign; in cifs_get_smb_ses()
3107 mutex_lock(&ses->session_mutex); in cifs_get_smb_ses()
3109 /* add server as first channel */ in cifs_get_smb_ses()
3110 ses->chans[0].server = server; in cifs_get_smb_ses()
3111 ses->chan_count = 1; in cifs_get_smb_ses()
3112 ses->chan_max = volume_info->multichannel ? volume_info->max_channels:1; in cifs_get_smb_ses()
3116 rc = cifs_setup_session(xid, ses, volume_info->local_nls); in cifs_get_smb_ses()
3118 /* each channel uses a different signing key */ in cifs_get_smb_ses()
3119 memcpy(ses->chans[0].signkey, ses->smb3signingkey, in cifs_get_smb_ses()
3120 sizeof(ses->smb3signingkey)); in cifs_get_smb_ses()
3122 mutex_unlock(&ses->session_mutex); in cifs_get_smb_ses()
3126 /* success, put it on the list and add it as first channel */ in cifs_get_smb_ses()
3128 list_add(&ses->smb_ses_list, &server->smb_ses_list); in cifs_get_smb_ses()
3143 static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) in match_tcon() argument
3145 if (tcon->tidStatus == CifsExiting) in match_tcon()
3147 if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE)) in match_tcon()
3149 if (tcon->seal != volume_info->seal) in match_tcon()
3151 if (tcon->snapshot_time != volume_info->snapshot_time) in match_tcon()
3153 if (tcon->handle_timeout != volume_info->handle_timeout) in match_tcon()
3155 if (tcon->no_lease != volume_info->no_lease) in match_tcon()
3157 if (tcon->nodelete != volume_info->nodelete) in match_tcon()
3166 struct cifs_tcon *tcon; in cifs_find_tcon() local
3169 list_for_each(tmp, &ses->tcon_list) { in cifs_find_tcon()
3170 tcon = list_entry(tmp, struct cifs_tcon, tcon_list); in cifs_find_tcon()
3172 if (tcon->dfs_path) in cifs_find_tcon()
3175 if (!match_tcon(tcon, volume_info)) in cifs_find_tcon()
3177 ++tcon->tc_count; in cifs_find_tcon()
3179 return tcon; in cifs_find_tcon()
3186 cifs_put_tcon(struct cifs_tcon *tcon) in cifs_put_tcon() argument
3192 * IPC tcon share the lifetime of their session and are in cifs_put_tcon()
3195 if (tcon == NULL || tcon->ipc) in cifs_put_tcon()
3198 ses = tcon->ses; in cifs_put_tcon()
3199 cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count); in cifs_put_tcon()
3201 if (--tcon->tc_count > 0) { in cifs_put_tcon()
3206 list_del_init(&tcon->tcon_list); in cifs_put_tcon()
3210 if (ses->server->ops->tree_disconnect) in cifs_put_tcon()
3211 ses->server->ops->tree_disconnect(xid, tcon); in cifs_put_tcon()
3214 cifs_fscache_release_super_cookie(tcon); in cifs_put_tcon()
3215 tconInfoFree(tcon); in cifs_put_tcon()
3220 * cifs_get_tcon - get a tcon matching @volume_info data from @ses
3222 * - tcon refcount is the number of mount points using the tcon.
3223 * - ses refcount is the number of tcon using the session.
3231 * a) a new tcon already allocated with refcount=1 (1 mount point) and
3232 * its session refcount incremented (1 new tcon). This +1 was
3235 * b) an existing tcon with refcount+1 (add a mount point to it) and
3236 * identical ses refcount (no new tcon). Because of (1) we need to
3243 struct cifs_tcon *tcon; in cifs_get_tcon() local
3245 tcon = cifs_find_tcon(ses, volume_info); in cifs_get_tcon()
3246 if (tcon) { in cifs_get_tcon()
3248 * tcon has refcount already incremented but we need to in cifs_get_tcon()
3253 return tcon; in cifs_get_tcon()
3256 if (!ses->server->ops->tree_connect) { in cifs_get_tcon()
3257 rc = -ENOSYS; in cifs_get_tcon()
3261 tcon = tconInfoAlloc(); in cifs_get_tcon()
3262 if (tcon == NULL) { in cifs_get_tcon()
3263 rc = -ENOMEM; in cifs_get_tcon()
3267 if (volume_info->snapshot_time) { in cifs_get_tcon()
3268 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3271 rc = -EOPNOTSUPP; in cifs_get_tcon()
3274 tcon->snapshot_time = volume_info->snapshot_time; in cifs_get_tcon()
3277 if (volume_info->handle_timeout) { in cifs_get_tcon()
3278 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3281 rc = -EOPNOTSUPP; in cifs_get_tcon()
3284 tcon->handle_timeout = volume_info->handle_timeout; in cifs_get_tcon()
3287 tcon->ses = ses; in cifs_get_tcon()
3288 if (volume_info->password) { in cifs_get_tcon()
3289 tcon->password = kstrdup(volume_info->password, GFP_KERNEL); in cifs_get_tcon()
3290 if (!tcon->password) { in cifs_get_tcon()
3291 rc = -ENOMEM; in cifs_get_tcon()
3296 if (volume_info->seal) { in cifs_get_tcon()
3297 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3300 rc = -EOPNOTSUPP; in cifs_get_tcon()
3302 } else if (tcon->ses->server->capabilities & in cifs_get_tcon()
3304 tcon->seal = true; in cifs_get_tcon()
3307 rc = -EOPNOTSUPP; in cifs_get_tcon()
3312 if (volume_info->linux_ext) { in cifs_get_tcon()
3313 if (ses->server->posix_ext_supported) { in cifs_get_tcon()
3314 tcon->posix_extensions = true; in cifs_get_tcon()
3318 rc = -EOPNOTSUPP; in cifs_get_tcon()
3324 * BB Do we need to wrap session_mutex around this TCon call and Unix in cifs_get_tcon()
3328 rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon, in cifs_get_tcon()
3329 volume_info->local_nls); in cifs_get_tcon()
3331 cifs_dbg(FYI, "Tcon rc = %d\n", rc); in cifs_get_tcon()
3335 tcon->use_persistent = false; in cifs_get_tcon()
3337 if (volume_info->persistent) { in cifs_get_tcon()
3338 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3341 rc = -EOPNOTSUPP; in cifs_get_tcon()
3343 } else if (ses->server->capabilities & in cifs_get_tcon()
3345 tcon->use_persistent = true; in cifs_get_tcon()
3349 rc = -EOPNOTSUPP; in cifs_get_tcon()
3352 } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) in cifs_get_tcon()
3353 && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) in cifs_get_tcon()
3354 && (volume_info->nopersistent == false)) { in cifs_get_tcon()
3356 tcon->use_persistent = true; in cifs_get_tcon()
3357 } else if (volume_info->resilient) { in cifs_get_tcon()
3358 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3361 rc = -EOPNOTSUPP; in cifs_get_tcon()
3364 tcon->use_resilient = true; in cifs_get_tcon()
3368 if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { in cifs_get_tcon()
3369 if (volume_info->cache_ro) in cifs_get_tcon()
3371 else if (volume_info->cache_rw) in cifs_get_tcon()
3375 if (volume_info->no_lease) { in cifs_get_tcon()
3376 if (ses->server->vals->protocol_id == 0) { in cifs_get_tcon()
3379 rc = -EOPNOTSUPP; in cifs_get_tcon()
3382 tcon->no_lease = volume_info->no_lease; in cifs_get_tcon()
3390 tcon->retry = volume_info->retry; in cifs_get_tcon()
3391 tcon->nocase = volume_info->nocase; in cifs_get_tcon()
3392 if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) in cifs_get_tcon()
3393 tcon->nohandlecache = volume_info->nohandlecache; in cifs_get_tcon()
3395 tcon->nohandlecache = 1; in cifs_get_tcon()
3396 tcon->nodelete = volume_info->nodelete; in cifs_get_tcon()
3397 tcon->local_lease = volume_info->local_lease; in cifs_get_tcon()
3398 INIT_LIST_HEAD(&tcon->pending_opens); in cifs_get_tcon()
3401 list_add(&tcon->tcon_list, &ses->tcon_list); in cifs_get_tcon()
3404 cifs_fscache_get_super_cookie(tcon); in cifs_get_tcon()
3406 return tcon; in cifs_get_tcon()
3409 tconInfoFree(tcon); in cifs_get_tcon()
3419 if (!atomic_dec_and_test(&tlink->tl_count) || in cifs_put_tlink()
3420 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) { in cifs_put_tlink()
3421 tlink->tl_time = jiffies; in cifs_put_tlink()
3435 struct cifs_sb_info *new = mnt_data->cifs_sb; in compare_mount_options()
3436 unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK; in compare_mount_options()
3437 unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK; in compare_mount_options()
3439 if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) in compare_mount_options()
3442 if (old->mnt_cifs_serverino_autodisabled) in compare_mount_options()
3452 if (new->wsize && new->wsize < old->wsize) in compare_mount_options()
3455 if (new->rsize && new->rsize < old->rsize) in compare_mount_options()
3458 if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid)) in compare_mount_options()
3461 if (old->mnt_file_mode != new->mnt_file_mode || in compare_mount_options()
3462 old->mnt_dir_mode != new->mnt_dir_mode) in compare_mount_options()
3465 if (strcmp(old->local_nls->charset, new->local_nls->charset)) in compare_mount_options()
3468 if (old->actimeo != new->actimeo) in compare_mount_options()
3478 struct cifs_sb_info *new = mnt_data->cifs_sb; in match_prepath()
3479 bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && in match_prepath()
3480 old->prepath; in match_prepath()
3481 bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && in match_prepath()
3482 new->prepath; in match_prepath()
3484 if (old_set && new_set && !strcmp(new->prepath, old->prepath)) in match_prepath()
3500 struct cifs_tcon *tcon; in cifs_match_super() local
3512 tcon = tlink_tcon(tlink); in cifs_match_super()
3513 ses = tcon->ses; in cifs_match_super()
3514 tcp_srv = ses->server; in cifs_match_super()
3516 volume_info = mnt_data->vol; in cifs_match_super()
3520 !match_tcon(tcon, volume_info) || in cifs_match_super()
3540 struct sock *sk = sock->sk; in cifs_reclassify_socket4()
3542 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS", in cifs_reclassify_socket4()
3543 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]); in cifs_reclassify_socket4()
3549 struct sock *sk = sock->sk; in cifs_reclassify_socket6()
3551 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS", in cifs_reclassify_socket6()
3552 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]); in cifs_reclassify_socket6()
3584 if (server->srcaddr.ss_family != AF_UNSPEC) { in bind_socket()
3586 struct socket *socket = server->ssocket; in bind_socket()
3587 rc = socket->ops->bind(socket, in bind_socket()
3588 (struct sockaddr *) &server->srcaddr, in bind_socket()
3589 sizeof(server->srcaddr)); in bind_socket()
3593 saddr4 = (struct sockaddr_in *)&server->srcaddr; in bind_socket()
3594 saddr6 = (struct sockaddr_in6 *)&server->srcaddr; in bind_socket()
3595 if (saddr6->sin6_family == AF_INET6) in bind_socket()
3597 &saddr6->sin6_addr, rc); in bind_socket()
3600 &saddr4->sin_addr.s_addr, rc); in bind_socket()
3612 * negprot - BB check reconnection in case where second in ip_rfc1001_connect()
3620 ses_init_buf->trailer.session_req.called_len = 32; in ip_rfc1001_connect()
3622 if (server->server_RFC1001_name[0] != 0) in ip_rfc1001_connect()
3623 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3625 server->server_RFC1001_name, in ip_rfc1001_connect()
3628 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3633 ses_init_buf->trailer.session_req.calling_len = 32; in ip_rfc1001_connect()
3639 if (server->workstation_RFC1001_name[0] != 0) in ip_rfc1001_connect()
3640 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3642 server->workstation_RFC1001_name, in ip_rfc1001_connect()
3645 rfc1002mangle(ses_init_buf->trailer. in ip_rfc1001_connect()
3650 ses_init_buf->trailer.session_req.scope1 = 0; in ip_rfc1001_connect()
3651 ses_init_buf->trailer.session_req.scope2 = 0; in ip_rfc1001_connect()
3655 smb_buf->smb_buf_length = cpu_to_be32(0x81000044); in ip_rfc1001_connect()
3684 struct socket *socket = server->ssocket; in generic_ip_connect()
3687 saddr = (struct sockaddr *) &server->dstaddr; in generic_ip_connect()
3689 if (server->dstaddr.ss_family == AF_INET6) { in generic_ip_connect()
3690 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr; in generic_ip_connect()
3692 sport = ipv6->sin6_port; in generic_ip_connect()
3695 cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n", __func__, &ipv6->sin6_addr, in generic_ip_connect()
3698 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr; in generic_ip_connect()
3700 sport = ipv4->sin_port; in generic_ip_connect()
3703 cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr, in generic_ip_connect()
3712 server->ssocket = NULL; in generic_ip_connect()
3718 server->ssocket = socket; in generic_ip_connect()
3719 socket->sk->sk_allocation = GFP_NOFS; in generic_ip_connect()
3735 socket->sk->sk_rcvtimeo = 7 * HZ; in generic_ip_connect()
3736 socket->sk->sk_sndtimeo = 5 * HZ; in generic_ip_connect()
3739 if (server->noautotune) { in generic_ip_connect()
3740 if (socket->sk->sk_sndbuf < (200 * 1024)) in generic_ip_connect()
3741 socket->sk->sk_sndbuf = 200 * 1024; in generic_ip_connect()
3742 if (socket->sk->sk_rcvbuf < (140 * 1024)) in generic_ip_connect()
3743 socket->sk->sk_rcvbuf = 140 * 1024; in generic_ip_connect()
3746 if (server->tcp_nodelay) in generic_ip_connect()
3747 tcp_sock_set_nodelay(socket->sk); in generic_ip_connect()
3750 socket->sk->sk_sndbuf, in generic_ip_connect()
3751 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); in generic_ip_connect()
3753 rc = socket->ops->connect(socket, saddr, slen, in generic_ip_connect()
3754 server->noblockcnt ? O_NONBLOCK : 0); in generic_ip_connect()
3758 * reconnect failover - if possible. in generic_ip_connect()
3760 if (server->noblockcnt && rc == -EINPROGRESS) in generic_ip_connect()
3765 server->ssocket = NULL; in generic_ip_connect()
3779 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; in ip_connect()
3780 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; in ip_connect()
3782 if (server->dstaddr.ss_family == AF_INET6) in ip_connect()
3783 sport = &addr6->sin6_port; in ip_connect()
3785 sport = &addr->sin_port; in ip_connect()
3804 void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, in reset_cifs_unix_caps() argument
3811 * Perhaps we could add a backpointer to array of sb from tcon in reset_cifs_unix_caps()
3813 * sb as NFS - then we only have one backpointer to sb. in reset_cifs_unix_caps()
3816 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); in reset_cifs_unix_caps()
3818 if (vol_info && vol_info->no_linux_ext) { in reset_cifs_unix_caps()
3819 tcon->fsUnixInfo.Capability = 0; in reset_cifs_unix_caps()
3820 tcon->unix_ext = 0; /* Unix Extensions disabled */ in reset_cifs_unix_caps()
3824 tcon->unix_ext = 1; /* Unix Extensions supported */ in reset_cifs_unix_caps()
3826 if (tcon->unix_ext == 0) { in reset_cifs_unix_caps()
3831 if (!CIFSSMBQFSUnixInfo(xid, tcon)) { in reset_cifs_unix_caps()
3832 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); in reset_cifs_unix_caps()
3852 cifs_dbg(VFS, "per-share encryption not supported yet\n"); in reset_cifs_unix_caps()
3855 if (vol_info && vol_info->no_psx_acl) in reset_cifs_unix_caps()
3860 cifs_sb->mnt_cifs_flags |= in reset_cifs_unix_caps()
3864 if (vol_info && vol_info->posix_paths == 0) in reset_cifs_unix_caps()
3869 cifs_sb->mnt_cifs_flags |= in reset_cifs_unix_caps()
3894 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { in reset_cifs_unix_caps()
3907 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); in cifs_setup_cifs_sb()
3909 spin_lock_init(&cifs_sb->tlink_tree_lock); in cifs_setup_cifs_sb()
3910 cifs_sb->tlink_tree = RB_ROOT; in cifs_setup_cifs_sb()
3912 cifs_sb->bsize = pvolume_info->bsize; in cifs_setup_cifs_sb()
3917 cifs_sb->rsize = pvolume_info->rsize; in cifs_setup_cifs_sb()
3918 cifs_sb->wsize = pvolume_info->wsize; in cifs_setup_cifs_sb()
3920 cifs_sb->mnt_uid = pvolume_info->linux_uid; in cifs_setup_cifs_sb()
3921 cifs_sb->mnt_gid = pvolume_info->linux_gid; in cifs_setup_cifs_sb()
3922 cifs_sb->mnt_file_mode = pvolume_info->file_mode; in cifs_setup_cifs_sb()
3923 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; in cifs_setup_cifs_sb()
3925 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); in cifs_setup_cifs_sb()
3927 cifs_sb->actimeo = pvolume_info->actimeo; in cifs_setup_cifs_sb()
3928 cifs_sb->local_nls = pvolume_info->local_nls; in cifs_setup_cifs_sb()
3930 if (pvolume_info->nodfs) in cifs_setup_cifs_sb()
3931 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS; in cifs_setup_cifs_sb()
3932 if (pvolume_info->noperm) in cifs_setup_cifs_sb()
3933 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; in cifs_setup_cifs_sb()
3934 if (pvolume_info->setuids) in cifs_setup_cifs_sb()
3935 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; in cifs_setup_cifs_sb()
3936 if (pvolume_info->setuidfromacl) in cifs_setup_cifs_sb()
3937 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL; in cifs_setup_cifs_sb()
3938 if (pvolume_info->server_ino) in cifs_setup_cifs_sb()
3939 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; in cifs_setup_cifs_sb()
3940 if (pvolume_info->remap) in cifs_setup_cifs_sb()
3941 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR; in cifs_setup_cifs_sb()
3942 if (pvolume_info->sfu_remap) in cifs_setup_cifs_sb()
3943 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; in cifs_setup_cifs_sb()
3944 if (pvolume_info->no_xattr) in cifs_setup_cifs_sb()
3945 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; in cifs_setup_cifs_sb()
3946 if (pvolume_info->sfu_emul) in cifs_setup_cifs_sb()
3947 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; in cifs_setup_cifs_sb()
3948 if (pvolume_info->nobrl) in cifs_setup_cifs_sb()
3949 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; in cifs_setup_cifs_sb()
3950 if (pvolume_info->nohandlecache) in cifs_setup_cifs_sb()
3951 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE; in cifs_setup_cifs_sb()
3952 if (pvolume_info->nostrictsync) in cifs_setup_cifs_sb()
3953 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; in cifs_setup_cifs_sb()
3954 if (pvolume_info->mand_lock) in cifs_setup_cifs_sb()
3955 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; in cifs_setup_cifs_sb()
3956 if (pvolume_info->rwpidforward) in cifs_setup_cifs_sb()
3957 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; in cifs_setup_cifs_sb()
3958 if (pvolume_info->mode_ace) in cifs_setup_cifs_sb()
3959 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID; in cifs_setup_cifs_sb()
3960 if (pvolume_info->cifs_acl) in cifs_setup_cifs_sb()
3961 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; in cifs_setup_cifs_sb()
3962 if (pvolume_info->backupuid_specified) { in cifs_setup_cifs_sb()
3963 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; in cifs_setup_cifs_sb()
3964 cifs_sb->mnt_backupuid = pvolume_info->backupuid; in cifs_setup_cifs_sb()
3966 if (pvolume_info->backupgid_specified) { in cifs_setup_cifs_sb()
3967 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; in cifs_setup_cifs_sb()
3968 cifs_sb->mnt_backupgid = pvolume_info->backupgid; in cifs_setup_cifs_sb()
3970 if (pvolume_info->override_uid) in cifs_setup_cifs_sb()
3971 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; in cifs_setup_cifs_sb()
3972 if (pvolume_info->override_gid) in cifs_setup_cifs_sb()
3973 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; in cifs_setup_cifs_sb()
3974 if (pvolume_info->dynperm) in cifs_setup_cifs_sb()
3975 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; in cifs_setup_cifs_sb()
3976 if (pvolume_info->fsc) in cifs_setup_cifs_sb()
3977 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; in cifs_setup_cifs_sb()
3978 if (pvolume_info->multiuser) in cifs_setup_cifs_sb()
3979 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | in cifs_setup_cifs_sb()
3981 if (pvolume_info->strict_io) in cifs_setup_cifs_sb()
3982 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; in cifs_setup_cifs_sb()
3983 if (pvolume_info->direct_io) { in cifs_setup_cifs_sb()
3985 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; in cifs_setup_cifs_sb()
3987 if (pvolume_info->cache_ro) { in cifs_setup_cifs_sb()
3989 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; in cifs_setup_cifs_sb()
3990 } else if (pvolume_info->cache_rw) { in cifs_setup_cifs_sb()
3992 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | in cifs_setup_cifs_sb()
3995 if (pvolume_info->mfsymlinks) { in cifs_setup_cifs_sb()
3996 if (pvolume_info->sfu_emul) { in cifs_setup_cifs_sb()
4010 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; in cifs_setup_cifs_sb()
4013 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) in cifs_setup_cifs_sb()
4016 if (pvolume_info->prepath) { in cifs_setup_cifs_sb()
4017 cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL); in cifs_setup_cifs_sb()
4018 if (cifs_sb->prepath == NULL) in cifs_setup_cifs_sb()
4019 return -ENOMEM; in cifs_setup_cifs_sb()
4020 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in cifs_setup_cifs_sb()
4029 kfree(volume_info->username); in cifs_cleanup_volume_info_contents()
4030 kfree_sensitive(volume_info->password); in cifs_cleanup_volume_info_contents()
4031 kfree(volume_info->UNC); in cifs_cleanup_volume_info_contents()
4032 kfree(volume_info->domainname); in cifs_cleanup_volume_info_contents()
4033 kfree(volume_info->iocharset); in cifs_cleanup_volume_info_contents()
4034 kfree(volume_info->prepath); in cifs_cleanup_volume_info_contents()
4050 struct cifs_ses *ses, struct cifs_tcon *tcon) in mount_put_conns() argument
4054 if (tcon) in mount_put_conns()
4055 cifs_put_tcon(tcon); in mount_put_conns()
4060 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS; in mount_put_conns()
4064 /* Get connections for tcp, ses and tcon */
4073 struct cifs_tcon *tcon; in mount_get_conns() local
4099 if ((vol->persistent == true) && (!(ses->server->capabilities & in mount_get_conns()
4102 return -EOPNOTSUPP; in mount_get_conns()
4105 /* search for existing tcon to this server share */ in mount_get_conns()
4106 tcon = cifs_get_tcon(ses, vol); in mount_get_conns()
4107 if (IS_ERR(tcon)) { in mount_get_conns()
4108 rc = PTR_ERR(tcon); in mount_get_conns()
4112 *ntcon = tcon; in mount_get_conns()
4115 if (tcon->posix_extensions) in mount_get_conns()
4116 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; in mount_get_conns()
4119 if (cap_unix(tcon->ses)) { in mount_get_conns()
4124 reset_cifs_unix_caps(*xid, tcon, cifs_sb, vol); in mount_get_conns()
4125 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && in mount_get_conns()
4126 (le64_to_cpu(tcon->fsUnixInfo.Capability) & in mount_get_conns()
4128 return -EACCES; in mount_get_conns()
4130 tcon->unix_ext = 0; /* server does not support them */ in mount_get_conns()
4132 /* do not care if a following call succeed - informational */ in mount_get_conns()
4133 if (!tcon->pipe && server->ops->qfs_tcon) { in mount_get_conns()
4134 server->ops->qfs_tcon(*xid, tcon, cifs_sb); in mount_get_conns()
4135 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { in mount_get_conns()
4136 if (tcon->fsDevInfo.DeviceCharacteristics & in mount_get_conns()
4139 else if ((cifs_sb->mnt_cifs_flags & in mount_get_conns()
4146 cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol); in mount_get_conns()
4147 cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol); in mount_get_conns()
4153 struct cifs_tcon *tcon) in mount_setup_tlink() argument
4157 /* hang the tcon off of the superblock */ in mount_setup_tlink()
4160 return -ENOMEM; in mount_setup_tlink()
4162 tlink->tl_uid = ses->linux_uid; in mount_setup_tlink()
4163 tlink->tl_tcon = tcon; in mount_setup_tlink()
4164 tlink->tl_time = jiffies; in mount_setup_tlink()
4165 set_bit(TCON_LINK_MASTER, &tlink->tl_flags); in mount_setup_tlink()
4166 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in mount_setup_tlink()
4168 cifs_sb->master_tlink = tlink; in mount_setup_tlink()
4169 spin_lock(&cifs_sb->tlink_tree_lock); in mount_setup_tlink()
4170 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); in mount_setup_tlink()
4171 spin_unlock(&cifs_sb->tlink_tree_lock); in mount_setup_tlink()
4173 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, in mount_setup_tlink()
4181 * exiting connection (tcon)
4188 unsigned int pplen = useppath && vol->prepath ? in build_unc_path_to_root()
4189 strlen(vol->prepath) + 1 : 0; in build_unc_path_to_root()
4190 unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); in build_unc_path_to_root()
4193 return ERR_PTR(-EINVAL); in build_unc_path_to_root()
4197 return ERR_PTR(-ENOMEM); in build_unc_path_to_root()
4199 memcpy(full_path, vol->UNC, unc_len); in build_unc_path_to_root()
4204 memcpy(pos + 1, vol->prepath, pplen); in build_unc_path_to_root()
4215 * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
4218 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
4234 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) in expand_dfs_referral()
4235 return -EREMOTE; in expand_dfs_referral()
4241 rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), in expand_dfs_referral()
4246 mdata = cifs_compose_mount_options(cifs_sb->mountdata, in expand_dfs_referral()
4260 kfree(cifs_sb->mountdata); in expand_dfs_referral()
4261 cifs_sb->mountdata = mdata; in expand_dfs_referral()
4275 return !*tgt_it ? -EHOSTDOWN : 0; in get_next_dfs_tgt()
4287 return -ENOMEM; in update_vol_info()
4290 kfree(vol->UNC); in update_vol_info()
4291 vol->UNC = new_unc; in update_vol_info()
4293 if (fake_vol->prepath) { in update_vol_info()
4294 kfree(vol->prepath); in update_vol_info()
4295 vol->prepath = fake_vol->prepath; in update_vol_info()
4296 fake_vol->prepath = NULL; in update_vol_info()
4298 memcpy(&vol->dstaddr, &fake_vol->dstaddr, sizeof(vol->dstaddr)); in update_vol_info()
4307 struct cifs_tcon **tcon) in setup_dfs_tgt_conn() argument
4320 mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref, &fake_devname); in setup_dfs_tgt_conn()
4340 mount_put_conns(cifs_sb, *xid, *server, *ses, *tcon); in setup_dfs_tgt_conn()
4342 tcon); in setup_dfs_tgt_conn()
4358 struct cifs_tcon **tcon) in do_dfs_failover() argument
4364 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) in do_dfs_failover()
4365 return -EOPNOTSUPP; in do_dfs_failover()
4372 /* Get next DFS target server - if any */ in do_dfs_failover()
4378 tcon); in do_dfs_failover()
4388 cifs_sb->local_nls, in do_dfs_failover()
4404 return -EINVAL; in cifs_setup_volume_info()
4406 if (volume_info->nullauth) { in cifs_setup_volume_info()
4408 kfree(volume_info->username); in cifs_setup_volume_info()
4409 volume_info->username = NULL; in cifs_setup_volume_info()
4410 } else if (volume_info->username) { in cifs_setup_volume_info()
4412 cifs_dbg(FYI, "Username: %s\n", volume_info->username); in cifs_setup_volume_info()
4417 return -EINVAL; in cifs_setup_volume_info()
4421 if (volume_info->iocharset == NULL) { in cifs_setup_volume_info()
4423 volume_info->local_nls = load_nls_default(); in cifs_setup_volume_info()
4425 volume_info->local_nls = load_nls(volume_info->iocharset); in cifs_setup_volume_info()
4426 if (volume_info->local_nls == NULL) { in cifs_setup_volume_info()
4428 volume_info->iocharset); in cifs_setup_volume_info()
4429 return -ELIBACC; in cifs_setup_volume_info()
4444 return ERR_PTR(-ENOMEM); in cifs_get_volume_info()
4458 struct cifs_tcon *tcon, in cifs_are_all_path_components_accessible() argument
4471 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, ""); in cifs_are_all_path_components_accessible()
4490 * temporarily null-terminate the path at the end of in cifs_are_all_path_components_accessible()
4495 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, in cifs_are_all_path_components_accessible()
4503 * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is,
4509 struct cifs_tcon *tcon) in is_path_remote() argument
4514 if (!server->ops->is_path_accessible) in is_path_remote()
4515 return -EOPNOTSUPP; in is_path_remote()
4518 * cifs_build_path_to_root works only when we have a valid tcon in is_path_remote()
4520 full_path = cifs_build_path_to_root(vol, cifs_sb, tcon, in is_path_remote()
4521 tcon->Flags & SMB_SHARE_IS_IN_DFS); in is_path_remote()
4523 return -ENOMEM; in is_path_remote()
4527 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, in is_path_remote()
4529 if (rc != 0 && rc != -EREMOTE) { in is_path_remote()
4534 if (rc != -EREMOTE) { in is_path_remote()
4535 rc = cifs_are_all_path_components_accessible(server, xid, tcon, in is_path_remote()
4536 cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); in is_path_remote()
4539 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in is_path_remote()
4554 ses->ses_count++; in set_root_ses()
4555 if (ses->tcon_ipc) in set_root_ses()
4556 ses->tcon_ipc->remap = cifs_remap(cifs_sb); in set_root_ses()
4571 struct cifs_tcon *tcon, char **dfs_path) in check_dfs_prepath() argument
4577 int added_treename = tcon->Flags & SMB_SHARE_IS_IN_DFS; in check_dfs_prepath()
4580 path = cifs_build_path_to_root(vol, cifs_sb, tcon, added_treename); in check_dfs_prepath()
4582 return -ENOMEM; in check_dfs_prepath()
4586 * the components is -EREMOTE, then update @dfs_path with the next DFS referral request path in check_dfs_prepath()
4609 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, path); in check_dfs_prepath()
4610 if (rc && rc == -EREMOTE) { in check_dfs_prepath()
4617 rc = -EREMOTE; in check_dfs_prepath()
4621 v.UNC = vol->UNC; in check_dfs_prepath()
4645 struct cifs_tcon *tcon = NULL; in cifs_mount() local
4651 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4659 if (dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), vol->UNC + 1, NULL, in cifs_mount()
4665 rc = is_path_remote(cifs_sb, vol, xid, server, tcon); in cifs_mount()
4668 if (rc != -EREMOTE) in cifs_mount()
4672 mntdata = kstrndup(cifs_sb->mountdata, strlen(cifs_sb->mountdata), GFP_KERNEL); in cifs_mount()
4674 rc = -ENOMEM; in cifs_mount()
4696 oldmnt = cifs_sb->mountdata; in cifs_mount()
4701 if (oldmnt != cifs_sb->mountdata) { in cifs_mount()
4702 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4703 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4708 &server, &ses, &tcon); in cifs_mount()
4710 if (rc == -EACCES || rc == -EOPNOTSUPP || !server || !ses) in cifs_mount()
4712 if (!tcon) in cifs_mount()
4715 if (is_tcon_dfs(tcon)) { in cifs_mount()
4719 /* Check for remaining path components and then continue chasing them (-EREMOTE) */ in cifs_mount()
4720 rc = check_dfs_prepath(cifs_sb, vol, xid, server, tcon, &ref_path); in cifs_mount()
4722 if (rc == -EREMOTE && ++count > MAX_NESTED_LINKS) in cifs_mount()
4723 rc = -ELOOP; in cifs_mount()
4724 } while (rc == -EREMOTE); in cifs_mount()
4735 * For DFS root mounts, the prefix path (cifs_sb->prepath) is preserved during reconnect so in cifs_mount()
4736 * only the root path is set in cifs_sb->origin_fullpath and tcon->dfs_path. And for DFS in cifs_mount()
4740 cifs_sb->origin_fullpath = kstrndup(full_path, strlen(full_path), GFP_KERNEL); in cifs_mount()
4741 if (!cifs_sb->origin_fullpath) { in cifs_mount()
4742 rc = -ENOMEM; in cifs_mount()
4746 tcon->dfs_path = full_path; in cifs_mount()
4748 tcon->remap = cifs_remap(cifs_sb); in cifs_mount()
4752 rc = dfs_cache_add_vol(mntdata, vol, cifs_sb->origin_fullpath); in cifs_mount()
4765 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; in cifs_mount()
4766 kfree(cifs_sb->prepath); in cifs_mount()
4767 cifs_sb->prepath = vol->prepath; in cifs_mount()
4768 vol->prepath = NULL; in cifs_mount()
4773 return mount_setup_tlink(cifs_sb, ses, tcon); in cifs_mount()
4779 kfree(cifs_sb->origin_fullpath); in cifs_mount()
4781 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4790 struct cifs_tcon *tcon; in cifs_mount() local
4793 rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); in cifs_mount()
4797 if (tcon) { in cifs_mount()
4798 rc = is_path_remote(cifs_sb, vol, xid, server, tcon); in cifs_mount()
4799 if (rc == -EREMOTE) in cifs_mount()
4800 rc = -EOPNOTSUPP; in cifs_mount()
4807 return mount_setup_tlink(cifs_sb, ses, tcon); in cifs_mount()
4810 mount_put_conns(cifs_sb, xid, server, ses, tcon); in cifs_mount()
4820 const char *tree, struct cifs_tcon *tcon, in CIFSTCon() argument
4833 return -EIO; in CIFSTCon()
4837 return -ENOMEM; in CIFSTCon()
4844 smb_buffer->Mid = get_next_mid(ses->server); in CIFSTCon()
4845 smb_buffer->Uid = ses->Suid; in CIFSTCon()
4849 pSMB->AndXCommand = 0xFF; in CIFSTCon()
4850 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); in CIFSTCon()
4851 bcc_ptr = &pSMB->Password[0]; in CIFSTCon()
4852 if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) { in CIFSTCon()
4853 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ in CIFSTCon()
4858 pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); in CIFSTCon()
4867 (ses->sectype == LANMAN)) in CIFSTCon()
4868 calc_lanman_hash(tcon->password, ses->server->cryptkey, in CIFSTCon()
4869 ses->server->sec_mode & in CIFSTCon()
4874 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey, in CIFSTCon()
4884 if (ses->capabilities & CAP_UNICODE) { in CIFSTCon()
4891 if (ses->server->sign) in CIFSTCon()
4892 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; in CIFSTCon()
4894 if (ses->capabilities & CAP_STATUS32) { in CIFSTCon()
4895 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; in CIFSTCon()
4897 if (ses->capabilities & CAP_DFS) { in CIFSTCon()
4898 smb_buffer->Flags2 |= SMBFLG2_DFS; in CIFSTCon()
4900 if (ses->capabilities & CAP_UNICODE) { in CIFSTCon()
4901 smb_buffer->Flags2 |= SMBFLG2_UNICODE; in CIFSTCon()
4915 count = bcc_ptr - &pSMB->Password[0]; in CIFSTCon()
4916 be32_add_cpu(&pSMB->hdr.smb_buf_length, count); in CIFSTCon()
4917 pSMB->ByteCount = cpu_to_le16(count); in CIFSTCon()
4926 tcon->tidStatus = CifsGood; in CIFSTCon()
4927 tcon->need_reconnect = false; in CIFSTCon()
4928 tcon->tid = smb_buffer_response->Tid; in CIFSTCon()
4931 length = strnlen(bcc_ptr, bytes_left - 2); in CIFSTCon()
4932 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) in CIFSTCon()
4943 tcon->ipc = true; in CIFSTCon()
4944 tcon->pipe = true; in CIFSTCon()
4953 bytes_left -= (length + 1); in CIFSTCon()
4954 strlcpy(tcon->treeName, tree, sizeof(tcon->treeName)); in CIFSTCon()
4956 /* mostly informational -- no need to fail on error here */ in CIFSTCon()
4957 kfree(tcon->nativeFileSystem); in CIFSTCon()
4958 tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr, in CIFSTCon()
4962 cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem); in CIFSTCon()
4964 if ((smb_buffer_response->WordCount == 3) || in CIFSTCon()
4965 (smb_buffer_response->WordCount == 7)) in CIFSTCon()
4967 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); in CIFSTCon()
4969 tcon->Flags = 0; in CIFSTCon()
4970 cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); in CIFSTCon()
4980 unload_nls(sbi->local_nls); in delayed_free()
4987 struct rb_root *root = &cifs_sb->tlink_tree; in cifs_umount()
4991 cancel_delayed_work_sync(&cifs_sb->prune_tlinks); in cifs_umount()
4993 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_umount()
4997 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in cifs_umount()
5000 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5002 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5004 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_umount()
5006 kfree(cifs_sb->mountdata); in cifs_umount()
5007 kfree(cifs_sb->prepath); in cifs_umount()
5009 dfs_cache_del_vol(cifs_sb->origin_fullpath); in cifs_umount()
5010 kfree(cifs_sb->origin_fullpath); in cifs_umount()
5012 call_rcu(&cifs_sb->rcu, delayed_free); in cifs_umount()
5021 if (!server->ops->need_neg || !server->ops->negotiate) in cifs_negotiate_protocol()
5022 return -ENOSYS; in cifs_negotiate_protocol()
5025 if (!server->ops->need_neg(server)) in cifs_negotiate_protocol()
5028 rc = server->ops->negotiate(xid, ses); in cifs_negotiate_protocol()
5031 if (server->tcpStatus == CifsNeedNegotiate) in cifs_negotiate_protocol()
5032 server->tcpStatus = CifsGood; in cifs_negotiate_protocol()
5034 rc = -EHOSTDOWN; in cifs_negotiate_protocol()
5045 int rc = -ENOSYS; in cifs_setup_session()
5048 if (!ses->binding) { in cifs_setup_session()
5049 ses->capabilities = server->capabilities; in cifs_setup_session()
5051 ses->capabilities &= (~server->vals->cap_unix); in cifs_setup_session()
5053 if (ses->auth_key.response) { in cifs_setup_session()
5055 ses->auth_key.response); in cifs_setup_session()
5056 kfree(ses->auth_key.response); in cifs_setup_session()
5057 ses->auth_key.response = NULL; in cifs_setup_session()
5058 ses->auth_key.len = 0; in cifs_setup_session()
5063 server->sec_mode, server->capabilities, server->timeAdj); in cifs_setup_session()
5065 if (server->ops->sess_setup) in cifs_setup_session()
5066 rc = server->ops->sess_setup(xid, ses, nls_info); in cifs_setup_session()
5077 vol->sectype = ses->sectype; in cifs_set_vol_auth()
5080 if (vol->sectype == Kerberos) in cifs_set_vol_auth()
5092 struct cifs_tcon *tcon = NULL; in cifs_construct_tcon() local
5097 return ERR_PTR(-ENOMEM); in cifs_construct_tcon()
5099 vol_info->local_nls = cifs_sb->local_nls; in cifs_construct_tcon()
5100 vol_info->linux_uid = fsuid; in cifs_construct_tcon()
5101 vol_info->cred_uid = fsuid; in cifs_construct_tcon()
5102 vol_info->UNC = master_tcon->treeName; in cifs_construct_tcon()
5103 vol_info->retry = master_tcon->retry; in cifs_construct_tcon()
5104 vol_info->nocase = master_tcon->nocase; in cifs_construct_tcon()
5105 vol_info->nohandlecache = master_tcon->nohandlecache; in cifs_construct_tcon()
5106 vol_info->local_lease = master_tcon->local_lease; in cifs_construct_tcon()
5107 vol_info->no_lease = master_tcon->no_lease; in cifs_construct_tcon()
5108 vol_info->resilient = master_tcon->use_resilient; in cifs_construct_tcon()
5109 vol_info->persistent = master_tcon->use_persistent; in cifs_construct_tcon()
5110 vol_info->handle_timeout = master_tcon->handle_timeout; in cifs_construct_tcon()
5111 vol_info->no_linux_ext = !master_tcon->unix_ext; in cifs_construct_tcon()
5112 vol_info->linux_ext = master_tcon->posix_extensions; in cifs_construct_tcon()
5113 vol_info->sectype = master_tcon->ses->sectype; in cifs_construct_tcon()
5114 vol_info->sign = master_tcon->ses->sign; in cifs_construct_tcon()
5115 vol_info->seal = master_tcon->seal; in cifs_construct_tcon()
5117 rc = cifs_set_vol_auth(vol_info, master_tcon->ses); in cifs_construct_tcon()
5119 tcon = ERR_PTR(rc); in cifs_construct_tcon()
5125 ++master_tcon->ses->server->srv_count; in cifs_construct_tcon()
5128 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); in cifs_construct_tcon()
5130 tcon = (struct cifs_tcon *)ses; in cifs_construct_tcon()
5131 cifs_put_tcp_session(master_tcon->ses->server, 0); in cifs_construct_tcon()
5135 tcon = cifs_get_tcon(ses, vol_info); in cifs_construct_tcon()
5136 if (IS_ERR(tcon)) { in cifs_construct_tcon()
5142 reset_cifs_unix_caps(0, tcon, NULL, vol_info); in cifs_construct_tcon()
5145 kfree(vol_info->username); in cifs_construct_tcon()
5146 kfree_sensitive(vol_info->password); in cifs_construct_tcon()
5149 return tcon; in cifs_construct_tcon()
5162 struct rb_node *node = root->rb_node; in tlink_rb_search()
5168 if (uid_gt(tlink->tl_uid, uid)) in tlink_rb_search()
5169 node = node->rb_left; in tlink_rb_search()
5170 else if (uid_lt(tlink->tl_uid, uid)) in tlink_rb_search()
5171 node = node->rb_right; in tlink_rb_search()
5182 struct rb_node **new = &(root->rb_node), *parent = NULL; in tlink_rb_insert()
5189 if (uid_gt(tlink->tl_uid, new_tlink->tl_uid)) in tlink_rb_insert()
5190 new = &((*new)->rb_left); in tlink_rb_insert()
5192 new = &((*new)->rb_right); in tlink_rb_insert()
5195 rb_link_node(&new_tlink->tl_rbnode, parent, new); in tlink_rb_insert()
5196 rb_insert_color(&new_tlink->tl_rbnode, root); in tlink_rb_insert()
5200 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
5204 * the master tcon for the mount.
5206 * First, search the rbtree for an existing tcon for this fsuid. If one
5222 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) in cifs_sb_tlink()
5225 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5226 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); in cifs_sb_tlink()
5229 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5234 return ERR_PTR(-ENOMEM); in cifs_sb_tlink()
5235 newtlink->tl_uid = fsuid; in cifs_sb_tlink()
5236 newtlink->tl_tcon = ERR_PTR(-EACCES); in cifs_sb_tlink()
5237 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); in cifs_sb_tlink()
5238 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); in cifs_sb_tlink()
5241 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5243 tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); in cifs_sb_tlink()
5246 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5251 tlink_rb_insert(&cifs_sb->tlink_tree, tlink); in cifs_sb_tlink()
5252 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_sb_tlink()
5255 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, in cifs_sb_tlink()
5259 return ERR_PTR(-ERESTARTSYS); in cifs_sb_tlink()
5263 if (!IS_ERR(tlink->tl_tcon)) in cifs_sb_tlink()
5267 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) { in cifs_sb_tlink()
5269 return ERR_PTR(-EACCES); in cifs_sb_tlink()
5272 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags)) in cifs_sb_tlink()
5276 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid); in cifs_sb_tlink()
5277 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags); in cifs_sb_tlink()
5278 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING); in cifs_sb_tlink()
5280 if (IS_ERR(tlink->tl_tcon)) { in cifs_sb_tlink()
5282 return ERR_PTR(-EACCES); in cifs_sb_tlink()
5297 struct rb_root *root = &cifs_sb->tlink_tree; in cifs_prune_tlinks()
5306 * umounts. Because this function is non-reentrant and is canceled in cifs_prune_tlinks()
5309 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5316 if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || in cifs_prune_tlinks()
5317 atomic_read(&tlink->tl_count) != 0 || in cifs_prune_tlinks()
5318 time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) in cifs_prune_tlinks()
5322 clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); in cifs_prune_tlinks()
5325 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5327 spin_lock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5329 spin_unlock(&cifs_sb->tlink_tree_lock); in cifs_prune_tlinks()
5331 queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, in cifs_prune_tlinks()
5336 int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) in cifs_tree_connect() argument
5339 struct TCP_Server_Info *server = tcon->ses->server; in cifs_tree_connect()
5340 const struct smb_version_operations *ops = server->ops; in cifs_tree_connect()
5354 return -ENOMEM; in cifs_tree_connect()
5357 if (!tcon->dfs_path || dfs_cache_noreq_find(tcon->dfs_path + 1, &ref, &tl)) { in cifs_tree_connect()
5358 if (tcon->ipc) { in cifs_tree_connect()
5359 scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); in cifs_tree_connect()
5360 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5362 rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); in cifs_tree_connect()
5370 extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len); in cifs_tree_connect()
5380 rc = dfs_cache_get_tgt_share(tcon->dfs_path + 1, it, &share, &prefix); in cifs_tree_connect()
5406 if (tcon->ipc) { in cifs_tree_connect()
5408 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5411 rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); in cifs_tree_connect()
5414 rc = update_super_prepath(tcon, prefix); in cifs_tree_connect()
5418 if (rc == -EREMOTE) in cifs_tree_connect()
5427 rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1, it); in cifs_tree_connect()
5429 rc = -ENOENT; in cifs_tree_connect()
5437 int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) in cifs_tree_connect() argument
5439 const struct smb_version_operations *ops = tcon->ses->server->ops; in cifs_tree_connect()
5441 return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); in cifs_tree_connect()