Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  *   fs/cifs/connect.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *   Copyright (C) International Business Machines  Corp., 2002,2011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *   Author(s): Steve French (sfrench@us.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *   This library is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *   it under the terms of the GNU Lesser General Public License as published
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *   by the Free Software Foundation; either version 2.1 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *   (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *   This library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *   the GNU Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  *   You should have received a copy of the GNU Lesser General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *   along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/mempool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/pagevec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/uuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <keys/user-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <linux/bvec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include "cifspdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include "cifs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include "cifs_fs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include "ntlmssp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include "nterr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include "rfc1002pdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include "fscache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include "smb2proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include "smbdirect.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include "dns_resolve.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include "dfs_cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include "fs_context.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) extern mempool_t *cifs_req_poolp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) extern bool disable_legacy_dialects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) /* FIXME: should these be tunable? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define TLINK_ERROR_EXPIRE	(1 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define TLINK_IDLE_EXPIRE	(600 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) /* Drop the connection to not overload the server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define NUM_STATUS_IO_TIMEOUT   5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	/* Mount options that take no arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	Opt_user_xattr, Opt_nouser_xattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	Opt_forceuid, Opt_noforceuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	Opt_forcegid, Opt_noforcegid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	Opt_noblocksend, Opt_noautotune, Opt_nolease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_nodelete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	Opt_mapposix, Opt_nomapposix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	Opt_mapchars, Opt_nomapchars, Opt_sfu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	Opt_nosfu, Opt_nodfs, Opt_posixpaths,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	Opt_noposixpaths, Opt_nounix, Opt_unix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	Opt_nocase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	Opt_brl, Opt_nobrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	Opt_handlecache, Opt_nohandlecache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	Opt_forcemandatorylock, Opt_setuidfromacl, Opt_setuids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	Opt_nohard, Opt_nosoft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	Opt_nointr, Opt_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	Opt_nostrictsync, Opt_strictsync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	Opt_serverino, Opt_noserverino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	Opt_acl, Opt_noacl, Opt_locallease,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	Opt_sign, Opt_ignore_signature, Opt_seal, Opt_noac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	Opt_fsc, Opt_mfsymlinks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	Opt_multiuser, Opt_sloppy, Opt_nosharesock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	Opt_persistent, Opt_nopersistent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	Opt_resilient, Opt_noresilient,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	Opt_domainauto, Opt_rdma, Opt_modesid, Opt_rootfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	Opt_multichannel, Opt_nomultichannel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	Opt_compress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	/* Mount options which take numeric value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	Opt_backupuid, Opt_backupgid, Opt_uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	Opt_cruid, Opt_gid, Opt_file_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	Opt_dirmode, Opt_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	Opt_min_enc_offload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	Opt_snapshot, Opt_max_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	/* Mount options which take string value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	Opt_user, Opt_pass, Opt_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	Opt_domain, Opt_srcaddr, Opt_iocharset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	Opt_netbiosname, Opt_servern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	Opt_ver, Opt_vers, Opt_sec, Opt_cache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	/* Mount options to be ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	Opt_ignore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	/* Options which could be blank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	Opt_blank_pass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	Opt_blank_user,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	Opt_blank_ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	Opt_err
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) static const match_table_t cifs_mount_option_tokens = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	{ Opt_user_xattr, "user_xattr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	{ Opt_nouser_xattr, "nouser_xattr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	{ Opt_forceuid, "forceuid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	{ Opt_noforceuid, "noforceuid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	{ Opt_forcegid, "forcegid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	{ Opt_noforcegid, "noforcegid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	{ Opt_noblocksend, "noblocksend" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	{ Opt_noautotune, "noautotune" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	{ Opt_nolease, "nolease" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	{ Opt_hard, "hard" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	{ Opt_soft, "soft" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	{ Opt_perm, "perm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	{ Opt_noperm, "noperm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	{ Opt_nodelete, "nodelete" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	{ Opt_mapchars, "mapchars" }, /* SFU style */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	{ Opt_nomapchars, "nomapchars" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	{ Opt_mapposix, "mapposix" }, /* SFM style */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	{ Opt_nomapposix, "nomapposix" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	{ Opt_sfu, "sfu" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	{ Opt_nosfu, "nosfu" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	{ Opt_nodfs, "nodfs" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	{ Opt_posixpaths, "posixpaths" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	{ Opt_noposixpaths, "noposixpaths" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	{ Opt_nounix, "nounix" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	{ Opt_nounix, "nolinux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	{ Opt_nounix, "noposix" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	{ Opt_unix, "unix" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	{ Opt_unix, "linux" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	{ Opt_unix, "posix" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	{ Opt_nocase, "nocase" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	{ Opt_nocase, "ignorecase" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	{ Opt_brl, "brl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	{ Opt_nobrl, "nobrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	{ Opt_handlecache, "handlecache" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	{ Opt_nohandlecache, "nohandlecache" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	{ Opt_nobrl, "nolock" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	{ Opt_forcemandatorylock, "forcemandatorylock" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	{ Opt_forcemandatorylock, "forcemand" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	{ Opt_setuids, "setuids" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	{ Opt_nosetuids, "nosetuids" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	{ Opt_setuidfromacl, "idsfromsid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	{ Opt_dynperm, "dynperm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	{ Opt_nodynperm, "nodynperm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	{ Opt_nohard, "nohard" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	{ Opt_nosoft, "nosoft" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	{ Opt_nointr, "nointr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	{ Opt_intr, "intr" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	{ Opt_nostrictsync, "nostrictsync" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	{ Opt_strictsync, "strictsync" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	{ Opt_serverino, "serverino" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	{ Opt_noserverino, "noserverino" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	{ Opt_rwpidforward, "rwpidforward" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	{ Opt_modesid, "modefromsid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	{ Opt_cifsacl, "cifsacl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	{ Opt_nocifsacl, "nocifsacl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	{ Opt_acl, "acl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	{ Opt_noacl, "noacl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	{ Opt_locallease, "locallease" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	{ Opt_sign, "sign" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	{ Opt_ignore_signature, "signloosely" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	{ Opt_seal, "seal" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	{ Opt_noac, "noac" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	{ Opt_fsc, "fsc" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	{ Opt_mfsymlinks, "mfsymlinks" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	{ Opt_multiuser, "multiuser" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	{ Opt_sloppy, "sloppy" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	{ Opt_nosharesock, "nosharesock" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	{ Opt_persistent, "persistenthandles"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	{ Opt_nopersistent, "nopersistenthandles"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	{ Opt_resilient, "resilienthandles"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	{ Opt_noresilient, "noresilienthandles"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	{ Opt_domainauto, "domainauto"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	{ Opt_rdma, "rdma"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	{ Opt_multichannel, "multichannel" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	{ Opt_nomultichannel, "nomultichannel" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	{ Opt_backupuid, "backupuid=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	{ Opt_backupgid, "backupgid=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	{ Opt_uid, "uid=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	{ Opt_cruid, "cruid=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	{ Opt_gid, "gid=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	{ Opt_file_mode, "file_mode=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	{ Opt_dirmode, "dirmode=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	{ Opt_dirmode, "dir_mode=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	{ Opt_port, "port=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	{ Opt_min_enc_offload, "esize=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	{ Opt_blocksize, "bsize=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	{ Opt_rsize, "rsize=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	{ Opt_wsize, "wsize=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	{ Opt_actimeo, "actimeo=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	{ Opt_handletimeout, "handletimeout=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	{ Opt_echo_interval, "echo_interval=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	{ Opt_max_credits, "max_credits=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	{ Opt_snapshot, "snapshot=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	{ Opt_max_channels, "max_channels=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	{ Opt_compress, "compress=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	{ Opt_blank_user, "user=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	{ Opt_blank_user, "username=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	{ Opt_user, "user=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	{ Opt_user, "username=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	{ Opt_blank_pass, "pass=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	{ Opt_blank_pass, "password=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	{ Opt_pass, "pass=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	{ Opt_pass, "password=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	{ Opt_blank_ip, "ip=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	{ Opt_blank_ip, "addr=" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	{ Opt_ip, "ip=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	{ Opt_ip, "addr=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	{ Opt_ignore, "unc=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	{ Opt_ignore, "target=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	{ Opt_ignore, "path=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	{ Opt_domain, "dom=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	{ Opt_domain, "domain=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	{ Opt_domain, "workgroup=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	{ Opt_srcaddr, "srcaddr=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	{ Opt_ignore, "prefixpath=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	{ Opt_iocharset, "iocharset=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	{ Opt_netbiosname, "netbiosname=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	{ Opt_servern, "servern=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	{ Opt_ver, "ver=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	{ Opt_vers, "vers=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	{ Opt_sec, "sec=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	{ Opt_cache, "cache=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	{ Opt_ignore, "cred" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	{ Opt_ignore, "credentials" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	{ Opt_ignore, "cred=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	{ Opt_ignore, "credentials=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	{ Opt_ignore, "guest" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	{ Opt_ignore, "rw" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	{ Opt_ignore, "ro" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	{ Opt_ignore, "suid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	{ Opt_ignore, "nosuid" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	{ Opt_ignore, "exec" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	{ Opt_ignore, "noexec" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	{ Opt_ignore, "nodev" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	{ Opt_ignore, "noauto" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	{ Opt_ignore, "dev" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	{ Opt_ignore, "mand" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	{ Opt_ignore, "nomand" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	{ Opt_ignore, "relatime" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	{ Opt_ignore, "_netdev" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	{ Opt_rootfs, "rootfs" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	{ Opt_err, NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) static int ip_connect(struct TCP_Server_Info *server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static int generic_ip_connect(struct TCP_Server_Info *server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static void cifs_prune_tlinks(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) static char *extract_hostname(const char *unc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * get their ip addresses changed at some point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * This should be called with server->srv_mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) static int reconn_set_ipaddr(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	char *unc, *ipaddr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	if (!server->hostname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	len = strlen(server->hostname) + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	unc = kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (!unc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	scnprintf(unc, len, "\\\\%s", server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	rc = dns_resolve_server_name_to_ip(unc, &ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	kfree(unc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			 __func__, server->hostname, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 				  strlen(ipaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	kfree(ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	return !rc ? -1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) static inline int reconn_set_ipaddr(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) /* These functions must be called with server->srv_mutex held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) static void reconn_set_next_dfs_target(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 				       struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				       struct dfs_cache_tgt_list *tgt_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 				       struct dfs_cache_tgt_iterator **tgt_it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	if (!cifs_sb || !cifs_sb->origin_fullpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	if (!*tgt_it) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		*tgt_it = dfs_cache_get_tgt_iterator(tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		*tgt_it = dfs_cache_get_next_tgt(tgt_list, *tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		if (!*tgt_it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			*tgt_it = dfs_cache_get_tgt_iterator(tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	cifs_dbg(FYI, "%s: UNC: %s\n", __func__, cifs_sb->origin_fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	name = dfs_cache_get_tgt_name(*tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	kfree(server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	server->hostname = extract_hostname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (IS_ERR(server->hostname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		cifs_dbg(FYI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			 "%s: failed to extract hostname from target: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			 __func__, PTR_ERR(server->hostname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) static inline int reconn_setup_dfs_targets(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 					   struct dfs_cache_tgt_list *tl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	if (!cifs_sb->origin_fullpath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	return dfs_cache_noreq_find(cifs_sb->origin_fullpath + 1, NULL, tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  * cifs tcp session reconnection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * mark tcp session as reconnecting so temporarily locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * mark all smb sessions as reconnecting for tcp session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  * reconnect tcp session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  * wake up waiters on reconnection? - (not needed currently)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) cifs_reconnect(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	struct list_head *tmp, *tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	struct mid_q_entry *mid_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	struct list_head retry_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	struct super_block *sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	struct cifs_sb_info *cifs_sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	struct dfs_cache_tgt_list tgt_list = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	struct dfs_cache_tgt_iterator *tgt_it = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	server->nr_targets = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	sb = cifs_get_tcp_super(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	if (IS_ERR(sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		rc = PTR_ERR(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		cifs_dbg(FYI, "%s: will not do DFS failover: rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		cifs_sb = CIFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			cifs_sb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 			if (rc != -EOPNOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				cifs_server_dbg(VFS, "%s: no target servers for DFS failover\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 						__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			server->nr_targets = dfs_cache_get_nr_tgts(&tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	cifs_dbg(FYI, "%s: will retry %d target(s)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		 server->nr_targets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (server->tcpStatus == CifsExiting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		/* the demux thread will exit normally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		next time through the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		dfs_cache_free_tgts(&tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		cifs_put_tcp_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		wake_up(&server->response_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		server->tcpStatus = CifsNeedReconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	server->maxBuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	server->max_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	cifs_dbg(FYI, "Mark tcp session as need reconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	trace_smb3_reconnect(server->CurrentMid, server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	/* before reconnecting the tcp session, mark the smb session (uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		and the tid bad so they are not used until reconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	list_for_each(tmp, &server->smb_ses_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		ses->need_reconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		list_for_each(tmp2, &ses->tcon_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			tcon->need_reconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		if (ses->tcon_ipc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			ses->tcon_ipc->need_reconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	/* do not want to be sending data on a socket we are freeing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	mutex_lock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	if (server->ssocket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			 server->ssocket->state, server->ssocket->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		kernel_sock_shutdown(server->ssocket, SHUT_WR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			 server->ssocket->state, server->ssocket->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		sock_release(server->ssocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		server->ssocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	server->sequence_number = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	server->session_estab = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	kfree(server->session_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	server->session_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	server->session_key.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	server->lstrp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	/* mark submitted MIDs for retry and issue callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	INIT_LIST_HEAD(&retry_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		kref_get(&mid_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			mid_entry->mid_state = MID_RETRY_NEEDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		list_move(&mid_entry->qhead, &retry_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		mid_entry->mid_flags |= MID_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	list_for_each_safe(tmp, tmp2, &retry_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		list_del_init(&mid_entry->qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		mid_entry->callback(mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		cifs_mid_q_entry_release(mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (cifs_rdma_enabled(server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		mutex_lock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		smbd_destroy(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		mutex_lock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		 * Set up next DFS target server (if any) for reconnect. If DFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		 * feature is disabled, then we will retry last server we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		 * connected to before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		reconn_set_next_dfs_target(server, cifs_sb, &tgt_list, &tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		rc = reconn_set_ipaddr(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		if (cifs_rdma_enabled(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 			rc = smbd_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			rc = generic_ip_connect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			cifs_dbg(FYI, "reconnect error %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 			mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			msleep(3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 			atomic_inc(&tcpSesReconnectCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			set_credits(server, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			if (server->tcpStatus != CifsExiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 				server->tcpStatus = CifsNeedNegotiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			mutex_unlock(&server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	} while (server->tcpStatus == CifsNeedReconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (tgt_it) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		rc = dfs_cache_noreq_update_tgthint(cifs_sb->origin_fullpath + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 						    tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 			cifs_server_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 				 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		rc = dfs_cache_update_vol(cifs_sb->origin_fullpath, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			cifs_server_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 				 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		dfs_cache_free_tgts(&tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	cifs_put_tcp_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	if (server->tcpStatus == CifsNeedNegotiate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		mod_delayed_work(cifsiod_wq, &server->echo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	wake_up(&server->response_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) cifs_echo_request(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	struct TCP_Server_Info *server = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 					struct TCP_Server_Info, echo.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	unsigned long echo_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	 * If we need to renegotiate, set echo interval to zero to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	 * immediately call echo service where we can renegotiate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	if (server->tcpStatus == CifsNeedNegotiate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		echo_interval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		echo_interval = server->echo_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	 * We cannot send an echo if it is disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	 * Also, no need to ping if we got a response recently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (server->tcpStatus == CifsNeedReconnect ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	    server->tcpStatus == CifsExiting ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	    server->tcpStatus == CifsNew ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	    time_before(jiffies, server->lstrp + echo_interval - HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		goto requeue_echo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			 server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) requeue_echo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	queue_delayed_work(cifsiod_wq, &server->echo, server->echo_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) allocate_buffers(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	if (!server->bigbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		server->bigbuf = (char *)cifs_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		if (!server->bigbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			cifs_server_dbg(VFS, "No memory for large SMB response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 			msleep(3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			/* retry will check if exiting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	} else if (server->large_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		/* we are reusing a dirty large buf, clear its start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		memset(server->bigbuf, 0, HEADER_SIZE(server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	if (!server->smallbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		server->smallbuf = (char *)cifs_small_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		if (!server->smallbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			cifs_server_dbg(VFS, "No memory for SMB response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			/* retry will check if exiting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		/* beginning of smb buffer is cleared in our buf_get */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		/* if existing small buf clear beginning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		memset(server->smallbuf, 0, HEADER_SIZE(server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) server_unresponsive(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	 * We need to wait 3 echo intervals to make sure we handle such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	 * situations right:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	 * 1s  client sends a normal SMB request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	 * 2s  client gets a response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	 * 30s echo workqueue job pops, and decides we got a response recently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	 *     and don't need to send another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	 * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	 * 65s kernel_recvmsg times out, and we see that we haven't gotten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	 *     a response in >60s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	if ((server->tcpStatus == CifsGood ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	    server->tcpStatus == CifsNeedNegotiate) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	    (!server->ops->can_echo || server->ops->can_echo(server)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	    time_after(jiffies, server->lstrp + 3 * server->echo_interval)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			 (3 * server->echo_interval) / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) zero_credits(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	val = server->credits + server->echo_credits + server->oplock_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (server->in_flight == 0 && val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	int length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	int total_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	smb_msg->msg_control = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	smb_msg->msg_controllen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	for (total_read = 0; msg_data_left(smb_msg); total_read += length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		/* reconnect if no credits and no requests in flight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		if (zero_credits(server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		if (server_unresponsive(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		if (cifs_rdma_enabled(server) && server->smbd_conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			length = smbd_recv(server->smbd_conn, smb_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			length = sock_recvmsg(server->ssocket, smb_msg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		if (server->tcpStatus == CifsExiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			return -ESHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		if (server->tcpStatus == CifsNeedReconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		if (length == -ERESTARTSYS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		    length == -EAGAIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		    length == -EINTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			 * Minimum sleep to prevent looping, allowing socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			 * to clear and app threads to set tcpStatus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			 * CifsNeedReconnect if server hung.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		if (length <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			cifs_dbg(FYI, "Received no data or error: %d\n", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	return total_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		      unsigned int to_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	struct msghdr smb_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	struct kvec iov = {.iov_base = buf, .iov_len = to_read};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	iov_iter_kvec(&smb_msg.msg_iter, READ, &iov, 1, to_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	return cifs_readv_from_socket(server, &smb_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	unsigned int page_offset, unsigned int to_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	struct msghdr smb_msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	struct bio_vec bv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		.bv_page = page, .bv_len = to_read, .bv_offset = page_offset};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	iov_iter_bvec(&smb_msg.msg_iter, READ, &bv, 1, to_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	return cifs_readv_from_socket(server, &smb_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) is_smb_response(struct TCP_Server_Info *server, unsigned char type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	 * The first byte big endian of the length field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	 * is actually not part of the length but the type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	 * with the most common, zero, as regular data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	case RFC1002_SESSION_MESSAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		/* Regular SMB response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	case RFC1002_SESSION_KEEP_ALIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		cifs_dbg(FYI, "RFC 1002 session keep alive\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	case RFC1002_POSITIVE_SESSION_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		cifs_dbg(FYI, "RFC 1002 positive session response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	case RFC1002_NEGATIVE_SESSION_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		 * We get this from Windows 98 instead of an error on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		 * SMB negprot response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		cifs_dbg(FYI, "RFC 1002 negative session response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		/* give server a second to clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		 * Always try 445 first on reconnect since we get NACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		 * on some if we ever connected to port 139 (the NACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		 * is since we do not begin with RFC1001 session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		 * initialize frame).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		cifs_server_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) dequeue_mid(struct mid_q_entry *mid, bool malformed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) #ifdef CONFIG_CIFS_STATS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	mid->when_received = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (!malformed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		mid->mid_state = MID_RESPONSE_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		mid->mid_state = MID_RESPONSE_MALFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	 * Trying to handle/dequeue a mid after the send_recv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	 * function has finished processing it is a bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (mid->mid_flags & MID_DELETED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		pr_warn_once("trying to dequeue a deleted mid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		list_del_init(&mid->qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		mid->mid_flags |= MID_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) smb2_get_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	 * SMB1 does not use credits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	if (server->vals->header_preamble_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	return le16_to_cpu(shdr->CreditRequest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	   char *buf, int malformed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	if (server->ops->check_trans2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	    server->ops->check_trans2(mid, server, buf, malformed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	mid->credits_received = smb2_get_credits_from_hdr(buf, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	mid->resp_buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	mid->large_buf = server->large_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	/* Was previous buf put in mpx struct for multi-rsp? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (!mid->multiRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		/* smb buffer will be freed by user thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		if (server->large_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			server->bigbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			server->smallbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	dequeue_mid(mid, malformed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) static void clean_demultiplex_info(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	/* take it off the list, if it's not already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	list_del_init(&server->tcp_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	cancel_delayed_work_sync(&server->echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	server->tcpStatus = CifsExiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	wake_up_all(&server->response_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	/* check if we have blocked requests that need to free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	if (server->credits <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		server->credits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	 * Although there should not be any requests blocked on this queue it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	 * can not hurt to be paranoid and try to wake up requests that may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	 * haven been blocked when more than 50 at time were on the wire to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	 * same server - they now will see the session is in exit state and get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	 * out of SendReceive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	wake_up_all(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	/* give those requests time to exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	msleep(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	if (cifs_rdma_enabled(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		smbd_destroy(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	if (server->ssocket) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		sock_release(server->ssocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		server->ssocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	if (!list_empty(&server->pending_mid_q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		struct list_head dispose_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		struct mid_q_entry *mid_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		struct list_head *tmp, *tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		INIT_LIST_HEAD(&dispose_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			cifs_dbg(FYI, "Clearing mid 0x%llx\n", mid_entry->mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			kref_get(&mid_entry->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			mid_entry->mid_state = MID_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			list_move(&mid_entry->qhead, &dispose_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			mid_entry->mid_flags |= MID_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		/* now walk dispose list and issue callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		list_for_each_safe(tmp, tmp2, &dispose_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			cifs_dbg(FYI, "Callback mid 0x%llx\n", mid_entry->mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			list_del_init(&mid_entry->qhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			mid_entry->callback(mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			cifs_mid_q_entry_release(mid_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		/* 1/8th of sec is more than enough time for them to exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		msleep(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	if (!list_empty(&server->pending_mid_q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		 * mpx threads have not exited yet give them at least the smb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		 * send timeout time for long ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		 * Due to delays on oplock break requests, we need to wait at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		 * least 45 seconds before giving up on a request getting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		 * response and going ahead and killing cifsd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		cifs_dbg(FYI, "Wait for exit from demultiplex thread\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		msleep(46000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		 * If threads still have not exited they are probably never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		 * coming home not much else we can do but free the memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	kfree(server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	kfree(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	length = atomic_dec_return(&tcpSesAllocCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	if (length > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	char *buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	unsigned int pdu_length = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	/* make sure this will fit in a large buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		server->vals->header_preamble_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		return -ECONNABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/* switch to large buffer if too big for a small one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		server->large_buf = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		memcpy(server->bigbuf, buf, server->total_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		buf = server->bigbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	/* now read the rest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 				       pdu_length - HEADER_SIZE(server) + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 				       + server->vals->header_preamble_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	server->total_read += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	dump_smb(buf, server->total_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	return cifs_handle_standard(server, mid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	char *buf = server->large_buf ? server->bigbuf : server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	 * We know that we received enough to get to the MID as we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	 * checked the pdu_length earlier. Now check to see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	 * if the rest of the header is OK. We borrow the length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	 * var for the rest of the loop to avoid a new stack var.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	 * 48 bytes is enough to display the header and a little bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	 * into the payload for debugging purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	length = server->ops->check_message(buf, server->total_read, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	if (length != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		cifs_dump_mem("Bad SMB: ", buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			min_t(unsigned int, server->total_read, 48));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (server->ops->is_session_expired &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	    server->ops->is_session_expired(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	if (server->ops->is_status_pending &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	    server->ops->is_status_pending(buf, server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	if (!mid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	handle_mid(mid, server, buf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	 * SMB1 does not use credits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	if (server->vals->header_preamble_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	if (shdr->CreditRequest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		spin_lock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		server->credits += le16_to_cpu(shdr->CreditRequest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		spin_unlock(&server->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		wake_up(&server->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) cifs_demultiplex_thread(void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	int i, num_mids, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	struct TCP_Server_Info *server = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	unsigned int pdu_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	unsigned int next_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	char *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	struct task_struct *task_to_wake = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	struct mid_q_entry *mids[MAX_COMPOUND];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	char *bufs[MAX_COMPOUND];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	unsigned int noreclaim_flag, num_io_timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	noreclaim_flag = memalloc_noreclaim_save();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	length = atomic_inc_return(&tcpSesAllocCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	if (length > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	set_freezable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	allow_kernel_signal(SIGKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	while (server->tcpStatus != CifsExiting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if (try_to_freeze())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		if (!allocate_buffers(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		server->large_buf = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		pdu_length = 4; /* enough to get RFC1001 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		length = cifs_read_from_socket(server, buf, pdu_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		if (server->vals->header_preamble_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			server->total_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			server->total_read = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		 * The right amount was read from socket - 4 bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		 * so we can now interpret the length field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		pdu_length = get_rfc1002_length(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		cifs_dbg(FYI, "RFC1002 header 0x%x\n", pdu_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		if (!is_smb_response(server, buf[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) next_pdu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		server->pdu_size = pdu_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		/* make sure we have enough to get to the MID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		if (server->pdu_size < HEADER_SIZE(server) - 1 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		    server->vals->header_preamble_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			cifs_server_dbg(VFS, "SMB response too short (%u bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 				 server->pdu_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		/* read down to the MID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		length = cifs_read_from_socket(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			     buf + server->vals->header_preamble_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			     HEADER_SIZE(server) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			     - server->vals->header_preamble_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		if (length < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		server->total_read += length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		if (server->ops->next_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			next_offset = server->ops->next_header(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			if (next_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 				server->pdu_size = next_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		memset(mids, 0, sizeof(mids));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		memset(bufs, 0, sizeof(bufs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		num_mids = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		if (server->ops->is_transform_hdr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		    server->ops->receive_transform &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		    server->ops->is_transform_hdr(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			length = server->ops->receive_transform(server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 								mids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 								bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 								&num_mids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 			mids[0] = server->ops->find_mid(server, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			bufs[0] = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			num_mids = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			if (!mids[0] || !mids[0]->receive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 				length = standard_receive3(server, mids[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 				length = mids[0]->receive(server, mids[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		if (length < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 			for (i = 0; i < num_mids; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 				if (mids[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 					cifs_mid_q_entry_release(mids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		if (server->ops->is_status_io_timeout &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		    server->ops->is_status_io_timeout(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			num_io_timeout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			if (num_io_timeout > NUM_STATUS_IO_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 				cifs_reconnect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 				num_io_timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		server->lstrp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		for (i = 0; i < num_mids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			if (mids[i] != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 				mids[i]->resp_buf_size = server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 				if (!mids[i]->multiRsp || mids[i]->multiEnd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 					mids[i]->callback(mids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 				cifs_mid_q_entry_release(mids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			} else if (server->ops->is_oplock_break &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 				   server->ops->is_oplock_break(bufs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 								server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 				smb2_add_credits_from_hdr(bufs[i], server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 				cifs_dbg(FYI, "Received oplock break\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 				cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 						atomic_read(&midCount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 				cifs_dump_mem("Received Data is: ", bufs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 					      HEADER_SIZE(server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 				smb2_add_credits_from_hdr(bufs[i], server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				if (server->ops->dump_detail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 					server->ops->dump_detail(bufs[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 								 server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 				cifs_dump_mids(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) #endif /* CIFS_DEBUG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		if (pdu_length > server->pdu_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 			if (!allocate_buffers(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			pdu_length -= server->pdu_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			server->total_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			server->large_buf = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			buf = server->smallbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			goto next_pdu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	} /* end while !EXITING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	/* buffer usually freed in free_mid - need to free it here on exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	cifs_buf_release(server->bigbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (server->smallbuf) /* no sense logging a debug message if NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		cifs_small_buf_release(server->smallbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	task_to_wake = xchg(&server->tsk, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	clean_demultiplex_info(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	/* if server->tsk was NULL then wait for a signal before exiting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	if (!task_to_wake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		while (!signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	memalloc_noreclaim_restore(noreclaim_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	module_put_and_exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) /* extract the host portion of the UNC string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) extract_hostname(const char *unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	const char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	char *dst, *delim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	/* skip double chars at beginning of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	/* BB: check validity of these bytes? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	if (strlen(unc) < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	for (src = unc; *src && *src == '\\'; src++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	if (!*src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	/* delimiter between hostname and sharename is always '\\' now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	delim = strchr(src, '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	if (!delim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	len = delim - src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	dst = kmalloc((len + 1), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	if (dst == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	memcpy(dst, src, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	dst[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	return dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) static int get_option_ul(substring_t args[], unsigned long *option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	char *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	rc = kstrtoul(string, 0, option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	kfree(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static int get_option_uid(substring_t args[], kuid_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	kuid_t uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	rc = get_option_ul(args, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	uid = make_kuid(current_user_ns(), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	if (!uid_valid(uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	*result = uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static int get_option_gid(substring_t args[], kgid_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	kgid_t gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	rc = get_option_ul(args, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	gid = make_kgid(current_user_ns(), value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	if (!gid_valid(gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	*result = gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)  * Parse a devname into substrings and populate the vol->UNC and vol->prepath
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)  * fields with the result. Returns 0 on success and an error otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) cifs_parse_devname(const char *devname, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	char *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	const char *delims = "/\\";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	if (unlikely(!devname || !*devname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		cifs_dbg(VFS, "Device name not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	/* make sure we have a valid UNC double delimiter prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	len = strspn(devname, delims);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	if (len != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	/* find delimiter between host and sharename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	pos = strpbrk(devname + 2, delims);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (!pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	/* skip past delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	++pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	/* now go until next delimiter or end of string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	len = strcspn(pos, delims);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	/* move "pos" up to delimiter or NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	if (!vol->UNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	convert_delimiter(vol->UNC, '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	/* skip any delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	if (*pos == '/' || *pos == '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	/* If pos is NULL then no prepath */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	if (!*pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	vol->prepath = kstrdup(pos, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	if (!vol->prepath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) cifs_parse_mount_options(const char *mountdata, const char *devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			 struct smb_vol *vol, bool is_smb3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	char *data, *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	char *mountdata_copy = NULL, *options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	unsigned int  temp_len, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	char separator[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	short int override_uid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	short int override_gid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	bool uid_specified = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	bool gid_specified = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	bool sloppy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	char *invalid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	char *nodename = utsname()->nodename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	char *string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	char *tmp_end, *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	char delim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	bool got_ip = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	bool got_version = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	unsigned short port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	separator[0] = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	separator[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	delim = separator[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	/* ensure we always start with zeroed-out smb_vol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	memset(vol, 0, sizeof(*vol));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	 * does not have to be perfect mapping since field is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	 * informational, only used for servers that do not support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	 * port 445 and it can be overridden at mount time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		vol->source_rfc1001_name[i] = toupper(nodename[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	/* null target name indicates to use *SMBSERVR default called name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	   if we end up sending RFC1001 session initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	vol->target_rfc1001_name[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	vol->cred_uid = current_uid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	vol->linux_uid = current_uid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	vol->linux_gid = current_gid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	vol->bsize = 1024 * 1024; /* can improve cp performance significantly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	 * default to SFM style remapping of seven reserved characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	 * unless user overrides it or we negotiate CIFS POSIX where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	 * it is unnecessary.  Can not simultaneously use more than one mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	 * since then readdir could list files that open could not open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	vol->remap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	/* default to only allowing write access to owner of the mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	/* default is always to request posix paths. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	vol->posix_paths = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	/* default to using server inode numbers where available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	vol->server_ino = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	/* default is to use strict cifs caching semantics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	vol->strict_io = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	vol->actimeo = CIFS_DEF_ACTIMEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	/* Most clients set timeout to 0, allows server to use its default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	vol->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	/* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	vol->ops = &smb30_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	vol->vals = &smbdefault_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	/* default to no multichannel (single server connection) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	vol->multichannel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	vol->max_channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	if (!mountdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	mountdata_copy = kstrndup(mountdata, PAGE_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	if (!mountdata_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	options = mountdata_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	end = options + strlen(options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	if (strncmp(options, "sep=", 4) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		if (options[4] != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 			separator[0] = options[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			options += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 			cifs_dbg(FYI, "Null separator not allowed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	vol->backupuid_specified = false; /* no backup intent for a user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	vol->backupgid_specified = false; /* no backup intent for a group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	switch (cifs_parse_devname(devname, vol)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	case -ENOMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		cifs_dbg(VFS, "Unable to allocate memory for devname\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	case -EINVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		cifs_dbg(VFS, "Malformed UNC in devname\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		cifs_dbg(VFS, "Unknown error parsing devname\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	while ((data = strsep(&options, separator)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		substring_t args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		unsigned long option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 		int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		if (!*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		token = match_token(data, cifs_mount_option_tokens, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		/* Ingnore the following */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		case Opt_ignore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		/* Boolean values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		case Opt_user_xattr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 			vol->no_xattr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		case Opt_nouser_xattr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			vol->no_xattr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		case Opt_forceuid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 			override_uid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		case Opt_noforceuid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 			override_uid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		case Opt_forcegid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			override_gid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		case Opt_noforcegid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 			override_gid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		case Opt_noblocksend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			vol->noblocksnd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		case Opt_noautotune:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			vol->noautotune = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		case Opt_nolease:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			vol->no_lease = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		case Opt_hard:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 			vol->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		case Opt_soft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 			vol->retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		case Opt_perm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			vol->noperm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		case Opt_noperm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			vol->noperm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		case Opt_nodelete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 			vol->nodelete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		case Opt_mapchars:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 			vol->sfu_remap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			vol->remap = false; /* disable SFM mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		case Opt_nomapchars:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			vol->sfu_remap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		case Opt_mapposix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 			vol->remap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 			vol->sfu_remap = false; /* disable SFU mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		case Opt_nomapposix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 			vol->remap = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		case Opt_sfu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 			vol->sfu_emul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		case Opt_nosfu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 			vol->sfu_emul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		case Opt_nodfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 			vol->nodfs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		case Opt_rootfs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) #ifdef CONFIG_CIFS_ROOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 			vol->rootfs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		case Opt_posixpaths:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 			vol->posix_paths = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		case Opt_noposixpaths:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 			vol->posix_paths = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		case Opt_nounix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 			if (vol->linux_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 				cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 					"conflicting unix mount options\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 			vol->no_linux_ext = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		case Opt_unix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 			if (vol->no_linux_ext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 				cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 					"conflicting unix mount options\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 			vol->linux_ext = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		case Opt_nocase:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 			vol->nocase = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		case Opt_brl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 			vol->nobrl =  0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		case Opt_nobrl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 			vol->nobrl =  1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 			 * turn off mandatory locking in mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			 * if remote locking is turned off since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			 * local vfs will do advisory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 			if (vol->file_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 				(S_IALLUGO & ~(S_ISUID | S_IXGRP)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 				vol->file_mode = S_IALLUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 		case Opt_nohandlecache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 			vol->nohandlecache = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 		case Opt_handlecache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			vol->nohandlecache = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 		case Opt_forcemandatorylock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 			vol->mand_lock = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		case Opt_setuids:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 			vol->setuids = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		case Opt_nosetuids:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 			vol->setuids = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		case Opt_setuidfromacl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 			vol->setuidfromacl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		case Opt_dynperm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 			vol->dynperm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		case Opt_nodynperm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 			vol->dynperm = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		case Opt_nohard:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			vol->retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		case Opt_nosoft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 			vol->retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		case Opt_nointr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 			vol->intr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		case Opt_intr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			vol->intr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		case Opt_nostrictsync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 			vol->nostrictsync = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		case Opt_strictsync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			vol->nostrictsync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		case Opt_serverino:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 			vol->server_ino = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		case Opt_noserverino:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 			vol->server_ino = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		case Opt_rwpidforward:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 			vol->rwpidforward = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		case Opt_modesid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 			vol->mode_ace = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 		case Opt_cifsacl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 			vol->cifs_acl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 		case Opt_nocifsacl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 			vol->cifs_acl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		case Opt_acl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 			vol->no_psx_acl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		case Opt_noacl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 			vol->no_psx_acl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		case Opt_locallease:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 			vol->local_lease = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		case Opt_sign:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 			vol->sign = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		case Opt_ignore_signature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 			vol->sign = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			vol->ignore_signature = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		case Opt_seal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 			/* we do not do the following in secFlags because seal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 			 * is a per tree connection (mount) not a per socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			 * or per-smb connection option in the protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 			 * vol->secFlg |= CIFSSEC_MUST_SEAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 			vol->seal = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		case Opt_noac:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		case Opt_fsc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) #ifndef CONFIG_CIFS_FSCACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 			goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 			vol->fsc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		case Opt_mfsymlinks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 			vol->mfsymlinks = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		case Opt_multiuser:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 			vol->multiuser = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		case Opt_sloppy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 			sloppy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		case Opt_nosharesock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 			vol->nosharesock = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 		case Opt_nopersistent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 			vol->nopersistent = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 			if (vol->persistent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 				cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 				  "persistenthandles mount options conflict\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 		case Opt_persistent:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 			vol->persistent = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 			if ((vol->nopersistent) || (vol->resilient)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 				cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 				  "persistenthandles mount options conflict\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		case Opt_resilient:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			vol->resilient = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			if (vol->persistent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 				cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 				  "persistenthandles mount options conflict\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		case Opt_noresilient:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 			vol->resilient = false; /* already the default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		case Opt_domainauto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 			vol->domainauto = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		case Opt_rdma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 			vol->rdma = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		case Opt_multichannel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 			vol->multichannel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			/* if number of channels not specified, default to 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 			if (vol->max_channels < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 				vol->max_channels = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		case Opt_nomultichannel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 			vol->multichannel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 			vol->max_channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		case Opt_compress:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			vol->compression = UNKNOWN_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 				"SMB3 compression support is experimental\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		/* Numeric Values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 		case Opt_backupuid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 			if (get_option_uid(args, &vol->backupuid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 				cifs_dbg(VFS, "%s: Invalid backupuid value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 			vol->backupuid_specified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		case Opt_backupgid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 			if (get_option_gid(args, &vol->backupgid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 				cifs_dbg(VFS, "%s: Invalid backupgid value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			vol->backupgid_specified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		case Opt_uid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 			if (get_option_uid(args, &vol->linux_uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 				cifs_dbg(VFS, "%s: Invalid uid value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 			uid_specified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		case Opt_cruid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 			if (get_option_uid(args, &vol->cred_uid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 				cifs_dbg(VFS, "%s: Invalid cruid value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 		case Opt_gid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 			if (get_option_gid(args, &vol->linux_gid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 				cifs_dbg(VFS, "%s: Invalid gid value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 			gid_specified = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 		case Opt_file_mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 				cifs_dbg(VFS, "%s: Invalid file_mode value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 			vol->file_mode = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 		case Opt_dirmode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 				cifs_dbg(VFS, "%s: Invalid dir_mode value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 			vol->dir_mode = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		case Opt_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 			if (get_option_ul(args, &option) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			    option > USHRT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 				cifs_dbg(VFS, "%s: Invalid port value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			port = (unsigned short)option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		case Opt_min_enc_offload:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 				cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 			vol->min_offload = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		case Opt_blocksize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 				cifs_dbg(VFS, "%s: Invalid blocksize value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 					__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 			 * inode blocksize realistically should never need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 			 * less than 16K or greater than 16M and default is 1MB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 			 * Note that small inode block sizes (e.g. 64K) can lead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			 * to very poor performance of common tools like cp and scp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 			if ((option < CIFS_MAX_MSGSIZE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 			   (option > (4 * SMB3_DEFAULT_IOSIZE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 				cifs_dbg(VFS, "%s: Invalid blocksize\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 					__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 			vol->bsize = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		case Opt_rsize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 				cifs_dbg(VFS, "%s: Invalid rsize value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 			vol->rsize = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 		case Opt_wsize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 				cifs_dbg(VFS, "%s: Invalid wsize value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 			vol->wsize = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		case Opt_actimeo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 				cifs_dbg(VFS, "%s: Invalid actimeo value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 			vol->actimeo = HZ * option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 			if (vol->actimeo > CIFS_MAX_ACTIMEO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 				cifs_dbg(VFS, "attribute cache timeout too large\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		case Opt_handletimeout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 				cifs_dbg(VFS, "%s: Invalid handletimeout value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 			vol->handle_timeout = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 			if (vol->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 				cifs_dbg(VFS, "Invalid handle cache timeout, longer than 16 minutes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		case Opt_echo_interval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 				cifs_dbg(VFS, "%s: Invalid echo interval value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 			vol->echo_interval = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		case Opt_snapshot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			if (get_option_ul(args, &option)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 				cifs_dbg(VFS, "%s: Invalid snapshot time\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 			vol->snapshot_time = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		case Opt_max_credits:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 			if (get_option_ul(args, &option) || (option < 20) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 			    (option > 60000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 				cifs_dbg(VFS, "%s: Invalid max_credits value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 					 __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 			vol->max_credits = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		case Opt_max_channels:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 			if (get_option_ul(args, &option) || option < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 				option > CIFS_MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 				cifs_dbg(VFS, "%s: Invalid max_channels value, needs to be 1-%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 					 __func__, CIFS_MAX_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 			vol->max_channels = option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		/* String Arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 		case Opt_blank_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 			/* null user, ie. anonymous authentication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 			vol->nullauth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			vol->username = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		case Opt_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 			if (strnlen(string, CIFS_MAX_USERNAME_LEN) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 							CIFS_MAX_USERNAME_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 				pr_warn("username too long\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 			kfree(vol->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 			vol->username = kstrdup(string, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 			if (!vol->username)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		case Opt_blank_pass:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			/* passwords have to be handled differently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 			 * to allow the character used for deliminator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 			 * to be passed within them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 			 * Check if this is a case where the  password
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 			 * starts with a delimiter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 			tmp_end = strchr(data, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 			tmp_end++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 			if (!(tmp_end < end && tmp_end[1] == delim)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 				/* No it is not. Set the password to NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 				kfree_sensitive(vol->password);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 				vol->password = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 			fallthrough;	/* to Opt_pass below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		case Opt_pass:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 			/* Obtain the value string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 			value = strchr(data, '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 			value++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 			/* Set tmp_end to end of the string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 			tmp_end = (char *) value + strlen(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 			/* Check if following character is the deliminator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 			 * If yes, we have encountered a double deliminator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 			 * reset the NULL character to the deliminator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 			if (tmp_end < end && tmp_end[1] == delim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 				tmp_end[0] = delim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 				/* Keep iterating until we get to a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 				 * deliminator OR the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 				while ((tmp_end = strchr(tmp_end, delim))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 					!= NULL && (tmp_end[1] == delim)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 						tmp_end = (char *) &tmp_end[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 				/* Reset var options to point to next element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 				if (tmp_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 					tmp_end[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 					options = (char *) &tmp_end[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 				} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 					/* Reached the end of the mount option
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 					 * string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 					options = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			kfree_sensitive(vol->password);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 			/* Now build new password string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 			temp_len = strlen(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 			vol->password = kzalloc(temp_len+1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 			if (vol->password == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 				pr_warn("no memory for password\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 			for (i = 0, j = 0; i < temp_len; i++, j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 				vol->password[j] = value[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 				if ((value[i] == delim) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 				     value[i+1] == delim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 					/* skip the second deliminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 					i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 			vol->password[j] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		case Opt_blank_ip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 			/* FIXME: should this be an error instead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 			got_ip = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		case Opt_ip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 			if (!cifs_convert_address(dstaddr, string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 					strlen(string))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 				pr_err("bad ip= option (%s)\n", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 			got_ip = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		case Opt_domain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 			if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 					== CIFS_MAX_DOMAINNAME_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 				pr_warn("domain name too long\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 			kfree(vol->domainname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 			vol->domainname = kstrdup(string, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 			if (!vol->domainname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 				pr_warn("no memory for domainname\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 			cifs_dbg(FYI, "Domain name set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 		case Opt_srcaddr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 			if (!cifs_convert_address(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 					(struct sockaddr *)&vol->srcaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 					string, strlen(string))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 				pr_warn("Could not parse srcaddr: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 					string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		case Opt_iocharset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 			if (strnlen(string, 1024) >= 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 				pr_warn("iocharset name too long\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 			 if (strncasecmp(string, "default", 7) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 				kfree(vol->iocharset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 				vol->iocharset = kstrdup(string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 							 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 				if (!vol->iocharset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 					pr_warn("no memory for charset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 					goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 			/* if iocharset not set then load_nls_default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 			 * is used by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 			 cifs_dbg(FYI, "iocharset set to %s\n", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		case Opt_netbiosname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 			memset(vol->source_rfc1001_name, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 				RFC1001_NAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 			 * FIXME: are there cases in which a comma can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			 * be valid in workstation netbios name (and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 			 * need special handling)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 			for (i = 0; i < RFC1001_NAME_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 				/* don't ucase netbiosname for user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 				if (string[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 				vol->source_rfc1001_name[i] = string[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 			/* The string has 16th byte zero still from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			 * set at top of the function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 			if (i == RFC1001_NAME_LEN && string[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 				pr_warn("netbiosname longer than 15 truncated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		case Opt_servern:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 			/* servernetbiosname specified override *SMBSERVER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 			/* last byte, type, is 0x20 for servr type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 			memset(vol->target_rfc1001_name, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 				RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			/* BB are there cases in which a comma can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 			   valid in this workstation netbios name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 			   (and need special handling)? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 			/* user or mount helper must uppercase the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 			   netbios name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 			for (i = 0; i < 15; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 				if (string[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 				vol->target_rfc1001_name[i] = string[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			/* The string has 16th byte zero still from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 			   set at top of the function  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 			if (i == RFC1001_NAME_LEN && string[i] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 				pr_warn("server netbiosname longer than 15 truncated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		case Opt_ver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 			/* version of mount userspace tools, not dialect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 			/* If interface changes in mount.cifs bump to new ver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 			if (strncasecmp(string, "1", 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 				if (strlen(string) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 					pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 						string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 					goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 				/* This is the default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			/* For all other value, error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			pr_warn("Invalid mount helper version specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 			goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 		case Opt_vers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 			/* protocol version (dialect) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			if (cifs_parse_smb_version(string, vol, is_smb3) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			got_version = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		case Opt_sec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 			if (cifs_parse_security_flavors(string, vol) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 		case Opt_cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 			string = match_strdup(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 			if (string == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 				goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 			if (cifs_parse_cache_flavor(string, vol) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 				goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 			 * An option we don't recognize. Save it off for later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 			 * if we haven't already found one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 			if (!invalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 				invalid = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		/* Free up any allocated string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 		kfree(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	if (!sloppy && invalid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		pr_err("Unknown mount option \"%s\"\n", invalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	if (vol->rdma && vol->vals->protocol_id < SMB30_PROT_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 		cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) #ifndef CONFIG_KEYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	/* Muliuser mounts require CONFIG_KEYS support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	if (vol->multiuser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 		cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	if (!vol->UNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 		cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	/* make sure UNC has a share name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	if (!strchr(vol->UNC + 3, '\\')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	if (!got_ip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		const char *slash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		/* No ip= option specified? Try to get it from UNC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		/* Use the address part of the UNC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		slash = strchr(&vol->UNC[2], '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		len = slash - &vol->UNC[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 			pr_err("Unable to determine destination address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 			goto cifs_parse_mount_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	/* set the port that we got earlier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	cifs_set_port(dstaddr, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	if (uid_specified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 		vol->override_uid = override_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	else if (override_uid == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 		pr_notice("ignoring forceuid mount option specified with no uid= option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	if (gid_specified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		vol->override_gid = override_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	else if (override_gid == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		pr_notice("ignoring forcegid mount option specified with no gid= option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	if (got_version == false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 		pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	kfree(mountdata_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) out_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	pr_warn("Could not allocate temporary buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) cifs_parse_mount_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	kfree(string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	kfree(mountdata_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) /** Returns true if srcaddr isn't specified and rhs isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)  * specified, or if srcaddr is specified and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)  * matches the IP address of the rhs argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	switch (srcaddr->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	case AF_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 		return (rhs->sa_family == AF_UNSPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	case AF_INET: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 		struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	case AF_INET6: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		return false; /* don't expect to be here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)  * If no port is specified in addr structure, we try to match with 445 port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)  * and if it fails - with 139 ports. It should be called only if address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)  * families of server and addr are equal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	__be16 port, *sport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	/* SMBDirect manages its own ports, don't match it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	if (server->rdma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	switch (addr->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		port = ((struct sockaddr_in *) addr)->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 		sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 		port = ((struct sockaddr_in6 *) addr)->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		port = htons(CIFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		if (port == *sport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 		port = htons(RFC1001_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	return port == *sport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	      struct sockaddr *srcaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	switch (addr->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	case AF_INET: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		struct sockaddr_in *srv_addr4 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 					(struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	case AF_INET6: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 		struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 		struct sockaddr_in6 *srv_addr6 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 					(struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		if (!ipv6_addr_equal(&addr6->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 				     &srv_addr6->sin6_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		return false; /* don't expect to be here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	if (!cifs_match_ipaddr(srcaddr, (struct sockaddr *)&server->srcaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	 * The select_sectype function should either return the vol->sectype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	 * that was specified, or "Unspecified" if that sectype was not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	 * compatible with the given NEGOTIATE request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	if (server->ops->select_sectype(server, vol->sectype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	     == Unspecified)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	 * Now check if signing mode is acceptable. No need to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	 * global_secflags at this point since if MUST_SIGN is set then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	 * the server->sign had better be too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	if (vol->sign && !server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	if (vol->nosharesock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	/* If multidialect negotiation see if existing sessions match one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 		if (server->vals->protocol_id < SMB30_PROT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	} else if (strcmp(vol->vals->version_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		   SMBDEFAULT_VERSION_STRING) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		if (server->vals->protocol_id < SMB21_PROT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	} else if ((server->vals != vol->vals) || (server->ops != vol->ops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	if (!match_address(server, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 			   (struct sockaddr *)&vol->srcaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	if (!match_port(server, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	if (!match_security(server, vol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	if (server->echo_interval != vol->echo_interval * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	if (server->rdma != vol->rdma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	if (server->ignore_signature != vol->ignore_signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	if (server->min_offload != vol->min_offload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) struct TCP_Server_Info *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) cifs_find_tcp_session(struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	struct TCP_Server_Info *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 		 * Skip ses channels since they're only handled in lower layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		 * (e.g. cifs_send_recv).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 		if (server->is_channel || !match_server(server, vol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		++server->srv_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 		cifs_dbg(FYI, "Existing tcp session with server found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 		return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	struct task_struct *task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	if (--server->srv_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	put_net(cifs_net_ns(server));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	list_del_init(&server->tcp_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	cancel_delayed_work_sync(&server->echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	if (from_reconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		 * Avoid deadlock here: reconnect work calls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		 * cifs_put_tcp_session() at its end. Need to be sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 		 * that reconnect work does nothing with server pointer after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		 * that step.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		cancel_delayed_work(&server->reconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 		cancel_delayed_work_sync(&server->reconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	server->tcpStatus = CifsExiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	cifs_crypto_secmech_release(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	cifs_fscache_release_client_cookie(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	kfree(server->session_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	server->session_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	server->session_key.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	task = xchg(&server->tsk, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	if (task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		send_sig(SIGKILL, task, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) struct TCP_Server_Info *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) cifs_get_tcp_session(struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	struct TCP_Server_Info *tcp_ses = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	/* see if we already have a matching tcp_ses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	tcp_ses = cifs_find_tcp_session(volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 	if (tcp_ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		return tcp_ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	if (!tcp_ses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	tcp_ses->ops = volume_info->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	tcp_ses->vals = volume_info->vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	tcp_ses->hostname = extract_hostname(volume_info->UNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	if (IS_ERR(tcp_ses->hostname)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		rc = PTR_ERR(tcp_ses->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 		goto out_err_crypto_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	tcp_ses->noblockcnt = volume_info->rootfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	tcp_ses->noautotune = volume_info->noautotune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	tcp_ses->rdma = volume_info->rdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	tcp_ses->in_flight = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	tcp_ses->max_in_flight = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 	tcp_ses->credits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	init_waitqueue_head(&tcp_ses->response_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	init_waitqueue_head(&tcp_ses->request_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	mutex_init(&tcp_ses->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	memcpy(tcp_ses->workstation_RFC1001_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	memcpy(tcp_ses->server_RFC1001_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	tcp_ses->session_estab = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	tcp_ses->sequence_number = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	tcp_ses->reconnect_instance = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	tcp_ses->lstrp = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	tcp_ses->compress_algorithm = cpu_to_le16(volume_info->compression);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	spin_lock_init(&tcp_ses->req_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	mutex_init(&tcp_ses->reconnect_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	       sizeof(tcp_ses->srcaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 		sizeof(tcp_ses->dstaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	if (volume_info->use_client_guid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 		memcpy(tcp_ses->client_guid, volume_info->client_guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		       SMB2_CLIENT_GUID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		generate_random_uuid(tcp_ses->client_guid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	 * at this point we are the only ones with the pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	 * to the struct since the kernel thread not created yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	 * no need to spinlock this init of tcpStatus or srv_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	tcp_ses->tcpStatus = CifsNew;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	++tcp_ses->srv_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		tcp_ses->echo_interval = volume_info->echo_interval * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 		tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	if (tcp_ses->rdma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) #ifndef CONFIG_CIFS_SMB_DIRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		goto out_err_crypto_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 		tcp_ses->smbd_conn = smbd_get_connection(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 			tcp_ses, (struct sockaddr *)&volume_info->dstaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		if (tcp_ses->smbd_conn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 			cifs_dbg(VFS, "RDMA transport established\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 			goto smbd_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 			rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 			goto out_err_crypto_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	rc = ip_connect(tcp_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		goto out_err_crypto_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) smbd_connected:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	 * since we're in a cifs function already, we know that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	 * this will succeed. No need for try_module_get().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	__module_get(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	tcp_ses->tsk = kthread_run(cifs_demultiplex_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 				  tcp_ses, "cifsd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	if (IS_ERR(tcp_ses->tsk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		rc = PTR_ERR(tcp_ses->tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 		cifs_dbg(VFS, "error %d create cifsd thread\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 		module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 		goto out_err_crypto_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	tcp_ses->min_offload = volume_info->min_offload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	tcp_ses->tcpStatus = CifsNeedNegotiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	if ((volume_info->max_credits < 20) || (volume_info->max_credits > 60000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 		tcp_ses->max_credits = SMB2_MAX_CREDITS_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 		tcp_ses->max_credits = volume_info->max_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	tcp_ses->nr_targets = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	tcp_ses->ignore_signature = volume_info->ignore_signature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	/* thread spawned, put it on the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	cifs_fscache_get_client_cookie(tcp_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	/* queue echo request delayed work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	return tcp_ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) out_err_crypto_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	cifs_crypto_secmech_release(tcp_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	put_net(cifs_net_ns(tcp_ses));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	if (tcp_ses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		if (!IS_ERR(tcp_ses->hostname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 			kfree(tcp_ses->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		if (tcp_ses->ssocket)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 			sock_release(tcp_ses->ssocket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		kfree(tcp_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	if (vol->sectype != Unspecified &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	    vol->sectype != ses->sectype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	 * If an existing session is limited to less channels than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	 * requested, it should not be reused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	if (ses->chan_max < vol->max_channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	switch (ses->sectype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	case Kerberos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		if (!uid_eq(vol->cred_uid, ses->cred_uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 		/* NULL username means anonymous session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 		if (ses->user_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 			if (!vol->nullauth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		/* anything else takes username/password */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		if (strncmp(ses->user_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			    vol->username ? vol->username : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 			    CIFS_MAX_USERNAME_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 		if ((vol->username && strlen(vol->username) != 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 		    ses->password != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		    strncmp(ses->password,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 			    vol->password ? vol->password : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 			    CIFS_MAX_PASSWORD_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)  * cifs_setup_ipc - helper to setup the IPC tcon for the session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)  * A new IPC connection is made and stored in the session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)  * tcon_ipc. The IPC tcon has the same lifetime as the session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	int rc = 0, xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	struct nls_table *nls_codepage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$")] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	bool seal = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 	struct TCP_Server_Info *server = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	 * If the mount request that resulted in the creation of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	 * session requires encryption, force IPC to be encrypted too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	if (volume_info->seal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 			seal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 			cifs_server_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 				 "IPC: server doesn't support encryption\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	tcon = tconInfoAlloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 	if (tcon == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	/* cannot fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	nls_codepage = load_nls_default();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	tcon->ses = ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	tcon->ipc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	tcon->seal = seal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		tconInfoFree(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	cifs_dbg(FYI, "IPC tcon rc = %d ipc tid = %d\n", rc, tcon->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	ses->tcon_ipc = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	unload_nls(nls_codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)  * cifs_free_ipc - helper to release the session IPC tcon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)  * Needs to be called everytime a session is destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) cifs_free_ipc(struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	int rc = 0, xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	struct cifs_tcon *tcon = ses->tcon_ipc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	if (tcon == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	if (ses->server->ops->tree_disconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 		xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 		rc = ses->server->ops->tree_disconnect(xid, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 		cifs_dbg(FYI, "failed to disconnect IPC tcon (rc=%d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	tconInfoFree(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 	ses->tcon_ipc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) static struct cifs_ses *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 		if (ses->status == CifsExiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 		if (!match_session(ses, vol))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 		++ses->ses_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		return ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) void cifs_put_smb_ses(struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	unsigned int rc, xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	struct TCP_Server_Info *server = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	if (ses->status == CifsExiting) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	if (--ses->ses_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	if (ses->status == CifsGood)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		ses->status = CifsExiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	cifs_free_ipc(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	if (ses->status == CifsExiting && server->ops->logoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		rc = server->ops->logoff(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 			cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 				__func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		_free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	list_del_init(&ses->smb_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	/* close any extra channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	if (ses->chan_count > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		for (i = 1; i < ses->chan_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			cifs_put_tcp_session(ses->chans[i].server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	sesInfoFree(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	cifs_put_tcp_session(server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) #ifdef CONFIG_KEYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) /* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) #define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) /* Populate username and pw fields from keyring if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	int is_domain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	const char *delim, *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	char *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	struct TCP_Server_Info *server = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	struct sockaddr_in *sa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	struct sockaddr_in6 *sa6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	const struct user_key_payload *upayload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	/* try to find an address key first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	switch (server->dstaddr.ss_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		sa = (struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 		sa6 = (struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		cifs_dbg(FYI, "Bad ss_family (%hu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 			 server->dstaddr.ss_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	key = request_key(&key_type_logon, desc, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	if (IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 		if (!ses->domainName) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 			cifs_dbg(FYI, "domainName is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 			rc = PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		/* didn't work, try to find a domain key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		sprintf(desc, "cifs:d:%s", ses->domainName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		key = request_key(&key_type_logon, desc, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		if (IS_ERR(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 			rc = PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 		is_domain = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	down_read(&key->sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	upayload = user_key_payload_locked(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	if (IS_ERR_OR_NULL(upayload)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		rc = upayload ? PTR_ERR(upayload) : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	/* find first : in payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	payload = upayload->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	delim = strnchr(payload, upayload->datalen, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	cifs_dbg(FYI, "payload=%s\n", payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	if (!delim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 			 upayload->datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	len = delim - payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	if (len > CIFS_MAX_USERNAME_LEN || len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		cifs_dbg(FYI, "Bad value from username search (len=%zd)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 			 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	vol->username = kstrndup(payload, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	if (!vol->username) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 			 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	len = key->datalen - (len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 	if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 		cifs_dbg(FYI, "Bad len for password search (len=%zd)\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		kfree(vol->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 		vol->username = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	++delim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	vol->password = kstrndup(delim, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	if (!vol->password) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 		cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 			 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		kfree(vol->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 		vol->username = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	 * If we have a domain key then we must set the domainName in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	 * for the request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	if (is_domain && ses->domainName) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 		vol->domainname = kstrndup(ses->domainName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 					   strlen(ses->domainName),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 					   GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 		if (!vol->domainname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 			cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 				 len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 			kfree(vol->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 			vol->username = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 			kfree_sensitive(vol->password);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 			vol->password = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 			goto out_key_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) out_key_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	up_read(&key->sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	kfree(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	cifs_dbg(FYI, "%s: returning %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) #else /* ! CONFIG_KEYS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		   struct cifs_ses *ses __attribute__((unused)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) #endif /* CONFIG_KEYS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)  * cifs_get_smb_ses - get a session matching @volume_info data from @server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)  * This function assumes it is being called from cifs_mount() where we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)  * already got a server reference (server refcount +1). See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)  * cifs_get_tcon() for refcount explanations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) struct cifs_ses *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	ses = cifs_find_smb_ses(server, volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	if (ses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 		cifs_dbg(FYI, "Existing smb sess found (status=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 			 ses->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		mutex_lock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		rc = cifs_negotiate_protocol(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 			mutex_unlock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 			/* problem -- put our ses reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 			cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 			free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 			return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 		if (ses->need_reconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 			cifs_dbg(FYI, "Session needs reconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 			rc = cifs_setup_session(xid, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 						volume_info->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 				mutex_unlock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 				/* problem -- put our reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 				cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 				free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 				return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 		mutex_unlock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		/* existing SMB ses has a server reference already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		cifs_put_tcp_session(server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		return ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 	cifs_dbg(FYI, "Existing smb sess not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	ses = sesInfoAlloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	if (ses == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 		goto get_ses_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	/* new SMB session uses our server ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	ses->server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	if (server->dstaddr.ss_family == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 		sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 		sprintf(ses->serverName, "%pI4", &addr->sin_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	if (volume_info->username) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 		ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 		if (!ses->user_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 			goto get_ses_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	/* volume_info->password freed at unmount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	if (volume_info->password) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		ses->password = kstrdup(volume_info->password, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 		if (!ses->password)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 			goto get_ses_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	if (volume_info->domainname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 		if (!ses->domainName)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 			goto get_ses_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	if (volume_info->domainauto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 		ses->domainAuto = volume_info->domainauto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	ses->cred_uid = volume_info->cred_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 	ses->linux_uid = volume_info->linux_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	ses->sectype = volume_info->sectype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	ses->sign = volume_info->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	mutex_lock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	/* add server as first channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	ses->chans[0].server = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	ses->chan_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	ses->chan_max = volume_info->multichannel ? volume_info->max_channels:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	rc = cifs_negotiate_protocol(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		rc = cifs_setup_session(xid, ses, volume_info->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	/* each channel uses a different signing key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	memcpy(ses->chans[0].signkey, ses->smb3signingkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	       sizeof(ses->smb3signingkey));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	mutex_unlock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 		goto get_ses_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	/* success, put it on the list and add it as first channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	list_add(&ses->smb_ses_list, &server->smb_ses_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	cifs_setup_ipc(ses, volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	return ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) get_ses_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 	sesInfoFree(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	if (tcon->tidStatus == CifsExiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	if (tcon->seal != volume_info->seal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	if (tcon->snapshot_time != volume_info->snapshot_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	if (tcon->handle_timeout != volume_info->handle_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	if (tcon->no_lease != volume_info->no_lease)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	if (tcon->nodelete != volume_info->nodelete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) static struct cifs_tcon *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	struct list_head *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	list_for_each(tmp, &ses->tcon_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 		tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 		if (tcon->dfs_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 		if (!match_tcon(tcon, volume_info))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 		++tcon->tc_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		return tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) cifs_put_tcon(struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	 * IPC tcon share the lifetime of their session and are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 	 * destroyed in the session put function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	if (tcon == NULL || tcon->ipc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	cifs_dbg(FYI, "%s: tc_count=%d\n", __func__, tcon->tc_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	if (--tcon->tc_count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 	list_del_init(&tcon->tcon_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	if (ses->server->ops->tree_disconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 		ses->server->ops->tree_disconnect(xid, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 	_free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	cifs_fscache_release_super_cookie(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	tconInfoFree(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)  * cifs_get_tcon - get a tcon matching @volume_info data from @ses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)  * - tcon refcount is the number of mount points using the tcon.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)  * - ses refcount is the number of tcon using the session.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)  * 1. This function assumes it is being called from cifs_mount() where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)  *    we already got a session reference (ses refcount +1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)  * 2. Since we're in the context of adding a mount point, the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229)  *    result should be either:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231)  * a) a new tcon already allocated with refcount=1 (1 mount point) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)  *    its session refcount incremented (1 new tcon). This +1 was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)  *    already done in (1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)  * b) an existing tcon with refcount+1 (add a mount point to it) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236)  *    identical ses refcount (no new tcon). Because of (1) we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237)  *    decrement the ses refcount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) static struct cifs_tcon *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	int rc, xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	tcon = cifs_find_tcon(ses, volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	if (tcon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 		 * tcon has refcount already incremented but we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 		 * decrement extra ses reference gotten by caller (case b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		cifs_dbg(FYI, "Found match on UNC path\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 		cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 		return tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	if (!ses->server->ops->tree_connect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 		rc = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	tcon = tconInfoAlloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	if (tcon == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 		goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	if (volume_info->snapshot_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 			     "Use SMB2 or later for snapshot mount option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 			tcon->snapshot_time = volume_info->snapshot_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	if (volume_info->handle_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 			     "Use SMB2.1 or later for handle timeout option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 			tcon->handle_timeout = volume_info->handle_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	tcon->ses = ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	if (volume_info->password) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 		if (!tcon->password) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 			rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 	if (volume_info->seal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 				 "SMB3 or later required for encryption\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		} else if (tcon->ses->server->capabilities &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 					SMB2_GLOBAL_CAP_ENCRYPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 			tcon->seal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 			cifs_dbg(VFS, "Encryption is not supported on share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 	if (volume_info->linux_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		if (ses->server->posix_ext_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			tcon->posix_extensions = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 			pr_warn_once("SMB3.11 POSIX Extensions are experimental\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 			cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	 * BB Do we need to wrap session_mutex around this TCon call and Unix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	 * SetFS as we do on SessSetup and reconnect?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 					    volume_info->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	cifs_dbg(FYI, "Tcon rc = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 		goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 	tcon->use_persistent = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	/* check if SMB2 or later, CIFS does not support persistent handles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	if (volume_info->persistent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 			     "SMB3 or later required for persistent handles\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		} else if (ses->server->capabilities &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 			   SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 			tcon->use_persistent = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 		else /* persistent handles requested but not supported */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 				"Persistent handles not supported on share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	} else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	     && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	     && (volume_info->nopersistent == false)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		cifs_dbg(FYI, "enabling persistent handles\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 		tcon->use_persistent = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	} else if (volume_info->resilient) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 			     "SMB2.1 or later required for resilient handles\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 		tcon->use_resilient = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	/* If the user really knows what they are doing they can override */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		if (volume_info->cache_ro)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 			cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		else if (volume_info->cache_rw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 			cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	if (volume_info->no_lease) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		if (ses->server->vals->protocol_id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 			cifs_dbg(VFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 				"SMB2 or later required for nolease option\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 			goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 			tcon->no_lease = volume_info->no_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	 * We can have only one retry value for a connection to a share so for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 	 * resources mounted more than once to the same server share the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	 * value passed in for the retry flag is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	tcon->retry = volume_info->retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	tcon->nocase = volume_info->nocase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 	if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 		tcon->nohandlecache = volume_info->nohandlecache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 		tcon->nohandlecache = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	tcon->nodelete = volume_info->nodelete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	tcon->local_lease = volume_info->local_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	INIT_LIST_HEAD(&tcon->pending_opens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	list_add(&tcon->tcon_list, &ses->tcon_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	cifs_fscache_get_super_cookie(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	return tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) out_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 	tconInfoFree(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) cifs_put_tlink(struct tcon_link *tlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	if (!tlink || IS_ERR(tlink))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	if (!atomic_dec_and_test(&tlink->tl_count) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	    test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 		tlink->tl_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	if (!IS_ERR(tlink_tcon(tlink)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 		cifs_put_tcon(tlink_tcon(tlink));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	kfree(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	struct cifs_sb_info *old = CIFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	struct cifs_sb_info *new = mnt_data->cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 	if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	if (old->mnt_cifs_serverino_autodisabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		newflags &= ~CIFS_MOUNT_SERVER_INUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	if (oldflags != newflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	 * We want to share sb only if we don't specify an r/wsize or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	 * specified r/wsize is greater than or equal to existing one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 	if (new->wsize && new->wsize < old->wsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	if (new->rsize && new->rsize < old->rsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 	if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 	if (old->mnt_file_mode != new->mnt_file_mode ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 	    old->mnt_dir_mode != new->mnt_dir_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	if (strcmp(old->local_nls->charset, new->local_nls->charset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	if (old->actimeo != new->actimeo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) match_prepath(struct super_block *sb, struct cifs_mnt_data *mnt_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	struct cifs_sb_info *old = CIFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	struct cifs_sb_info *new = mnt_data->cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 	bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 		old->prepath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 	bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 		new->prepath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	if (old_set && new_set && !strcmp(new->prepath, old->prepath))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	else if (!old_set && !new_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) cifs_match_super(struct super_block *sb, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	struct smb_vol *volume_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	struct cifs_sb_info *cifs_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	struct TCP_Server_Info *tcp_srv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	cifs_sb = CIFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	if (tlink == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		/* can not match superblock if tlink were ever null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	tcon = tlink_tcon(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	ses = tcon->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	tcp_srv = ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	volume_info = mnt_data->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	if (!match_server(tcp_srv, volume_info) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	    !match_session(ses, volume_info) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	    !match_tcon(tcon, volume_info) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	    !match_prepath(sb, mnt_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	rc = compare_mount_options(sb, mnt_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) #ifdef CONFIG_DEBUG_LOCK_ALLOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) static struct lock_class_key cifs_key[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) static struct lock_class_key cifs_slock_key[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) cifs_reclassify_socket4(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	BUG_ON(!sock_allow_reclassification(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 		&cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) cifs_reclassify_socket6(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	struct sock *sk = sock->sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	BUG_ON(!sock_allow_reclassification(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 	sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 		&cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) cifs_reclassify_socket4(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) cifs_reclassify_socket6(struct socket *sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) /* See RFC1001 section 14 on representation of Netbios names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) static void rfc1002mangle(char *target, char *source, unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 	unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 	for (i = 0, j = 0; i < (length); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 		/* mask a nibble at a time and encode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 		target[j] = 'A' + (0x0F & (source[i] >> 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 		target[j+1] = 'A' + (0x0F & source[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 		j += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) bind_socket(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	if (server->srcaddr.ss_family != AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 		/* Bind to the specified local IP address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 		struct socket *socket = server->ssocket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 		rc = socket->ops->bind(socket,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 				       (struct sockaddr *) &server->srcaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 				       sizeof(server->srcaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 		if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 			struct sockaddr_in *saddr4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 			struct sockaddr_in6 *saddr6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 			saddr4 = (struct sockaddr_in *)&server->srcaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 			saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 			if (saddr6->sin6_family == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 				cifs_server_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 					 &saddr6->sin6_addr, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 				cifs_server_dbg(VFS, "Failed to bind to: %pI4, error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 					 &saddr4->sin_addr.s_addr, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) ip_rfc1001_connect(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	 * some servers require RFC1001 sessinit before sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	 * negprot - BB check reconnection in case where second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	 * sessinit is sent but no second negprot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	struct rfc1002_session_packet *ses_init_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 			       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	if (ses_init_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 		ses_init_buf->trailer.session_req.called_len = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 		if (server->server_RFC1001_name[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 			rfc1002mangle(ses_init_buf->trailer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 				      session_req.called_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 				      server->server_RFC1001_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 				      RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 			rfc1002mangle(ses_init_buf->trailer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 				      session_req.called_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 				      DEFAULT_CIFS_CALLED_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 				      RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 		ses_init_buf->trailer.session_req.calling_len = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 		 * calling name ends in null (byte 16) from old smb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 		 * convention.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		if (server->workstation_RFC1001_name[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 			rfc1002mangle(ses_init_buf->trailer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 				      session_req.calling_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 				      server->workstation_RFC1001_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 				      RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 			rfc1002mangle(ses_init_buf->trailer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 				      session_req.calling_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 				      "LINUX_CIFS_CLNT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 				      RFC1001_NAME_LEN_WITH_NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		ses_init_buf->trailer.session_req.scope1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 		ses_init_buf->trailer.session_req.scope2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 		smb_buf = (struct smb_hdr *)ses_init_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		/* sizeof RFC1002_SESSION_REQUEST with no scope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 		smb_buf->smb_buf_length = cpu_to_be32(0x81000044);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		rc = smb_send(server, smb_buf, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 		kfree(ses_init_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 		 * RFC1001 layer in at least one server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 		 * requires very short break before negprot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 		 * presumably because not expecting negprot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 		 * to follow so fast.  This is a simple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		 * solution that works without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		 * complicating the code and causes no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 		 * significant slowing down on mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 		 * for everyone else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 		usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	 * else the negprot may still work without this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	 * even though malloc failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) generic_ip_connect(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 	__be16 sport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 	int slen, sfamily;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	struct socket *socket = server->ssocket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 	struct sockaddr *saddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	saddr = (struct sockaddr *) &server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	if (server->dstaddr.ss_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 		struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 		sport = ipv6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 		slen = sizeof(struct sockaddr_in6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 		sfamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 		cifs_dbg(FYI, "%s: connecting to [%pI6]:%d\n", __func__, &ipv6->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 				ntohs(sport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 		sport = ipv4->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 		slen = sizeof(struct sockaddr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 		sfamily = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 		cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 				ntohs(sport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	if (socket == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 		rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 				   IPPROTO_TCP, &socket, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 		if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 			cifs_server_dbg(VFS, "Error %d creating socket\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 			server->ssocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 		/* BB other socket options to set KEEPALIVE, NODELAY? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		cifs_dbg(FYI, "Socket created\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 		server->ssocket = socket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 		socket->sk->sk_allocation = GFP_NOFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 		if (sfamily == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 			cifs_reclassify_socket6(socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 			cifs_reclassify_socket4(socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	rc = bind_socket(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 	 * Eventually check for other socket options to change from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	 * the default. sock_setsockopt not used because it expects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 	 * user space buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	socket->sk->sk_rcvtimeo = 7 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	socket->sk->sk_sndtimeo = 5 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	/* make the bufsizes depend on wsize/rsize and max requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 	if (server->noautotune) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 		if (socket->sk->sk_sndbuf < (200 * 1024))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 			socket->sk->sk_sndbuf = 200 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 		if (socket->sk->sk_rcvbuf < (140 * 1024))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 			socket->sk->sk_rcvbuf = 140 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	if (server->tcp_nodelay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 		tcp_sock_set_nodelay(socket->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	cifs_dbg(FYI, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 		 socket->sk->sk_sndbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 		 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 	rc = socket->ops->connect(socket, saddr, slen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 				  server->noblockcnt ? O_NONBLOCK : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 	 * When mounting SMB root file systems, we do not want to block in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 	 * connect. Otherwise bail out and then let cifs_reconnect() perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 	 * reconnect failover - if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	if (server->noblockcnt && rc == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		cifs_dbg(FYI, "Error %d connecting to server\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 		sock_release(socket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 		server->ssocket = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	if (sport == htons(RFC1001_PORT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 		rc = ip_rfc1001_connect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) ip_connect(struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	__be16 *sport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 	if (server->dstaddr.ss_family == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 		sport = &addr6->sin6_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		sport = &addr->sin_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	if (*sport == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 		int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 		/* try with 445 port at first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 		*sport = htons(CIFS_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 		rc = generic_ip_connect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 		if (rc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 		/* if it failed, try with 139 port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 		*sport = htons(RFC1001_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	return generic_ip_connect(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			  struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 	/* if we are reconnecting then should we check to see if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 	 * any requested capabilities changed locally e.g. via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 	 * remount but we can not do much about it here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 	 * if they have (even if we could detect it by the following)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	 * Perhaps we could add a backpointer to array of sb from tcon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 	 * or if we change to make all sb to same share the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	 * sb as NFS - then we only have one backpointer to sb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 	 * What if we wanted to mount the server share twice once with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	 * and once without posixacls or posix paths? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 	__u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	if (vol_info && vol_info->no_linux_ext) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 		tcon->fsUnixInfo.Capability = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 		tcon->unix_ext = 0; /* Unix Extensions disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 		cifs_dbg(FYI, "Linux protocol extensions disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 	} else if (vol_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 		tcon->unix_ext = 1; /* Unix Extensions supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	if (tcon->unix_ext == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 		cifs_dbg(FYI, "Unix extensions disabled so not set on reconnect\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 	if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 		__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 		cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 		/* check for reconnect case in which we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 		   want to change the mount behavior if we can avoid it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		if (vol_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 			/* turn off POSIX ACL and PATHNAMES if not set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 			   originally at mount time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 			if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 				cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 			if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 				if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 					cifs_dbg(VFS, "POSIXPATH support change\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 				cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 			} else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 				cifs_dbg(VFS, "possible reconnect error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 				cifs_dbg(VFS, "server disabled POSIX path support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 			cifs_dbg(VFS, "per-share encryption not supported yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		cap &= CIFS_UNIX_CAP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		if (vol_info && vol_info->no_psx_acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 			cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 			cifs_dbg(FYI, "negotiated posix acl support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 			if (cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 				cifs_sb->mnt_cifs_flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 					CIFS_MOUNT_POSIXACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 		if (vol_info && vol_info->posix_paths == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 			cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 		else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 			cifs_dbg(FYI, "negotiate posix pathnames\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 			if (cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 				cifs_sb->mnt_cifs_flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 					CIFS_MOUNT_POSIX_PATHS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 		cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) #ifdef CONFIG_CIFS_DEBUG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 		if (cap & CIFS_UNIX_FCNTL_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 			cifs_dbg(FYI, "FCNTL cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 		if (cap & CIFS_UNIX_EXTATTR_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 			cifs_dbg(FYI, "EXTATTR cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 		if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 			cifs_dbg(FYI, "POSIX path cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 		if (cap & CIFS_UNIX_XATTR_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 			cifs_dbg(FYI, "XATTR cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 		if (cap & CIFS_UNIX_POSIX_ACL_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 			cifs_dbg(FYI, "POSIX ACL cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 		if (cap & CIFS_UNIX_LARGE_READ_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 			cifs_dbg(FYI, "very large read cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 		if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 			cifs_dbg(FYI, "very large write cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 			cifs_dbg(FYI, "transport encryption cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 			cifs_dbg(FYI, "mandatory transport encryption cap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) #endif /* CIFS_DEBUG2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 		if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 			if (vol_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 				cifs_dbg(FYI, "resetting capabilities failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 				cifs_dbg(VFS, "Negotiating Unix capabilities with the server failed. Consider mounting with the Unix Extensions disabled if problems are found by specifying the nounix mount option.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 			struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 	spin_lock_init(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	cifs_sb->tlink_tree = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 	cifs_sb->bsize = pvolume_info->bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	 * Temporarily set r/wsize for matching superblock. If we end up using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	 * new sb then client will later negotiate it downward if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 	cifs_sb->rsize = pvolume_info->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 	cifs_sb->wsize = pvolume_info->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 	cifs_sb->mnt_uid = pvolume_info->linux_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 	cifs_sb->mnt_gid = pvolume_info->linux_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 	cifs_sb->mnt_file_mode = pvolume_info->file_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 	cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 		 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 	cifs_sb->actimeo = pvolume_info->actimeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 	cifs_sb->local_nls = pvolume_info->local_nls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 	if (pvolume_info->nodfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	if (pvolume_info->noperm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	if (pvolume_info->setuids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 	if (pvolume_info->setuidfromacl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	if (pvolume_info->server_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	if (pvolume_info->remap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 	if (pvolume_info->sfu_remap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 	if (pvolume_info->no_xattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 	if (pvolume_info->sfu_emul)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	if (pvolume_info->nobrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	if (pvolume_info->nohandlecache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	if (pvolume_info->nostrictsync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	if (pvolume_info->mand_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 	if (pvolume_info->rwpidforward)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 	if (pvolume_info->mode_ace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	if (pvolume_info->cifs_acl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 	if (pvolume_info->backupuid_specified) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 		cifs_sb->mnt_backupuid = pvolume_info->backupuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 	if (pvolume_info->backupgid_specified) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 		cifs_sb->mnt_backupgid = pvolume_info->backupgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	if (pvolume_info->override_uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	if (pvolume_info->override_gid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 	if (pvolume_info->dynperm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	if (pvolume_info->fsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	if (pvolume_info->multiuser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 					    CIFS_MOUNT_NO_PERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	if (pvolume_info->strict_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 	if (pvolume_info->direct_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		cifs_dbg(FYI, "mounting share using direct i/o\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 	if (pvolume_info->cache_ro) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 	} else if (pvolume_info->cache_rw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 					    CIFS_MOUNT_RW_CACHE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	if (pvolume_info->mfsymlinks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		if (pvolume_info->sfu_emul) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 			 * Our SFU ("Services for Unix" emulation does not allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 			 * creating symlinks but does allow reading existing SFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 			 * symlinks (it does allow both creating and reading SFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 			 * style mknod and FIFOs though). When "mfsymlinks" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 			 * "sfu" are both enabled at the same time, it allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 			 * reading both types of symlinks, but will only create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 			 * them with mfsymlinks format. This allows better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 			 * Apple compatibility (probably better for Samba too)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 			 * while still recognizing old Windows style symlinks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 			cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 		cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 	if (pvolume_info->prepath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 		if (cifs_sb->prepath == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) cifs_cleanup_volume_info_contents(struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 	kfree(volume_info->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	kfree_sensitive(volume_info->password);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 	kfree(volume_info->UNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 	kfree(volume_info->domainname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 	kfree(volume_info->iocharset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	kfree(volume_info->prepath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) cifs_cleanup_volume_info(struct smb_vol *volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 	if (!volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 	cifs_cleanup_volume_info_contents(volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 	kfree(volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) /* Release all succeed connections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) static inline void mount_put_conns(struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 				   unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 				   struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 				   struct cifs_ses *ses, struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 	if (tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 		cifs_put_tcon(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 	else if (ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 		cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 	else if (server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 		cifs_put_tcp_session(server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) /* Get connections for tcp, ses and tcon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 			   unsigned int *xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 			   struct TCP_Server_Info **nserver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 			   struct cifs_ses **nses, struct cifs_tcon **ntcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	struct TCP_Server_Info *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 	*nserver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 	*nses = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 	*ntcon = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 	*xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 	/* get a reference to a tcp session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 	server = cifs_get_tcp_session(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	if (IS_ERR(server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 		rc = PTR_ERR(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	*nserver = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 	/* get a reference to a SMB session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 	ses = cifs_get_smb_ses(server, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	if (IS_ERR(ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 		rc = PTR_ERR(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 	*nses = ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 	if ((vol->persistent == true) && (!(ses->server->capabilities &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 					    SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 		cifs_server_dbg(VFS, "persistent handles not supported by server\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	/* search for existing tcon to this server share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 	tcon = cifs_get_tcon(ses, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	if (IS_ERR(tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 		rc = PTR_ERR(tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	*ntcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	/* if new SMB3.11 POSIX extensions are supported do not remap / and \ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 	if (tcon->posix_extensions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 	/* tell server which Unix caps we support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 	if (cap_unix(tcon->ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 		 * reset of caps checks mount to see if unix extensions disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 		 * for just this mount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 		reset_cifs_unix_caps(*xid, tcon, cifs_sb, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 		if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 		    (le64_to_cpu(tcon->fsUnixInfo.Capability) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 		     CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 			return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 		tcon->unix_ext = 0; /* server does not support them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	/* do not care if a following call succeed - informational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	if (!tcon->pipe && server->ops->qfs_tcon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 		server->ops->qfs_tcon(*xid, tcon, cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 			if (tcon->fsDevInfo.DeviceCharacteristics &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 			    cpu_to_le32(FILE_READ_ONLY_DEVICE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 				cifs_dbg(VFS, "mounted to read only share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 			else if ((cifs_sb->mnt_cifs_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 				  CIFS_MOUNT_RW_CACHE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 				cifs_dbg(VFS, "read only mount of RW share\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 			/* no need to log a RW mount of a typical RW share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 	cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 			     struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	/* hang the tcon off of the superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	tlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	if (tlink == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	tlink->tl_uid = ses->linux_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	tlink->tl_tcon = tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	tlink->tl_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 	set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	cifs_sb->master_tlink = tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 				TLINK_IDLE_EXPIRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180)  * cifs_build_path_to_root returns full path to root when we do not have an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181)  * exiting connection (tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) static char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) build_unc_path_to_root(const struct smb_vol *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 		       const struct cifs_sb_info *cifs_sb, bool useppath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 	char *full_path, *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	unsigned int pplen = useppath && vol->prepath ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 		strlen(vol->prepath) + 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	if (unc_len > MAX_TREE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 	if (full_path == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 	memcpy(full_path, vol->UNC, unc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	pos = full_path + unc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 	if (pplen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 		*pos = CIFS_DIR_SEP(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 		memcpy(pos + 1, vol->prepath, pplen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 		pos += pplen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	*pos = '\0'; /* add trailing null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	cifs_dbg(FYI, "%s: full_path=%s\n", __func__, full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 	return full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215)  * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218)  * If a referral is found, cifs_sb->mountdata will be (re-)allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219)  * to a string containing updated options for the submount.  Otherwise it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220)  * will be left untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222)  * Returns the rc from get_dfs_path to the caller, which can be used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223)  * determine whether there were referrals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 		    struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 		    char *ref_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 	struct dfs_info3_param referral = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 	char *full_path = NULL, *mdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 		return -EREMOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	full_path = build_unc_path_to_root(volume_info, cifs_sb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 	if (IS_ERR(full_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 		return PTR_ERR(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 			    ref_path, &referral, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 		char *fake_devname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 		mdata = cifs_compose_mount_options(cifs_sb->mountdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 						   full_path + 1, &referral,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 						   &fake_devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 		free_dfs_info_param(&referral);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 		if (IS_ERR(mdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 			rc = PTR_ERR(mdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 			mdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 			cifs_cleanup_volume_info_contents(volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 			rc = cifs_setup_volume_info(volume_info, mdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 						    fake_devname, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 		kfree(fake_devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 		kfree(cifs_sb->mountdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 		cifs_sb->mountdata = mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	kfree(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) static inline int get_next_dfs_tgt(const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 				   struct dfs_cache_tgt_list *tgt_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 				   struct dfs_cache_tgt_iterator **tgt_it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 	if (!*tgt_it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		*tgt_it = dfs_cache_get_tgt_iterator(tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 		*tgt_it = dfs_cache_get_next_tgt(tgt_list, *tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	return !*tgt_it ? -EHOSTDOWN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 			   struct smb_vol *fake_vol, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 	const char *tgt = dfs_cache_get_tgt_name(tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	int len = strlen(tgt) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 	char *new_unc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 	new_unc = kmalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	if (!new_unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 	scnprintf(new_unc, len, "\\%s", tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 	kfree(vol->UNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 	vol->UNC = new_unc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	if (fake_vol->prepath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 		kfree(vol->prepath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 		vol->prepath = fake_vol->prepath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 		fake_vol->prepath = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	memcpy(&vol->dstaddr, &fake_vol->dstaddr, sizeof(vol->dstaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) static int setup_dfs_tgt_conn(const char *path, const char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 			      const struct dfs_cache_tgt_iterator *tgt_it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 			      struct cifs_sb_info *cifs_sb, struct smb_vol *vol, unsigned int *xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 			      struct TCP_Server_Info **server, struct cifs_ses **ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 			      struct cifs_tcon **tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 	struct dfs_info3_param ref = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 	char *mdata = NULL, *fake_devname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 	struct smb_vol fake_vol = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 	rc = dfs_cache_get_tgt_referral(path, tgt_it, &ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 	mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref, &fake_devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 	free_dfs_info_param(&ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 	if (IS_ERR(mdata)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 		rc = PTR_ERR(mdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 		mdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 		cifs_dbg(FYI, "%s: fake_devname: %s\n", __func__, fake_devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 		rc = cifs_setup_volume_info(&fake_vol, mdata, fake_devname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 					    false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 	kfree(mdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	kfree(fake_devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 		 * We use a 'fake_vol' here because we need pass it down to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 		 * mount_{get,put} functions to test connection against new DFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 		 * targets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		mount_put_conns(cifs_sb, *xid, *server, *ses, *tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 		rc = mount_get_conns(&fake_vol, cifs_sb, xid, server, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 				     tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 		if (!rc || (*server && *ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 			 * We were able to connect to new target server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 			 * Update current volume info with new target server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 			rc = update_vol_info(tgt_it, &fake_vol, vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	cifs_cleanup_volume_info_contents(&fake_vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) static int do_dfs_failover(const char *path, const char *full_path, struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 			   struct smb_vol *vol, struct cifs_ses *root_ses, unsigned int *xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 			   struct TCP_Server_Info **server, struct cifs_ses **ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 			   struct cifs_tcon **tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	struct dfs_cache_tgt_list tgt_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 	struct dfs_cache_tgt_iterator *tgt_it = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	rc = dfs_cache_noreq_find(path, NULL, &tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 		/* Get next DFS target server - if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 		rc = get_next_dfs_tgt(path, &tgt_list, &tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 		/* Connect to next DFS target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 		rc = setup_dfs_tgt_conn(path, full_path, tgt_it, cifs_sb, vol, xid, server, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 					tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 		if (!rc || (*server && *ses))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 		 * Update DFS target hint in DFS referral cache with the target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 		 * server we successfully reconnected to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 		rc = dfs_cache_update_tgthint(*xid, root_ses ? root_ses : *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 					      cifs_sb->local_nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 					      cifs_remap(cifs_sb), path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 					      tgt_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 	dfs_cache_free_tgts(&tgt_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 			const char *devname, bool is_smb3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	if (cifs_parse_mount_options(mount_data, devname, volume_info, is_smb3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 	if (volume_info->nullauth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 		cifs_dbg(FYI, "Anonymous login\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 		kfree(volume_info->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 		volume_info->username = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	} else if (volume_info->username) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 		/* BB fixme parse for domain name here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 		cifs_dbg(FYI, "Username: %s\n", volume_info->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 		cifs_dbg(VFS, "No username specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	/* In userspace mount helper we can get user name from alternate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	   locations such as env variables and files on disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	/* this is needed for ASCII cp to Unicode converts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	if (volume_info->iocharset == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 		/* load_nls_default cannot return null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 		volume_info->local_nls = load_nls_default();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 		volume_info->local_nls = load_nls(volume_info->iocharset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 		if (volume_info->local_nls == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 			cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 				 volume_info->iocharset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 			return -ELIBACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) struct smb_vol *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) cifs_get_volume_info(char *mount_data, const char *devname, bool is_smb3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	struct smb_vol *volume_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 	if (!volume_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	rc = cifs_setup_volume_info(volume_info, mount_data, devname, is_smb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 		cifs_cleanup_volume_info(volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 		volume_info = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	return volume_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 					unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 					struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 					struct cifs_sb_info *cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 					char *full_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 					int added_treename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	char sep, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	int skip = added_treename ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	sep = CIFS_DIR_SEP(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 	s = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 	while (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 		/* skip separators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		while (*s == sep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 			s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 		if (!*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 		/* next separator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 		while (*s && *s != sep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 			s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 		 * if the treename is added, we then have to skip the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 		 * part within the separators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 		if (skip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 			skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 		 * temporarily null-terminate the path at the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 		 * the current component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 		tmp = *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 		*s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 						     full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 		*s = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)  * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504)  * otherwise 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 			  const unsigned int xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 			  struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 			  struct cifs_tcon *tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	char *full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	if (!server->ops->is_path_accessible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	 * cifs_build_path_to_root works only when we have a valid tcon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	full_path = cifs_build_path_to_root(vol, cifs_sb, tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 					    tcon->Flags & SMB_SHARE_IS_IN_DFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	if (full_path == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 	cifs_dbg(FYI, "%s: full_path: %s\n", __func__, full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 	rc = server->ops->is_path_accessible(xid, tcon, cifs_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 					     full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 	if (rc != 0 && rc != -EREMOTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 		kfree(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 	if (rc != -EREMOTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 		rc = cifs_are_all_path_components_accessible(server, xid, tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 			cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 		if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 			cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	kfree(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) static void set_root_ses(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 			 struct cifs_ses **root_ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 	if (ses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 		spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 		ses->ses_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 		if (ses->tcon_ipc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 			ses->tcon_ipc->remap = cifs_remap(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 	*root_ses = ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) static void put_root_ses(struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 	if (ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 		cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) /* Check if a path component is remote and then update @dfs_path accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 			     const unsigned int xid, struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 			     struct cifs_tcon *tcon, char **dfs_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 	char *path, *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 	char sep = CIFS_DIR_SEP(cifs_sb), tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 	char *npath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 	int added_treename = tcon->Flags & SMB_SHARE_IS_IN_DFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 	int skip = added_treename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 	path = cifs_build_path_to_root(vol, cifs_sb, tcon, added_treename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	if (!path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 	 * Walk through the path components in @path and check if they're accessible. In case any of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 	 * the components is -EREMOTE, then update @dfs_path with the next DFS referral request path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	 * (NOT including the remaining components).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 	s = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 		/* skip separators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 		while (*s && *s == sep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 			s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 		if (!*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 		/* next separator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 		while (*s && *s != sep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 			s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 		 * if the treename is added, we then have to skip the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 		 * part within the separators
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 		if (skip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 			skip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 		tmp = *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 		*s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 		rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 		if (rc && rc == -EREMOTE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 			struct smb_vol v = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 			/* if @path contains a tree name, skip it in the prefix path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 			if (added_treename) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 				rc = cifs_parse_devname(path, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 				if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) 				rc = -EREMOTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 				npath = build_unc_path_to_root(&v, cifs_sb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 				cifs_cleanup_volume_info_contents(&v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) 				v.UNC = vol->UNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 				v.prepath = path + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 				npath = build_unc_path_to_root(&v, cifs_sb, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 			if (IS_ERR(npath)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 				rc = PTR_ERR(npath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 			kfree(*dfs_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 			*dfs_path = npath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 		*s = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	} while (rc == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	kfree(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 	struct TCP_Server_Info *server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 	struct cifs_ses *ses = NULL, *root_ses = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 	struct cifs_tcon *tcon = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	char *ref_path = NULL, *full_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	char *oldmnt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	char *mntdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 	rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 	 * Unconditionally try to get an DFS referral (even cached) to determine whether it is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	 * DFS mount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 	 * Skip prefix path to provide support for DFS referrals from w2k8 servers which don't seem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) 	 * to respond with PATH_NOT_COVERED to requests that include the prefix.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 	if (dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), vol->UNC + 1, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) 			   NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 		/* No DFS referral was returned.  Looks like a regular share. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 		/* Check if it is fully accessible and then mount it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 		rc = is_path_remote(cifs_sb, vol, xid, server, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 		if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 		if (rc != -EREMOTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 	/* Save mount options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 	mntdata = kstrndup(cifs_sb->mountdata, strlen(cifs_sb->mountdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 	if (!mntdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 	/* Get path of DFS root */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 	ref_path = build_unc_path_to_root(vol, cifs_sb, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 	if (IS_ERR(ref_path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 		rc = PTR_ERR(ref_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 		ref_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 	set_root_ses(cifs_sb, ses, &root_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) 		/* Save full path of last DFS path we used to resolve final target server */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) 		kfree(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) 		full_path = build_unc_path_to_root(vol, cifs_sb, !!count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 		if (IS_ERR(full_path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 			rc = PTR_ERR(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 			full_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 		/* Chase referral */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 		oldmnt = cifs_sb->mountdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 		rc = expand_dfs_referral(xid, root_ses, vol, cifs_sb, ref_path + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 		/* Connect to new DFS target only if we were redirected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 		if (oldmnt != cifs_sb->mountdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 			mount_put_conns(cifs_sb, xid, server, ses, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 			rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 		if (rc && !server && !ses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) 			/* Failed to connect. Try to connect to other targets in the referral. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 			rc = do_dfs_failover(ref_path + 1, full_path, cifs_sb, vol, root_ses, &xid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 					     &server, &ses, &tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 		if (rc == -EACCES || rc == -EOPNOTSUPP || !server || !ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 		if (!tcon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 		/* Make sure that requests go through new root servers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 		if (is_tcon_dfs(tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 			put_root_ses(root_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 			set_root_ses(cifs_sb, ses, &root_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 		/* Check for remaining path components and then continue chasing them (-EREMOTE) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) 		rc = check_dfs_prepath(cifs_sb, vol, xid, server, tcon, &ref_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 		/* Prevent recursion on broken link referrals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 		if (rc == -EREMOTE && ++count > MAX_NESTED_LINKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 			rc = -ELOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 	} while (rc == -EREMOTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	put_root_ses(root_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 	root_ses = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 	kfree(ref_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 	ref_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 	 * Store DFS full path in both superblock and tree connect structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 	 * For DFS root mounts, the prefix path (cifs_sb->prepath) is preserved during reconnect so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 	 * only the root path is set in cifs_sb->origin_fullpath and tcon->dfs_path. And for DFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	 * links, the prefix path is included in both and may be changed during reconnect.  See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 	 * cifs_tree_connect().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 	cifs_sb->origin_fullpath = kstrndup(full_path, strlen(full_path), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	if (!cifs_sb->origin_fullpath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 	tcon->dfs_path = full_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 	full_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 	tcon->remap = cifs_remap(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 	/* Add original volume information for DFS cache to be used when refreshing referrals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 	rc = dfs_cache_add_vol(mntdata, vol, cifs_sb->origin_fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	 * After reconnecting to a different server, unique ids won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 	 * match anymore, so we disable serverino. This prevents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 	 * dentry revalidation to think the dentry are stale (ESTALE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 	cifs_autodisable_serverino(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 	 * Force the use of prefix path to support failover on DFS paths that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 	 * resolve to targets that have different prefix paths.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 	cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 	kfree(cifs_sb->prepath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 	cifs_sb->prepath = vol->prepath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 	vol->prepath = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 	cifs_try_adding_channels(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 	return mount_setup_tlink(cifs_sb, ses, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 	kfree(ref_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 	kfree(full_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 	kfree(mntdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 	kfree(cifs_sb->origin_fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 	put_root_ses(root_ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 	mount_put_conns(cifs_sb, xid, server, ses, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 	struct cifs_tcon *tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 	struct TCP_Server_Info *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 	rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 	if (tcon) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 		rc = is_path_remote(cifs_sb, vol, xid, server, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 		if (rc == -EREMOTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 			rc = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	free_xid(xid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 	return mount_setup_tlink(cifs_sb, ses, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 	mount_put_conns(cifs_sb, xid, server, ses, tcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816)  * Issue a TREE_CONNECT request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) 	 const char *tree, struct cifs_tcon *tcon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) 	 const struct nls_table *nls_codepage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 	struct smb_hdr *smb_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 	struct smb_hdr *smb_buffer_response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) 	TCONX_REQ *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	TCONX_RSP *pSMBr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 	unsigned char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	__u16 bytes_left, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 	if (ses == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 	smb_buffer = cifs_buf_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	if (smb_buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 	smb_buffer_response = smb_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 			NULL /*no tid */ , 4 /*wct */ );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 	smb_buffer->Mid = get_next_mid(ses->server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 	smb_buffer->Uid = ses->Suid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 	pSMB = (TCONX_REQ *) smb_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 	pSMBr = (TCONX_RSP *) smb_buffer_response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 	pSMB->AndXCommand = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 	bcc_ptr = &pSMB->Password[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 		*bcc_ptr = 0; /* password is null byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 		bcc_ptr++;              /* skip password */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 		/* already aligned so no need to do it below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 		   specified as required (when that support is added to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 		   the vfs in the future) as only NTLM or the much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 		   weaker LANMAN (which we do not send by default) is accepted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 		   by Samba (not sure whether other servers allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 		   NTLMv2 password here) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) #ifdef CONFIG_CIFS_WEAK_PW_HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 		if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 		    (ses->sectype == LANMAN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 			calc_lanman_hash(tcon->password, ses->server->cryptkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 					 ses->server->sec_mode &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 					    SECMODE_PW_ENCRYPT ? true : false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 					 bcc_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) #endif /* CIFS_WEAK_PW_HASH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 		rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 					bcc_ptr, nls_codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 			cifs_dbg(FYI, "%s Can't generate NTLM rsp. Error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 				 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 			cifs_buf_release(smb_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 			return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 		bcc_ptr += CIFS_AUTH_RESP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 		if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 			/* must align unicode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 			*bcc_ptr = 0; /* null byte password */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 			bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 	if (ses->server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 	if (ses->capabilities & CAP_STATUS32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 		smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 	if (ses->capabilities & CAP_DFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 		smb_buffer->Flags2 |= SMBFLG2_DFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 		smb_buffer->Flags2 |= SMBFLG2_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) 		length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 		    cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) 			6 /* max utf8 char length in bytes */ *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 			(/* server len*/ + 256 /* share len */), nls_codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 		bcc_ptr += 2 * length;	/* convert num 16 bit words to bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 		bcc_ptr += 2;	/* skip trailing null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 	} else {		/* ASCII */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 		strcpy(bcc_ptr, tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 		bcc_ptr += strlen(tree) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 	strcpy(bcc_ptr, "?????");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 	bcc_ptr += strlen("?????");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 	bcc_ptr += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 	count = bcc_ptr - &pSMB->Password[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 	be32_add_cpu(&pSMB->hdr.smb_buf_length, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 	pSMB->ByteCount = cpu_to_le16(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) 	rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 			 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 	/* above now done in SendReceive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) 	if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) 		bool is_unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) 		tcon->tidStatus = CifsGood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) 		tcon->need_reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 		tcon->tid = smb_buffer_response->Tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 		bcc_ptr = pByteArea(smb_buffer_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 		bytes_left = get_bcc(smb_buffer_response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 		length = strnlen(bcc_ptr, bytes_left - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 		if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 			is_unicode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 			is_unicode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 		/* skip service field (NB: this field is always ASCII) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) 		if (length == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) 			if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) 			    (bcc_ptr[2] == 'C')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) 				cifs_dbg(FYI, "IPC connection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) 				tcon->ipc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 				tcon->pipe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) 		} else if (length == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 			if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) 				/* the most common case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) 				cifs_dbg(FYI, "disk share connection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 		bcc_ptr += length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 		bytes_left -= (length + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 		strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 		/* mostly informational -- no need to fail on error here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 		kfree(tcon->nativeFileSystem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 		tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) 						      bytes_left, is_unicode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 						      nls_codepage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 		cifs_dbg(FYI, "nativeFileSystem=%s\n", tcon->nativeFileSystem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 		if ((smb_buffer_response->WordCount == 3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 			 (smb_buffer_response->WordCount == 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 			/* field is in same location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 			tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 			tcon->Flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 		cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) 	cifs_buf_release(smb_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) static void delayed_free(struct rcu_head *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 	struct cifs_sb_info *sbi = container_of(p, struct cifs_sb_info, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 	unload_nls(sbi->local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 	kfree(sbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) cifs_umount(struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) 	struct rb_root *root = &cifs_sb->tlink_tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) 	struct rb_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) 	cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 	spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 	while ((node = rb_first(root))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 		cifs_get_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 		rb_erase(node, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 		spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 		cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 		spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 	spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 	kfree(cifs_sb->mountdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) 	kfree(cifs_sb->prepath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 	dfs_cache_del_vol(cifs_sb->origin_fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 	kfree(cifs_sb->origin_fullpath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 	call_rcu(&cifs_sb->rcu, delayed_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 	struct TCP_Server_Info *server = cifs_ses_server(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 	if (!server->ops->need_neg || !server->ops->negotiate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) 		return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) 	/* only send once per connect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) 	if (!server->ops->need_neg(server))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) 	rc = server->ops->negotiate(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) 	if (rc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) 		spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) 		if (server->tcpStatus == CifsNeedNegotiate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) 			server->tcpStatus = CifsGood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 			rc = -EHOSTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 		spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 		   struct nls_table *nls_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) 	int rc = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 	struct TCP_Server_Info *server = cifs_ses_server(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 	if (!ses->binding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 		ses->capabilities = server->capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) 		if (linuxExtEnabled == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 			ses->capabilities &= (~server->vals->cap_unix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) 		if (ses->auth_key.response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 			cifs_dbg(FYI, "Free previous auth_key.response = %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 				 ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 			kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 			ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 			ses->auth_key.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 	cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 		 server->sec_mode, server->capabilities, server->timeAdj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 	if (server->ops->sess_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) 		rc = server->ops->sess_setup(xid, ses, nls_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) 		cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 	vol->sectype = ses->sectype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) 	/* krb5 is special, since we don't need username or pw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 	if (vol->sectype == Kerberos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) 	return cifs_set_cifscreds(vol, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) static struct cifs_tcon *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 	struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 	struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 	struct cifs_tcon *tcon = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 	struct smb_vol *vol_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 	vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) 	if (vol_info == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 	vol_info->local_nls = cifs_sb->local_nls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 	vol_info->linux_uid = fsuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 	vol_info->cred_uid = fsuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 	vol_info->UNC = master_tcon->treeName;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 	vol_info->retry = master_tcon->retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) 	vol_info->nocase = master_tcon->nocase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 	vol_info->nohandlecache = master_tcon->nohandlecache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) 	vol_info->local_lease = master_tcon->local_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) 	vol_info->no_lease = master_tcon->no_lease;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 	vol_info->resilient = master_tcon->use_resilient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 	vol_info->persistent = master_tcon->use_persistent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 	vol_info->handle_timeout = master_tcon->handle_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 	vol_info->no_linux_ext = !master_tcon->unix_ext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) 	vol_info->linux_ext = master_tcon->posix_extensions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 	vol_info->sectype = master_tcon->ses->sectype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) 	vol_info->sign = master_tcon->ses->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 	vol_info->seal = master_tcon->seal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) 	rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) 		tcon = ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) 	/* get a reference for the same TCP session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) 	spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) 	++master_tcon->ses->server->srv_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) 	spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) 	ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) 	if (IS_ERR(ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) 		tcon = (struct cifs_tcon *)ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) 		cifs_put_tcp_session(master_tcon->ses->server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 	tcon = cifs_get_tcon(ses, vol_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) 	if (IS_ERR(tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 		cifs_put_smb_ses(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) 	if (cap_unix(ses))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 		reset_cifs_unix_caps(0, tcon, NULL, vol_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) 	kfree(vol_info->username);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 	kfree_sensitive(vol_info->password);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) 	kfree(vol_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 	return tcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) struct cifs_tcon *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 	return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) /* find and return a tlink with given uid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) static struct tcon_link *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) tlink_rb_search(struct rb_root *root, kuid_t uid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) 	struct rb_node *node = root->rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) 	while (node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 		tlink = rb_entry(node, struct tcon_link, tl_rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) 		if (uid_gt(tlink->tl_uid, uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 			node = node->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) 		else if (uid_lt(tlink->tl_uid, uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) 			node = node->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) 			return tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) /* insert a tcon_link into the tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) 	struct rb_node **new = &(root->rb_node), *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) 	while (*new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) 		tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) 		parent = *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) 		if (uid_gt(tlink->tl_uid, new_tlink->tl_uid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) 			new = &((*new)->rb_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) 			new = &((*new)->rb_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) 	rb_link_node(&new_tlink->tl_rbnode, parent, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) 	rb_insert_color(&new_tlink->tl_rbnode, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200)  * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201)  * current task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203)  * If the superblock doesn't refer to a multiuser mount, then just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204)  * the master tcon for the mount.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206)  * First, search the rbtree for an existing tcon for this fsuid. If one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207)  * exists, then check to see if it's pending construction. If it is then wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208)  * for construction to complete. Once it's no longer pending, check to see if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209)  * it failed and either return an error or retry construction, depending on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210)  * the timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212)  * If one doesn't exist then insert a new tcon_link struct into the tree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213)  * try to construct a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) struct tcon_link *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) 	kuid_t fsuid = current_fsuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) 	struct tcon_link *tlink, *newtlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) 		return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) 	spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) 	tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) 	if (tlink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) 		cifs_get_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) 	spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) 	if (tlink == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) 		newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) 		if (newtlink == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) 			return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) 		newtlink->tl_uid = fsuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) 		newtlink->tl_tcon = ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) 		set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) 		set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) 		cifs_get_tlink(newtlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) 		spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) 		/* was one inserted after previous search? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) 		tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) 		if (tlink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) 			cifs_get_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) 			spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) 			kfree(newtlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) 			goto wait_for_construction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) 		tlink = newtlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) 		tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) 		spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) wait_for_construction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) 		ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) 				  TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) 			cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) 			return ERR_PTR(-ERESTARTSYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) 		/* if it's good, return it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) 		if (!IS_ERR(tlink->tl_tcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) 			return tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) 		/* return error if we tried this already recently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) 		if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) 			cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) 			return ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) 		if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) 			goto wait_for_construction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) 	tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) 	clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) 	wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) 	if (IS_ERR(tlink->tl_tcon)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) 		cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) 		return ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) 	return tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289)  * periodic workqueue job that scans tcon_tree for a superblock and closes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290)  * out tcons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) cifs_prune_tlinks(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) 	struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) 						    prune_tlinks.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) 	struct rb_root *root = &cifs_sb->tlink_tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) 	struct rb_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) 	struct rb_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) 	struct tcon_link *tlink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) 	 * Because we drop the spinlock in the loop in order to put the tlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) 	 * it's not guarded against removal of links from the tree. The only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) 	 * places that remove entries from the tree are this function and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) 	 * umounts. Because this function is non-reentrant and is canceled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) 	 * before umount can proceed, this is safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) 	spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) 	node = rb_first(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) 	while (node != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) 		tmp = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) 		node = rb_next(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) 		tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) 		if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) 		    atomic_read(&tlink->tl_count) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) 		    time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) 		cifs_get_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) 		clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) 		rb_erase(tmp, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) 		spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) 		cifs_put_tlink(tlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) 		spin_lock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) 	spin_unlock(&cifs_sb->tlink_tree_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) 	queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) 				TLINK_IDLE_EXPIRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) #ifdef CONFIG_CIFS_DFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) 	struct TCP_Server_Info *server = tcon->ses->server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) 	const struct smb_version_operations *ops = server->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) 	struct dfs_cache_tgt_list tl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) 	struct dfs_cache_tgt_iterator *it = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) 	char *tree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) 	const char *tcp_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) 	size_t tcp_host_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) 	const char *dfs_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) 	size_t dfs_host_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) 	char *share = NULL, *prefix = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) 	struct dfs_info3_param ref = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) 	bool isroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) 	tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) 	if (!tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) 	/* If it is not dfs or there was no cached dfs referral, then reconnect to same share */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) 	if (!tcon->dfs_path || dfs_cache_noreq_find(tcon->dfs_path + 1, &ref, &tl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) 		if (tcon->ipc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) 			scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) 			rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) 			rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) 	isroot = ref.server_type == DFS_TYPE_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) 	free_dfs_info_param(&ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) 	extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) 	for (it = dfs_cache_get_tgt_iterator(&tl); it; it = dfs_cache_get_next_tgt(&tl, it)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) 		bool target_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) 		kfree(share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) 		kfree(prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) 		share = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) 		prefix = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) 		rc = dfs_cache_get_tgt_share(tcon->dfs_path + 1, it, &share, &prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) 			cifs_dbg(VFS, "%s: failed to parse target share %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) 				 __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) 		extract_unc_hostname(share, &dfs_host, &dfs_host_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) 		if (dfs_host_len != tcp_host_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) 		    || strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) 			cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n", __func__, (int)dfs_host_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) 				 dfs_host, (int)tcp_host_len, tcp_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) 			rc = match_target_ip(server, dfs_host, dfs_host_len, &target_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) 				cifs_dbg(VFS, "%s: failed to match target ip: %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) 			if (!target_match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) 				cifs_dbg(FYI, "%s: skipping target\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) 		if (tcon->ipc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) 			scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) 			rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) 			scnprintf(tree, MAX_TREE_SIZE, "\\%s", share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) 			rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) 			/* Only handle prefix paths of DFS link targets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) 			if (!rc && !isroot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) 				rc = update_super_prepath(tcon, prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) 		if (rc == -EREMOTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) 	kfree(share);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) 	kfree(prefix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) 		if (it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) 			rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1, it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) 			rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) 	dfs_cache_free_tgts(&tl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) 	kfree(tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) 	const struct smb_version_operations *ops = tcon->ses->server->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) 	return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) #endif