^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