From ebcd6de98754d9b6a5f89d7835864b1c365d432f Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 8 Dec 2020 21:13:31 -0600 Subject: SMB3: avoid confusing warning message on mount to Azure Mounts to Azure cause an unneeded warning message in dmesg "CIFS: VFS: parse_server_interfaces: incomplete interface info" Azure rounds up the size (by 8 additional bytes, to a 16 byte boundary) of the structure returned on the query of the server interfaces at mount time. This is permissible even though different than other servers so do not log a warning if query network interfaces response is only rounded up by 8 bytes or fewer. CC: Stable Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smb2ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/cifs/smb2ops.c') diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 3d914d7d0d11..22f1d8dc12b0 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -477,7 +477,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, goto out; } - if (bytes_left || p->Next) + /* Azure rounds the buffer size up 8, to a 16 byte boundary */ + if ((bytes_left > 8) || p->Next) cifs_dbg(VFS, "%s: incomplete interface info\n", __func__); -- cgit v1.2.3 From 3fa1c6d1b8f5c3d9be9e8047ad894ab3de67dc6e Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 9 Dec 2020 23:07:12 -0600 Subject: cifs: rename smb_vol as smb3_fs_context and move it to fs_context.h Harmonize and change all such variables to 'ctx', where possible. No changes to actual logic. Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 25 +- fs/cifs/cifsglob.h | 99 +----- fs/cifs/cifsproto.h | 24 +- fs/cifs/connect.c | 960 +++++++++++++++++++++++++-------------------------- fs/cifs/dfs_cache.c | 83 ++--- fs/cifs/dfs_cache.h | 2 +- fs/cifs/dir.c | 7 +- fs/cifs/fs_context.c | 102 +++--- fs/cifs/fs_context.h | 105 +++++- fs/cifs/sess.c | 51 +-- fs/cifs/smb1ops.c | 11 +- fs/cifs/smb2ops.c | 17 +- 12 files changed, 750 insertions(+), 736 deletions(-) (limited to 'fs/cifs/smb2ops.c') diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 472cb7777e3e..9fb85fcff6ae 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -55,6 +55,7 @@ #ifdef CONFIG_CIFS_DFS_UPCALL #include "dfs_cache.h" #endif +#include "fs_context.h" /* * DOS dates from 1980/1/1 through 2107/12/31 @@ -720,7 +721,7 @@ static const struct super_operations cifs_super_ops = { * Return dentry with refcount + 1 on success and NULL otherwise. */ static struct dentry * -cifs_get_root(struct smb_vol *vol, struct super_block *sb) +cifs_get_root(struct smb3_fs_context *ctx, struct super_block *sb) { struct dentry *dentry; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); @@ -731,7 +732,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) return dget(sb->s_root); - full_path = cifs_build_path_to_root(vol, cifs_sb, + full_path = cifs_build_path_to_root(ctx, cifs_sb, cifs_sb_master_tcon(cifs_sb), 0); if (full_path == NULL) return ERR_PTR(-ENOMEM); @@ -784,7 +785,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, int rc; struct super_block *sb; struct cifs_sb_info *cifs_sb; - struct smb_vol *volume_info; + struct smb3_fs_context *ctx; struct cifs_mnt_data mnt_data; struct dentry *root; @@ -797,9 +798,9 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, else cifs_info("Attempting to mount %s\n", dev_name); - volume_info = cifs_get_volume_info((char *)data, dev_name, is_smb3); - if (IS_ERR(volume_info)) - return ERR_CAST(volume_info); + ctx = cifs_get_volume_info((char *)data, dev_name, is_smb3); + if (IS_ERR(ctx)) + return ERR_CAST(ctx); cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); if (cifs_sb == NULL) { @@ -813,13 +814,13 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, goto out_free; } - rc = cifs_setup_cifs_sb(volume_info, cifs_sb); + rc = cifs_setup_cifs_sb(ctx, cifs_sb); if (rc) { root = ERR_PTR(rc); goto out_free; } - rc = cifs_mount(cifs_sb, volume_info); + rc = cifs_mount(cifs_sb, ctx); if (rc) { if (!(flags & SB_SILENT)) cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n", @@ -828,7 +829,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, goto out_free; } - mnt_data.vol = volume_info; + mnt_data.ctx = ctx; mnt_data.cifs_sb = cifs_sb; mnt_data.flags = flags; @@ -855,7 +856,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, sb->s_flags |= SB_ACTIVE; } - root = cifs_get_root(volume_info, sb); + root = cifs_get_root(ctx, sb); if (IS_ERR(root)) goto out_super; @@ -865,7 +866,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, out_super: deactivate_locked_super(sb); out: - cifs_cleanup_volume_info(volume_info); + cifs_cleanup_volume_info(ctx); return root; out_free: @@ -873,7 +874,7 @@ out_free: kfree(cifs_sb->mountdata); kfree(cifs_sb); out_nls: - unload_nls(volume_info->local_nls); + unload_nls(ctx->local_nls); goto out; } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 484ec2d8c5c9..b46809260e79 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -202,7 +202,7 @@ struct cifs_ses; struct cifs_tcon; struct dfs_info3_param; struct cifs_fattr; -struct smb_vol; +struct smb3_fs_context; struct cifs_fid; struct cifs_readdata; struct cifs_writedata; @@ -268,9 +268,9 @@ struct smb_version_operations { /* negotiate to the server */ int (*negotiate)(const unsigned int, struct cifs_ses *); /* set negotiated write size */ - unsigned int (*negotiate_wsize)(struct cifs_tcon *, struct smb_vol *); + unsigned int (*negotiate_wsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); /* set negotiated read size */ - unsigned int (*negotiate_rsize)(struct cifs_tcon *, struct smb_vol *); + unsigned int (*negotiate_rsize)(struct cifs_tcon *tcon, struct smb3_fs_context *ctx); /* setup smb sessionn */ int (*sess_setup)(const unsigned int, struct cifs_ses *, const struct nls_table *); @@ -530,97 +530,6 @@ struct smb_version_values { #define HEADER_SIZE(server) (server->vals->header_size) #define MAX_HEADER_SIZE(server) (server->vals->max_header_size) -struct smb_vol { - char *username; - char *password; - char *domainname; - char *UNC; - char *iocharset; /* local code page for mapping to and from Unicode */ - char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ - char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ - kuid_t cred_uid; - kuid_t linux_uid; - kgid_t linux_gid; - kuid_t backupuid; - kgid_t backupgid; - umode_t file_mode; - umode_t dir_mode; - enum securityEnum sectype; /* sectype requested via mnt opts */ - bool sign; /* was signing requested via mnt opts? */ - bool ignore_signature:1; - bool retry:1; - bool intr:1; - bool setuids:1; - bool setuidfromacl:1; - bool override_uid:1; - bool override_gid:1; - bool dynperm:1; - bool noperm:1; - bool nodelete:1; - bool mode_ace:1; - bool no_psx_acl:1; /* set if posix acl support should be disabled */ - bool cifs_acl:1; - bool backupuid_specified; /* mount option backupuid is specified */ - bool backupgid_specified; /* mount option backupgid is specified */ - bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ - bool server_ino:1; /* use inode numbers from server ie UniqueId */ - bool direct_io:1; - bool strict_io:1; /* strict cache behavior */ - bool cache_ro:1; - bool cache_rw:1; - bool remap:1; /* set to remap seven reserved chars in filenames */ - bool sfu_remap:1; /* remap seven reserved chars ala SFU */ - bool posix_paths:1; /* unset to not ask for posix pathnames. */ - bool no_linux_ext:1; - bool linux_ext:1; - bool sfu_emul:1; - bool nullauth:1; /* attempt to authenticate with null user */ - bool nocase:1; /* request case insensitive filenames */ - bool nobrl:1; /* disable sending byte range locks to srv */ - bool nohandlecache:1; /* disable caching dir handles if srvr probs */ - bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ - bool seal:1; /* request transport encryption on share */ - bool nodfs:1; /* Do not request DFS, even if available */ - bool local_lease:1; /* check leases only on local system, not remote */ - bool noblocksnd:1; - bool noautotune:1; - bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ - bool no_lease:1; /* disable requesting leases */ - bool fsc:1; /* enable fscache */ - bool mfsymlinks:1; /* use Minshall+French Symlinks */ - bool multiuser:1; - bool rwpidforward:1; /* pid forward for read/write operations */ - bool nosharesock:1; - bool persistent:1; - bool nopersistent:1; - bool resilient:1; /* noresilient not required since not fored for CA */ - bool domainauto:1; - bool rdma:1; - bool multichannel:1; - bool use_client_guid:1; - /* reuse existing guid for multichannel */ - u8 client_guid[SMB2_CLIENT_GUID_SIZE]; - unsigned int bsize; - unsigned int rsize; - unsigned int wsize; - unsigned int min_offload; - bool sockopt_tcp_nodelay:1; - unsigned long actimeo; /* attribute cache timeout (jiffies) */ - struct smb_version_operations *ops; - struct smb_version_values *vals; - char *prepath; - struct sockaddr_storage dstaddr; /* destination address */ - struct sockaddr_storage srcaddr; /* allow binding to a local IP */ - struct nls_table *local_nls; - unsigned int echo_interval; /* echo interval in secs */ - __u64 snapshot_time; /* needed for timewarp tokens */ - __u32 handle_timeout; /* persistent and durable handle timeout in ms */ - unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ - unsigned int max_channels; - __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ - bool rootfs:1; /* if it's a SMB root file system */ -}; - /** * CIFS superblock mount flags (mnt_cifs_flags) to consider when * trying to reuse existing superblock for a new mount @@ -649,7 +558,7 @@ struct smb_vol { struct cifs_mnt_data { struct cifs_sb_info *cifs_sb; - struct smb_vol *vol; + struct smb3_fs_context *ctx; int flags; }; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2ed98d4a30c1..e891a4f421a6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -27,8 +27,8 @@ #endif struct statfs; -struct smb_vol; struct smb_rqst; +struct smb3_fs_context; /* ***************************************************************** @@ -72,7 +72,7 @@ extern void exit_cifs_spnego(void); extern char *build_path_from_dentry(struct dentry *); extern char *build_path_from_dentry_optional_prefix(struct dentry *direntry, bool prefix); -extern char *cifs_build_path_to_root(struct smb_vol *vol, +extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, int add_treename); @@ -234,13 +234,13 @@ extern int cifs_read_page_from_socket(struct TCP_Server_Info *server, struct page *page, unsigned int page_offset, unsigned int to_read); -extern int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, +extern int cifs_setup_cifs_sb(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb); extern int cifs_match_super(struct super_block *, void *); -extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); -extern struct smb_vol *cifs_get_volume_info(char *mount_data, +extern void cifs_cleanup_volume_info(struct smb3_fs_context *ctx); +extern struct smb3_fs_context *cifs_get_volume_info(char *mount_data, const char *devname, bool is_smb3); -extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol); +extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx); extern void cifs_umount(struct cifs_sb_info *); extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon); extern void cifs_reopen_persistent_handles(struct cifs_tcon *tcon); @@ -256,7 +256,7 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid, struct tcon_link *tlink, struct cifs_pending_open *open); extern void cifs_del_pending_open(struct cifs_pending_open *open); -extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb_vol *vol); +extern struct TCP_Server_Info *cifs_get_tcp_session(struct smb3_fs_context *ctx); extern void cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect); extern void cifs_put_tcon(struct cifs_tcon *tcon); @@ -332,7 +332,7 @@ extern int parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size, const char *searchName, bool is_unicode); extern void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, - struct smb_vol *vol); + struct smb3_fs_context *ctx); extern int CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, struct kstatfs *FSData); extern int SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, @@ -553,18 +553,18 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); extern int -cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, +cifs_setup_volume_info(struct smb3_fs_context *ctx, char *mount_data, const char *devname, bool is_smb3); extern void -cifs_cleanup_volume_info_contents(struct smb_vol *volume_info); +cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx); extern struct TCP_Server_Info * -cifs_find_tcp_session(struct smb_vol *vol); +cifs_find_tcp_session(struct smb3_fs_context *ctx); extern void cifs_put_smb_ses(struct cifs_ses *ses); extern struct cifs_ses * -cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info); +cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx); void cifs_readdata_release(struct kref *refcount); int cifs_async_readv(struct cifs_readdata *rdata); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 44f9cce57099..fedb904b516f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1320,7 +1320,7 @@ static int get_option_gid(substring_t args[], kgid_t *result) * fields with the result. Returns 0 on success and an error otherwise. */ static int -cifs_parse_devname(const char *devname, struct smb_vol *vol) +cifs_parse_devname(const char *devname, struct smb3_fs_context *ctx) { char *pos; const char *delims = "/\\"; @@ -1349,11 +1349,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol) /* move "pos" up to delimiter or NULL */ pos += len; - vol->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); - if (!vol->UNC) + ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); + if (!ctx->UNC) return -ENOMEM; - convert_delimiter(vol->UNC, '\\'); + convert_delimiter(ctx->UNC, '\\'); /* skip any delimiter */ if (*pos == '/' || *pos == '\\') @@ -1363,8 +1363,8 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol) if (!*pos) return 0; - vol->prepath = kstrdup(pos, GFP_KERNEL); - if (!vol->prepath) + ctx->prepath = kstrdup(pos, GFP_KERNEL); + if (!ctx->prepath) return -ENOMEM; return 0; @@ -1372,7 +1372,7 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol) static int cifs_parse_mount_options(const char *mountdata, const char *devname, - struct smb_vol *vol, bool is_smb3) + struct smb3_fs_context *ctx, bool is_smb3) { char *data, *end; char *mountdata_copy = NULL, *options; @@ -1391,66 +1391,66 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, bool got_ip = false; bool got_version = false; unsigned short port = 0; - struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr; + struct sockaddr *dstaddr = (struct sockaddr *)&ctx->dstaddr; separator[0] = ','; separator[1] = 0; delim = separator[0]; - /* ensure we always start with zeroed-out smb_vol */ - memset(vol, 0, sizeof(*vol)); + /* ensure we always start with zeroed-out ctx */ + memset(ctx, 0, sizeof(*ctx)); /* * does not have to be perfect mapping since field is * informational, only used for servers that do not support * port 445 and it can be overridden at mount time */ - memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); + memset(ctx->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++) - vol->source_rfc1001_name[i] = toupper(nodename[i]); + ctx->source_rfc1001_name[i] = toupper(nodename[i]); - vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0; + ctx->source_rfc1001_name[RFC1001_NAME_LEN] = 0; /* null target name indicates to use *SMBSERVR default called name if we end up sending RFC1001 session initialize */ - vol->target_rfc1001_name[0] = 0; - vol->cred_uid = current_uid(); - vol->linux_uid = current_uid(); - vol->linux_gid = current_gid(); - vol->bsize = 1024 * 1024; /* can improve cp performance significantly */ + ctx->target_rfc1001_name[0] = 0; + ctx->cred_uid = current_uid(); + ctx->linux_uid = current_uid(); + ctx->linux_gid = current_gid(); + ctx->bsize = 1024 * 1024; /* can improve cp performance significantly */ /* * default to SFM style remapping of seven reserved characters * unless user overrides it or we negotiate CIFS POSIX where * it is unnecessary. Can not simultaneously use more than one mapping * since then readdir could list files that open could not open */ - vol->remap = true; + ctx->remap = true; /* default to only allowing write access to owner of the mount */ - vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; + ctx->dir_mode = ctx->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; - /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ + /* ctx->retry default is 0 (i.e. "soft" limited retry not hard retry) */ /* default is always to request posix paths. */ - vol->posix_paths = 1; + ctx->posix_paths = 1; /* default to using server inode numbers where available */ - vol->server_ino = 1; + ctx->server_ino = 1; /* default is to use strict cifs caching semantics */ - vol->strict_io = true; + ctx->strict_io = true; - vol->actimeo = CIFS_DEF_ACTIMEO; + ctx->actimeo = CIFS_DEF_ACTIMEO; /* Most clients set timeout to 0, allows server to use its default */ - vol->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ + ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */ /* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */ - vol->ops = &smb30_operations; - vol->vals = &smbdefault_values; + ctx->ops = &smb30_operations; + ctx->vals = &smbdefault_values; - vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; + ctx->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; /* default to no multichannel (single server connection) */ - vol->multichannel = false; - vol->max_channels = 1; + ctx->multichannel = false; + ctx->max_channels = 1; if (!mountdata) goto cifs_parse_mount_err; @@ -1470,10 +1470,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, cifs_dbg(FYI, "Null separator not allowed\n"); } } - vol->backupuid_specified = false; /* no backup intent for a user */ - vol->backupgid_specified = false; /* no backup intent for a group */ + ctx->backupuid_specified = false; /* no backup intent for a user */ + ctx->backupgid_specified = false; /* no backup intent for a group */ - switch (cifs_parse_devname(devname, vol)) { + switch (cifs_parse_devname(devname, ctx)) { case 0: break; case -ENOMEM: @@ -1505,10 +1505,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* Boolean values */ case Opt_user_xattr: - vol->no_xattr = 0; + ctx->no_xattr = 0; break; case Opt_nouser_xattr: - vol->no_xattr = 1; + ctx->no_xattr = 1; break; case Opt_forceuid: override_uid = 1; @@ -1523,175 +1523,175 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, override_gid = 0; break; case Opt_noblocksend: - vol->noblocksnd = 1; + ctx->noblocksnd = 1; break; case Opt_noautotune: - vol->noautotune = 1; + ctx->noautotune = 1; break; case Opt_nolease: - vol->no_lease = 1; + ctx->no_lease = 1; break; case Opt_hard: - vol->retry = 1; + ctx->retry = 1; break; case Opt_soft: - vol->retry = 0; + ctx->retry = 0; break; case Opt_perm: - vol->noperm = 0; + ctx->noperm = 0; break; case Opt_noperm: - vol->noperm = 1; + ctx->noperm = 1; break; case Opt_nodelete: - vol->nodelete = 1; + ctx->nodelete = 1; break; case Opt_mapchars: - vol->sfu_remap = true; - vol->remap = false; /* disable SFM mapping */ + ctx->sfu_remap = true; + ctx->remap = false; /* disable SFM mapping */ break; case Opt_nomapchars: - vol->sfu_remap = false; + ctx->sfu_remap = false; break; case Opt_mapposix: - vol->remap = true; - vol->sfu_remap = false; /* disable SFU mapping */ + ctx->remap = true; + ctx->sfu_remap = false; /* disable SFU mapping */ break; case Opt_nomapposix: - vol->remap = false; + ctx->remap = false; break; case Opt_sfu: - vol->sfu_emul = 1; + ctx->sfu_emul = 1; break; case Opt_nosfu: - vol->sfu_emul = 0; + ctx->sfu_emul = 0; break; case Opt_nodfs: - vol->nodfs = 1; + ctx->nodfs = 1; break; case Opt_rootfs: #ifdef CONFIG_CIFS_ROOT - vol->rootfs = true; + ctx->rootfs = true; #endif break; case Opt_posixpaths: - vol->posix_paths = 1; + ctx->posix_paths = 1; break; case Opt_noposixpaths: - vol->posix_paths = 0; + ctx->posix_paths = 0; break; case Opt_nounix: - if (vol->linux_ext) + if (ctx->linux_ext) cifs_dbg(VFS, "conflicting unix mount options\n"); - vol->no_linux_ext = 1; + ctx->no_linux_ext = 1; break; case Opt_unix: - if (vol->no_linux_ext) + if (ctx->no_linux_ext) cifs_dbg(VFS, "conflicting unix mount options\n"); - vol->linux_ext = 1; + ctx->linux_ext = 1; break; case Opt_nocase: - vol->nocase = 1; + ctx->nocase = 1; break; case Opt_brl: - vol->nobrl = 0; + ctx->nobrl = 0; break; case Opt_nobrl: - vol->nobrl = 1; + ctx->nobrl = 1; /* * turn off mandatory locking in mode * if remote locking is turned off since the * local vfs will do advisory */ - if (vol->file_mode == + if (ctx->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP))) - vol->file_mode = S_IALLUGO; + ctx->file_mode = S_IALLUGO; break; case Opt_nohandlecache: - vol->nohandlecache = 1; + ctx->nohandlecache = 1; break; case Opt_handlecache: - vol->nohandlecache = 0; + ctx->nohandlecache = 0; break; case Opt_forcemandatorylock: - vol->mand_lock = 1; + ctx->mand_lock = 1; break; case Opt_setuids: - vol->setuids = 1; + ctx->setuids = 1; break; case Opt_nosetuids: - vol->setuids = 0; + ctx->setuids = 0; break; case Opt_setuidfromacl: - vol->setuidfromacl = 1; + ctx->setuidfromacl = 1; break; case Opt_dynperm: - vol->dynperm = true; + ctx->dynperm = true; break; case Opt_nodynperm: - vol->dynperm = false; + ctx->dynperm = false; break; case Opt_nohard: - vol->retry = 0; + ctx->retry = 0; break; case Opt_nosoft: - vol->retry = 1; + ctx->retry = 1; break; case Opt_nointr: - vol->intr = 0; + ctx->intr = 0; break; case Opt_intr: - vol->intr = 1; + ctx->intr = 1; break; case Opt_nostrictsync: - vol->nostrictsync = 1; + ctx->nostrictsync = 1; break; case Opt_strictsync: - vol->nostrictsync = 0; + ctx->nostrictsync = 0; break; case Opt_serverino: - vol->server_ino = 1; + ctx->server_ino = 1; break; case Opt_noserverino: - vol->server_ino = 0; + ctx->server_ino = 0; break; case Opt_rwpidforward: - vol->rwpidforward = 1; + ctx->rwpidforward = 1; break; case Opt_modesid: - vol->mode_ace = 1; + ctx->mode_ace = 1; break; case Opt_cifsacl: - vol->cifs_acl = 1; + ctx->cifs_acl = 1; break; case Opt_nocifsacl: - vol->cifs_acl = 0; + ctx->cifs_acl = 0; break; case Opt_acl: - vol->no_psx_acl = 0; + ctx->no_psx_acl = 0; break; case Opt_noacl: - vol->no_psx_acl = 1; + ctx->no_psx_acl = 1; break; case Opt_locallease: - vol->local_lease = 1; + ctx->local_lease = 1; break; case Opt_sign: - vol->sign = true; + ctx->sign = true; break; case Opt_ignore_signature: - vol->sign = true; - vol->ignore_signature = true; + ctx->sign = true; + ctx->ignore_signature = true; break; case Opt_seal: /* we do not do the following in secFlags because seal * is a per tree connection (mount) not a per socket * or per-smb connection option in the protocol - * vol->secFlg |= CIFSSEC_MUST_SEAL; + * ctx->secFlg |= CIFSSEC_MUST_SEAL; */ - vol->seal = 1; + ctx->seal = 1; break; case Opt_noac: pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n"); @@ -1701,88 +1701,88 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n"); goto cifs_parse_mount_err; #endif - vol->fsc = true; + ctx->fsc = true; break; case Opt_mfsymlinks: - vol->mfsymlinks = true; + ctx->mfsymlinks = true; break; case Opt_multiuser: - vol->multiuser = true; + ctx->multiuser = true; break; case Opt_sloppy: sloppy = true; break; case Opt_nosharesock: - vol->nosharesock = true; + ctx->nosharesock = true; break; case Opt_nopersistent: - vol->nopersistent = true; - if (vol->persistent) { + ctx->nopersistent = true; + if (ctx->persistent) { cifs_dbg(VFS, "persistenthandles mount options conflict\n"); goto cifs_parse_mount_err; } break; case Opt_persistent: - vol->persistent = true; - if ((vol->nopersistent) || (vol->resilient)) { + ctx->persistent = true; + if ((ctx->nopersistent) || (ctx->resilient)) { cifs_dbg(VFS, "persistenthandles mount options conflict\n"); goto cifs_parse_mount_err; } break; case Opt_resilient: - vol->resilient = true; - if (vol->persistent) { + ctx->resilient = true; + if (ctx->persistent) { cifs_dbg(VFS, "persistenthandles mount options conflict\n"); goto cifs_parse_mount_err; } break; case Opt_noresilient: - vol->resilient = false; /* already the default */ + ctx->resilient = false; /* already the default */ break; case Opt_domainauto: - vol->domainauto = true; + ctx->domainauto = true; break; case Opt_rdma: - vol->rdma = true; + ctx->rdma = true; break; case Opt_multichannel: - vol->multichannel = true; + ctx->multichannel = true; /* if number of channels not specified, default to 2 */ - if (vol->max_channels < 2) - vol->max_channels = 2; + if (ctx->max_channels < 2) + ctx->max_channels = 2; break; case Opt_nomultichannel: - vol->multichannel = false; - vol->max_channels = 1; + ctx->multichannel = false; + ctx->max_channels = 1; break; case Opt_compress: - vol->compression = UNKNOWN_TYPE; + ctx->compression = UNKNOWN_TYPE; cifs_dbg(VFS, "SMB3 compression support is experimental\n"); break; /* Numeric Values */ case Opt_backupuid: - if (get_option_uid(args, &vol->backupuid)) { + if (get_option_uid(args, &ctx->backupuid)) { cifs_dbg(VFS, "%s: Invalid backupuid value\n", __func__); goto cifs_parse_mount_err; } - vol->backupuid_specified = true; + ctx->backupuid_specified = true; break; case Opt_backupgid: - if (get_option_gid(args, &vol->backupgid)) { + if (get_option_gid(args, &ctx->backupgid)) { cifs_dbg(VFS, "%s: Invalid backupgid value\n", __func__); goto cifs_parse_mount_err; } - vol->backupgid_specified = true; + ctx->backupgid_specified = true; break; case Opt_uid: - if (get_option_uid(args, &vol->linux_uid)) { + if (get_option_uid(args, &ctx->linux_uid)) { cifs_dbg(VFS, "%s: Invalid uid value\n", __func__); goto cifs_parse_mount_err; @@ -1790,14 +1790,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, uid_specified = true; break; case Opt_cruid: - if (get_option_uid(args, &vol->cred_uid)) { + if (get_option_uid(args, &ctx->cred_uid)) { cifs_dbg(VFS, "%s: Invalid cruid value\n", __func__); goto cifs_parse_mount_err; } break; case Opt_gid: - if (get_option_gid(args, &vol->linux_gid)) { + if (get_option_gid(args, &ctx->linux_gid)) { cifs_dbg(VFS, "%s: Invalid gid value\n", __func__); goto cifs_parse_mount_err; @@ -1810,7 +1810,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->file_mode = option; + ctx->file_mode = option; break; case Opt_dirmode: if (get_option_ul(args, &option)) { @@ -1818,7 +1818,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->dir_mode = option; + ctx->dir_mode = option; break; case Opt_port: if (get_option_ul(args, &option) || @@ -1834,7 +1834,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n"); goto cifs_parse_mount_err; } - vol->min_offload = option; + ctx->min_offload = option; break; case Opt_blocksize: if (get_option_ul(args, &option)) { @@ -1854,7 +1854,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->bsize = option; + ctx->bsize = option; break; case Opt_rsize: if (get_option_ul(args, &option)) { @@ -1862,7 +1862,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->rsize = option; + ctx->rsize = option; break; case Opt_wsize: if (get_option_ul(args, &option)) { @@ -1870,7 +1870,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->wsize = option; + ctx->wsize = option; break; case Opt_actimeo: if (get_option_ul(args, &option)) { @@ -1878,8 +1878,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->actimeo = HZ * option; - if (vol->actimeo > CIFS_MAX_ACTIMEO) { + ctx->actimeo = HZ * option; + if (ctx->actimeo > CIFS_MAX_ACTIMEO) { cifs_dbg(VFS, "attribute cache timeout too large\n"); goto cifs_parse_mount_err; } @@ -1890,8 +1890,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->handle_timeout = option; - if (vol->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { + ctx->handle_timeout = option; + if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) { cifs_dbg(VFS, "Invalid handle cache timeout, longer than 16 minutes\n"); goto cifs_parse_mount_err; } @@ -1902,7 +1902,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->echo_interval = option; + ctx->echo_interval = option; break; case Opt_snapshot: if (get_option_ul(args, &option)) { @@ -1910,7 +1910,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->snapshot_time = option; + ctx->snapshot_time = option; break; case Opt_max_credits: if (get_option_ul(args, &option) || (option < 20) || @@ -1919,7 +1919,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__); goto cifs_parse_mount_err; } - vol->max_credits = option; + ctx->max_credits = option; break; case Opt_max_channels: if (get_option_ul(args, &option) || option < 1 || @@ -1928,15 +1928,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, __func__, CIFS_MAX_CHANNELS); goto cifs_parse_mount_err; } - vol->max_channels = option; + ctx->max_channels = option; break; /* String Arguments */ case Opt_blank_user: /* null user, ie. anonymous authentication */ - vol->nullauth = 1; - vol->username = NULL; + ctx->nullauth = 1; + ctx->username = NULL; break; case Opt_user: string = match_strdup(args); @@ -1949,9 +1949,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto cifs_parse_mount_err; } - kfree(vol->username); - vol->username = kstrdup(string, GFP_KERNEL); - if (!vol->username) + kfree(ctx->username); + ctx->username = kstrdup(string, GFP_KERNEL); + if (!ctx->username) goto cifs_parse_mount_err; break; case Opt_blank_pass: @@ -1968,8 +1968,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, tmp_end++; if (!(tmp_end < end && tmp_end[1] == delim)) { /* No it is not. Set the password to NULL */ - kfree_sensitive(vol->password); - vol->password = NULL; + kfree_sensitive(ctx->password); + ctx->password = NULL; break; } fallthrough; /* to Opt_pass below */ @@ -2006,23 +2006,23 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, options = end; } - kfree_sensitive(vol->password); + kfree_sensitive(ctx->password); /* Now build new password string */ temp_len = strlen(value); - vol->password = kzalloc(temp_len+1, GFP_KERNEL); - if (vol->password == NULL) { + ctx->password = kzalloc(temp_len+1, GFP_KERNEL); + if (ctx->password == NULL) { pr_warn("no memory for password\n"); goto cifs_parse_mount_err; } for (i = 0, j = 0; i < temp_len; i++, j++) { - vol->password[j] = value[i]; + ctx->password[j] = value[i]; if ((value[i] == delim) && value[i+1] == delim) /* skip the second deliminator */ i++; } - vol->password[j] = '\0'; + ctx->password[j] = '\0'; break; case Opt_blank_ip: /* FIXME: should this be an error instead? */ @@ -2051,9 +2051,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto cifs_parse_mount_err; } - kfree(vol->domainname); - vol->domainname = kstrdup(string, GFP_KERNEL); - if (!vol->domainname) { + kfree(ctx->domainname); + ctx->domainname = kstrdup(string, GFP_KERNEL); + if (!ctx->domainname) { pr_warn("no memory for domainname\n"); goto cifs_parse_mount_err; } @@ -2065,7 +2065,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto out_nomem; if (!cifs_convert_address( - (struct sockaddr *)&vol->srcaddr, + (struct sockaddr *)&ctx->srcaddr, string, strlen(string))) { pr_warn("Could not parse srcaddr: %s\n", string); @@ -2083,10 +2083,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } if (strncasecmp(string, "default", 7) != 0) { - kfree(vol->iocharset); - vol->iocharset = kstrdup(string, + kfree(ctx->iocharset); + ctx->iocharset = kstrdup(string, GFP_KERNEL); - if (!vol->iocharset) { + if (!ctx->iocharset) { pr_warn("no memory for charset\n"); goto cifs_parse_mount_err; } @@ -2101,7 +2101,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - memset(vol->source_rfc1001_name, 0x20, + memset(ctx->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); /* * FIXME: are there cases in which a comma can @@ -2112,7 +2112,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* don't ucase netbiosname for user */ if (string[i] == 0) break; - vol->source_rfc1001_name[i] = string[i]; + ctx->source_rfc1001_name[i] = string[i]; } /* The string has 16th byte zero still from * set at top of the function @@ -2127,7 +2127,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto out_nomem; /* last byte, type, is 0x20 for servr type */ - memset(vol->target_rfc1001_name, 0x20, + memset(ctx->target_rfc1001_name, 0x20, RFC1001_NAME_LEN_WITH_NULL); /* BB are there cases in which a comma can be @@ -2139,7 +2139,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, for (i = 0; i < 15; i++) { if (string[i] == 0) break; - vol->target_rfc1001_name[i] = string[i]; + ctx->target_rfc1001_name[i] = string[i]; } /* The string has 16th byte zero still from set at top of the function */ @@ -2171,7 +2171,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (cifs_parse_smb_version(string, vol, is_smb3) != 0) + if (cifs_parse_smb_version(string, ctx, is_smb3) != 0) goto cifs_parse_mount_err; got_version = true; break; @@ -2180,7 +2180,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (cifs_parse_security_flavors(string, vol) != 0) + if (cifs_parse_security_flavors(string, ctx) != 0) goto cifs_parse_mount_err; break; case Opt_cache: @@ -2188,7 +2188,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (cifs_parse_cache_flavor(string, vol) != 0) + if (cifs_parse_cache_flavor(string, ctx) != 0) goto cifs_parse_mount_err; break; default: @@ -2210,25 +2210,25 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, goto cifs_parse_mount_err; } - if (vol->rdma && vol->vals->protocol_id < SMB30_PROT_ID) { + if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) { cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n"); goto cifs_parse_mount_err; } #ifndef CONFIG_KEYS /* Muliuser mounts require CONFIG_KEYS support */ - if (vol->multiuser) { + if (ctx->multiuser) { cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n"); goto cifs_parse_mount_err; } #endif - if (!vol->UNC) { + if (!ctx->UNC) { cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n"); goto cifs_parse_mount_err; } /* make sure UNC has a share name */ - if (!strchr(vol->UNC + 3, '\\')) { + if (!strchr(ctx->UNC + 3, '\\')) { cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n"); goto cifs_parse_mount_err; } @@ -2239,9 +2239,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* No ip= option specified? Try to get it from UNC */ /* Use the address part of the UNC. */ - slash = strchr(&vol->UNC[2], '\\'); - len = slash - &vol->UNC[2]; - if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) { + slash = strchr(&ctx->UNC[2], '\\'); + len = slash - &ctx->UNC[2]; + if (!cifs_convert_address(dstaddr, &ctx->UNC[2], len)) { pr_err("Unable to determine destination address\n"); goto cifs_parse_mount_err; } @@ -2251,12 +2251,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, cifs_set_port(dstaddr, port); if (uid_specified) - vol->override_uid = override_uid; + ctx->override_uid = override_uid; else if (override_uid == 1) pr_notice("ignoring forceuid mount option specified with no uid= option\n"); if (gid_specified) - vol->override_gid = override_gid; + ctx->override_gid = override_gid; else if (override_gid == 1) pr_notice("ignoring forcegid mount option specified with no gid= option\n"); @@ -2377,14 +2377,14 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr, } static bool -match_security(struct TCP_Server_Info *server, struct smb_vol *vol) +match_security(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) { /* - * The select_sectype function should either return the vol->sectype + * The select_sectype function should either return the ctx->sectype * that was specified, or "Unspecified" if that sectype was not * compatible with the given NEGOTIATE request. */ - if (server->ops->select_sectype(server, vol->sectype) + if (server->ops->select_sectype(server, ctx->sectype) == Unspecified) return false; @@ -2393,60 +2393,60 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol) * global_secflags at this point since if MUST_SIGN is set then * the server->sign had better be too. */ - if (vol->sign && !server->sign) + if (ctx->sign && !server->sign) return false; return true; } -static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) +static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) { - struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr; + struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr; - if (vol->nosharesock) + if (ctx->nosharesock) return 0; /* If multidialect negotiation see if existing sessions match one */ - if (strcmp(vol->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { + if (strcmp(ctx->vals->version_string, SMB3ANY_VERSION_STRING) == 0) { if (server->vals->protocol_id < SMB30_PROT_ID) return 0; - } else if (strcmp(vol->vals->version_string, + } else if (strcmp(ctx->vals->version_string, SMBDEFAULT_VERSION_STRING) == 0) { if (server->vals->protocol_id < SMB21_PROT_ID) return 0; - } else if ((server->vals != vol->vals) || (server->ops != vol->ops)) + } else if ((server->vals != ctx->vals) || (server->ops != ctx->ops)) return 0; if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) return 0; if (!match_address(server, addr, - (struct sockaddr *)&vol->srcaddr)) + (struct sockaddr *)&ctx->srcaddr)) return 0; if (!match_port(server, addr)) return 0; - if (!match_security(server, vol)) + if (!match_security(server, ctx)) return 0; - if (server->echo_interval != vol->echo_interval * HZ) + if (server->echo_interval != ctx->echo_interval * HZ) return 0; - if (server->rdma != vol->rdma) + if (server->rdma != ctx->rdma) return 0; - if (server->ignore_signature != vol->ignore_signature) + if (server->ignore_signature != ctx->ignore_signature) return 0; - if (server->min_offload != vol->min_offload) + if (server->min_offload != ctx->min_offload) return 0; return 1; } struct TCP_Server_Info * -cifs_find_tcp_session(struct smb_vol *vol) +cifs_find_tcp_session(struct smb3_fs_context *ctx) { struct TCP_Server_Info *server; @@ -2456,7 +2456,7 @@ cifs_find_tcp_session(struct smb_vol *vol) * Skip ses channels since they're only handled in lower layers * (e.g. cifs_send_recv). */ - if (server->is_channel || !match_server(server, vol)) + if (server->is_channel || !match_server(server, ctx)) continue; ++server->srv_count; @@ -2514,15 +2514,15 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) } struct TCP_Server_Info * -cifs_get_tcp_session(struct smb_vol *volume_info) +cifs_get_tcp_session(struct smb3_fs_context *ctx) { struct TCP_Server_Info *tcp_ses = NULL; int rc; - cifs_dbg(FYI, "UNC: %s\n", volume_info->UNC); + cifs_dbg(FYI, "UNC: %s\n", ctx->UNC); /* see if we already have a matching tcp_ses */ - tcp_ses = cifs_find_tcp_session(volume_info); + tcp_ses = cifs_find_tcp_session(ctx); if (tcp_ses) return tcp_ses; @@ -2532,20 +2532,20 @@ cifs_get_tcp_session(struct smb_vol *volume_info) goto out_err; } - tcp_ses->ops = volume_info->ops; - tcp_ses->vals = volume_info->vals; + tcp_ses->ops = ctx->ops; + tcp_ses->vals = ctx->vals; cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); - tcp_ses->hostname = extract_hostname(volume_info->UNC); + tcp_ses->hostname = extract_hostname(ctx->UNC); if (IS_ERR(tcp_ses->hostname)) { rc = PTR_ERR(tcp_ses->hostname); goto out_err_crypto_release; } - tcp_ses->noblockcnt = volume_info->rootfs; - tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs; - tcp_ses->noautotune = volume_info->noautotune; - tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; - tcp_ses->rdma = volume_info->rdma; + tcp_ses->noblockcnt = ctx->rootfs; + tcp_ses->noblocksnd = ctx->noblocksnd || ctx->rootfs; + tcp_ses->noautotune = ctx->noautotune; + tcp_ses->tcp_nodelay = ctx->sockopt_tcp_nodelay; + tcp_ses->rdma = ctx->rdma; tcp_ses->in_flight = 0; tcp_ses->max_in_flight = 0; tcp_ses->credits = 1; @@ -2554,26 +2554,26 @@ cifs_get_tcp_session(struct smb_vol *volume_info) INIT_LIST_HEAD(&tcp_ses->pending_mid_q); mutex_init(&tcp_ses->srv_mutex); memcpy(tcp_ses->workstation_RFC1001_name, - volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); + ctx->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); memcpy(tcp_ses->server_RFC1001_name, - volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); + ctx->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; tcp_ses->reconnect_instance = 1; tcp_ses->lstrp = jiffies; - tcp_ses->compress_algorithm = cpu_to_le16(volume_info->compression); + tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression); spin_lock_init(&tcp_ses->req_lock); INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); mutex_init(&tcp_ses->reconnect_mutex); - memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, + memcpy(&tcp_ses->srcaddr, &ctx->srcaddr, sizeof(tcp_ses->srcaddr)); - memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, + memcpy(&tcp_ses->dstaddr, &ctx->dstaddr, sizeof(tcp_ses->dstaddr)); - if (volume_info->use_client_guid) - memcpy(tcp_ses->client_guid, volume_info->client_guid, + if (ctx->use_client_guid) + memcpy(tcp_ses->client_guid, ctx->client_guid, SMB2_CLIENT_GUID_SIZE); else generate_random_uuid(tcp_ses->client_guid); @@ -2585,9 +2585,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->tcpStatus = CifsNew; ++tcp_ses->srv_count; - if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN && - volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX) - tcp_ses->echo_interval = volume_info->echo_interval * HZ; + if (ctx->echo_interval >= SMB_ECHO_INTERVAL_MIN && + ctx->echo_interval <= SMB_ECHO_INTERVAL_MAX) + tcp_ses->echo_interval = ctx->echo_interval * HZ; else tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ; if (tcp_ses->rdma) { @@ -2597,7 +2597,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) goto out_err_crypto_release; #endif tcp_ses->smbd_conn = smbd_get_connection( - tcp_ses, (struct sockaddr *)&volume_info->dstaddr); + tcp_ses, (struct sockaddr *)&ctx->dstaddr); if (tcp_ses->smbd_conn) { cifs_dbg(VFS, "RDMA transport established\n"); rc = 0; @@ -2626,11 +2626,11 @@ smbd_connected: module_put(THIS_MODULE); goto out_err_crypto_release; } - tcp_ses->min_offload = volume_info->min_offload; + tcp_ses->min_offload = ctx->min_offload; tcp_ses->tcpStatus = CifsNeedNegotiate; tcp_ses->nr_targets = 1; - tcp_ses->ignore_signature = volume_info->ignore_signature; + tcp_ses->ignore_signature = ctx->ignore_signature; /* thread spawned, put it on the list */ spin_lock(&cifs_tcp_ses_lock); list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); @@ -2659,41 +2659,41 @@ out_err: return ERR_PTR(rc); } -static int match_session(struct cifs_ses *ses, struct smb_vol *vol) +static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx) { - if (vol->sectype != Unspecified && - vol->sectype != ses->sectype) + if (ctx->sectype != Unspecified && + ctx->sectype != ses->sectype) return 0; /* * If an existing session is limited to less channels than * requested, it should not be reused */ - if (ses->chan_max < vol->max_channels) + if (ses->chan_max < ctx->max_channels) return 0; switch (ses->sectype) { case Kerberos: - if (!uid_eq(vol->cred_uid, ses->cred_uid)) + if (!uid_eq(ctx->cred_uid, ses->cred_uid)) return 0; break; default: /* NULL username means anonymous session */ if (ses->user_name == NULL) { - if (!vol->nullauth) + if (!ctx->nullauth) return 0; break; } /* anything else takes username/password */ if (strncmp(ses->user_name, - vol->username ? vol->username : "", + ctx->username ? ctx->username : "", CIFS_MAX_USERNAME_LEN)) return 0; - if ((vol->username && strlen(vol->username) != 0) && + if ((ctx->username && strlen(ctx->username) != 0) && ses->password != NULL && strncmp(ses->password, - vol->password ? vol->password : "", + ctx->password ? ctx->password : "", CIFS_MAX_PASSWORD_LEN)) return 0; } @@ -2707,7 +2707,7 @@ static int match_session(struct cifs_ses *ses, struct smb_vol *vol) * tcon_ipc. The IPC tcon has the same lifetime as the session. */ static int -cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info) +cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx) { int rc = 0, xid; struct cifs_tcon *tcon; @@ -2720,7 +2720,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info) * If the mount request that resulted in the creation of the * session requires encryption, force IPC to be encrypted too. */ - if (volume_info->seal) { + if (ctx->seal) { if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) seal = true; else { @@ -2789,7 +2789,7 @@ cifs_free_ipc(struct cifs_ses *ses) } static struct cifs_ses * -cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) +cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) { struct cifs_ses *ses; @@ -2797,7 +2797,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { if (ses->status == CifsExiting) continue; - if (!match_session(ses, vol)) + if (!match_session(ses, ctx)) continue; ++ses->ses_count; spin_unlock(&cifs_tcp_ses_lock); @@ -2861,7 +2861,7 @@ void cifs_put_smb_ses(struct cifs_ses *ses) /* Populate username and pw fields from keyring if possible */ static int -cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) +cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) { int rc = 0; int is_domain = 0; @@ -2941,32 +2941,32 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) goto out_key_put; } - vol->username = kstrndup(payload, len, GFP_KERNEL); - if (!vol->username) { + ctx->username = kstrndup(payload, len, GFP_KERNEL); + if (!ctx->username) { cifs_dbg(FYI, "Unable to allocate %zd bytes for username\n", len); rc = -ENOMEM; goto out_key_put; } - cifs_dbg(FYI, "%s: username=%s\n", __func__, vol->username); + cifs_dbg(FYI, "%s: username=%s\n", __func__, ctx->username); len = key->datalen - (len + 1); if (len > CIFS_MAX_PASSWORD_LEN || len <= 0) { cifs_dbg(FYI, "Bad len for password search (len=%zd)\n", len); rc = -EINVAL; - kfree(vol->username); - vol->username = NULL; + kfree(ctx->username); + ctx->username = NULL; goto out_key_put; } ++delim; - vol->password = kstrndup(delim, len, GFP_KERNEL); - if (!vol->password) { + ctx->password = kstrndup(delim, len, GFP_KERNEL); + if (!ctx->password) { cifs_dbg(FYI, "Unable to allocate %zd bytes for password\n", len); rc = -ENOMEM; - kfree(vol->username); - vol->username = NULL; + kfree(ctx->username); + ctx->username = NULL; goto out_key_put; } @@ -2975,17 +2975,17 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses) * for the request. */ if (is_domain && ses->domainName) { - vol->domainname = kstrndup(ses->domainName, + ctx->domainname = kstrndup(ses->domainName, strlen(ses->domainName), GFP_KERNEL); - if (!vol->domainname) { + if (!ctx->domainname) { cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n", len); rc = -ENOMEM; - kfree(vol->username); - vol->username = NULL; - kfree_sensitive(vol->password); - vol->password = NULL; + kfree(ctx->username); + ctx->username = NULL; + kfree_sensitive(ctx->password); + ctx->password = NULL; goto out_key_put; } } @@ -3000,7 +3000,7 @@ out_err: } #else /* ! CONFIG_KEYS */ static inline int -cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)), +cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)), struct cifs_ses *ses __attribute__((unused))) { return -ENOSYS; @@ -3008,14 +3008,14 @@ cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)), #endif /* CONFIG_KEYS */ /** - * cifs_get_smb_ses - get a session matching @volume_info data from @server + * cifs_get_smb_ses - get a session matching @ctx data from @server * * This function assumes it is being called from cifs_mount() where we * already got a server reference (server refcount +1). See * cifs_get_tcon() for refcount explanations. */ struct cifs_ses * -cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) +cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx) { int rc = -ENOMEM; unsigned int xid; @@ -3025,7 +3025,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) xid = get_xid(); - ses = cifs_find_smb_ses(server, volume_info); + ses = cifs_find_smb_ses(server, ctx); if (ses) { cifs_dbg(FYI, "Existing smb sess found (status=%d)\n", ses->status); @@ -3042,7 +3042,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) if (ses->need_reconnect) { cifs_dbg(FYI, "Session needs reconnect\n"); rc = cifs_setup_session(xid, ses, - volume_info->local_nls); + ctx->local_nls); if (rc) { mutex_unlock(&ses->session_mutex); /* problem -- put our reference */ @@ -3071,40 +3071,40 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) else sprintf(ses->serverName, "%pI4", &addr->sin_addr); - if (volume_info->username) { - ses->user_name = kstrdup(volume_info->username, GFP_KERNEL); + if (ctx->username) { + ses->user_name = kstrdup(ctx->username, GFP_KERNEL); if (!ses->user_name) goto get_ses_fail; } - /* volume_info->password freed at unmount */ - if (volume_info->password) { - ses->password = kstrdup(volume_info->password, GFP_KERNEL); + /* ctx->password freed at unmount */ + if (ctx->password) { + ses->password = kstrdup(ctx->password, GFP_KERNEL); if (!ses->password) goto get_ses_fail; } - if (volume_info->domainname) { - ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL); + if (ctx->domainname) { + ses->domainName = kstrdup(ctx->domainname, GFP_KERNEL); if (!ses->domainName) goto get_ses_fail; } - if (volume_info->domainauto) - ses->domainAuto = volume_info->domainauto; - ses->cred_uid = volume_info->cred_uid; - ses->linux_uid = volume_info->linux_uid; + if (ctx->domainauto) + ses->domainAuto = ctx->domainauto; + ses->cred_uid = ctx->cred_uid; + ses->linux_uid = ctx->linux_uid; - ses->sectype = volume_info->sectype; - ses->sign = volume_info->sign; + ses->sectype = ctx->sectype; + ses->sign = ctx->sign; mutex_lock(&ses->session_mutex); /* add server as first channel */ ses->chans[0].server = server; ses->chan_count = 1; - ses->chan_max = volume_info->multichannel ? volume_info->max_channels:1; + ses->chan_max = ctx->multichannel ? ctx->max_channels:1; rc = cifs_negotiate_protocol(xid, ses); if (!rc) - rc = cifs_setup_session(xid, ses, volume_info->local_nls); + rc = cifs_setup_session(xid, ses, ctx->local_nls); /* each channel uses a different signing key */ memcpy(ses->chans[0].signkey, ses->smb3signingkey, @@ -3121,7 +3121,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) free_xid(xid); - cifs_setup_ipc(ses, volume_info); + cifs_setup_ipc(ses, ctx); return ses; @@ -3131,27 +3131,27 @@ get_ses_fail: return ERR_PTR(rc); } -static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) +static int match_tcon(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { if (tcon->tidStatus == CifsExiting) return 0; - if (strncmp(tcon->treeName, volume_info->UNC, MAX_TREE_SIZE)) + if (strncmp(tcon->treeName, ctx->UNC, MAX_TREE_SIZE)) return 0; - if (tcon->seal != volume_info->seal) + if (tcon->seal != ctx->seal) return 0; - if (tcon->snapshot_time != volume_info->snapshot_time) + if (tcon->snapshot_time != ctx->snapshot_time) return 0; - if (tcon->handle_timeout != volume_info->handle_timeout) + if (tcon->handle_timeout != ctx->handle_timeout) return 0; - if (tcon->no_lease != volume_info->no_lease) + if (tcon->no_lease != ctx->no_lease) return 0; - if (tcon->nodelete != volume_info->nodelete) + if (tcon->nodelete != ctx->nodelete) return 0; return 1; } static struct cifs_tcon * -cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) +cifs_find_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) { struct list_head *tmp; struct cifs_tcon *tcon; @@ -3163,7 +3163,7 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) if (tcon->dfs_path) continue; #endif - if (!match_tcon(tcon, volume_info)) + if (!match_tcon(tcon, ctx)) continue; ++tcon->tc_count; spin_unlock(&cifs_tcp_ses_lock); @@ -3208,7 +3208,7 @@ cifs_put_tcon(struct cifs_tcon *tcon) } /** - * cifs_get_tcon - get a tcon matching @volume_info data from @ses + * cifs_get_tcon - get a tcon matching @ctx data from @ses * * - tcon refcount is the number of mount points using the tcon. * - ses refcount is the number of tcon using the session. @@ -3228,12 +3228,12 @@ cifs_put_tcon(struct cifs_tcon *tcon) * decrement the ses refcount. */ static struct cifs_tcon * -cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) +cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx) { int rc, xid; struct cifs_tcon *tcon; - tcon = cifs_find_tcon(ses, volume_info); + tcon = cifs_find_tcon(ses, ctx); if (tcon) { /* * tcon has refcount already incremented but we need to @@ -3255,36 +3255,36 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) goto out_fail; } - if (volume_info->snapshot_time) { + if (ctx->snapshot_time) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "Use SMB2 or later for snapshot mount option\n"); rc = -EOPNOTSUPP; goto out_fail; } else - tcon->snapshot_time = volume_info->snapshot_time; + tcon->snapshot_time = ctx->snapshot_time; } - if (volume_info->handle_timeout) { + if (ctx->handle_timeout) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "Use SMB2.1 or later for handle timeout option\n"); rc = -EOPNOTSUPP; goto out_fail; } else - tcon->handle_timeout = volume_info->handle_timeout; + tcon->handle_timeout = ctx->handle_timeout; } tcon->ses = ses; - if (volume_info->password) { - tcon->password = kstrdup(volume_info->password, GFP_KERNEL); + if (ctx->password) { + tcon->password = kstrdup(ctx->password, GFP_KERNEL); if (!tcon->password) { rc = -ENOMEM; goto out_fail; } } - if (volume_info->seal) { + if (ctx->seal) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "SMB3 or later required for encryption\n"); @@ -3300,7 +3300,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) } } - if (volume_info->linux_ext) { + if (ctx->linux_ext) { if (ses->server->posix_ext_supported) { tcon->posix_extensions = true; pr_warn_once("SMB3.11 POSIX Extensions are experimental\n"); @@ -3316,8 +3316,8 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) * SetFS as we do on SessSetup and reconnect? */ xid = get_xid(); - rc = ses->server->ops->tree_connect(xid, ses, volume_info->UNC, tcon, - volume_info->local_nls); + rc = ses->server->ops->tree_connect(xid, ses, ctx->UNC, tcon, + ctx->local_nls); free_xid(xid); cifs_dbg(FYI, "Tcon rc = %d\n", rc); if (rc) @@ -3325,7 +3325,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) tcon->use_persistent = false; /* check if SMB2 or later, CIFS does not support persistent handles */ - if (volume_info->persistent) { + if (ctx->persistent) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "SMB3 or later required for persistent handles\n"); @@ -3342,10 +3342,10 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) } } else if ((tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) && (ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) - && (volume_info->nopersistent == false)) { + && (ctx->nopersistent == false)) { cifs_dbg(FYI, "enabling persistent handles\n"); tcon->use_persistent = true; - } else if (volume_info->resilient) { + } else if (ctx->resilient) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "SMB2.1 or later required for resilient handles\n"); @@ -3357,20 +3357,20 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) /* If the user really knows what they are doing they can override */ if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { - if (volume_info->cache_ro) + if (ctx->cache_ro) cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n"); - else if (volume_info->cache_rw) + else if (ctx->cache_rw) cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n"); } - if (volume_info->no_lease) { + if (ctx->no_lease) { if (ses->server->vals->protocol_id == 0) { cifs_dbg(VFS, "SMB2 or later required for nolease option\n"); rc = -EOPNOTSUPP; goto out_fail; } else - tcon->no_lease = volume_info->no_lease; + tcon->no_lease = ctx->no_lease; } /* @@ -3378,14 +3378,14 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) * resources mounted more than once to the same server share the last * value passed in for the retry flag is used. */ - tcon->retry = volume_info->retry; - tcon->nocase = volume_info->nocase; + tcon->retry = ctx->retry; + tcon->nocase = ctx->nocase; if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) - tcon->nohandlecache = volume_info->nohandlecache; + tcon->nohandlecache = ctx->nohandlecache; else tcon->nohandlecache = 1; - tcon->nodelete = volume_info->nodelete; - tcon->local_lease = volume_info->local_lease; + tcon->nodelete = ctx->nodelete; + tcon->local_lease = ctx->local_lease; INIT_LIST_HEAD(&tcon->pending_opens); spin_lock(&cifs_tcp_ses_lock); @@ -3484,7 +3484,7 @@ int cifs_match_super(struct super_block *sb, void *data) { struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data; - struct smb_vol *volume_info; + struct smb3_fs_context *ctx; struct cifs_sb_info *cifs_sb; struct TCP_Server_Info *tcp_srv; struct cifs_ses *ses; @@ -3503,11 +3503,11 @@ cifs_match_super(struct super_block *sb, void *data) ses = tcon->ses; tcp_srv = ses->server; - volume_info = mnt_data->vol; + ctx = mnt_data->ctx; - if (!match_server(tcp_srv, volume_info) || - !match_session(ses, volume_info) || - !match_tcon(tcon, volume_info) || + if (!match_server(tcp_srv, ctx) || + !match_session(ses, ctx) || + !match_tcon(tcon, ctx) || !match_prepath(sb, mnt_data)) { rc = 0; goto out; @@ -3792,7 +3792,7 @@ ip_connect(struct TCP_Server_Info *server) } void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, - struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info) + struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) { /* if we are reconnecting then should we check to see if * any requested capabilities changed locally e.g. via @@ -3805,12 +3805,12 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, * and once without posixacls or posix paths? */ __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); - if (vol_info && vol_info->no_linux_ext) { + if (ctx && ctx->no_linux_ext) { tcon->fsUnixInfo.Capability = 0; tcon->unix_ext = 0; /* Unix Extensions disabled */ cifs_dbg(FYI, "Linux protocol extensions disabled\n"); return; - } else if (vol_info) + } else if (ctx) tcon->unix_ext = 1; /* Unix Extensions supported */ if (tcon->unix_ext == 0) { @@ -3823,7 +3823,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, cifs_dbg(FYI, "unix caps which server supports %lld\n", cap); /* check for reconnect case in which we do not want to change the mount behavior if we can avoid it */ - if (vol_info == NULL) { + if (ctx == NULL) { /* turn off POSIX ACL and PATHNAMES if not set originally at mount time */ if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) @@ -3842,7 +3842,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, cifs_dbg(VFS, "per-share encryption not supported yet\n"); cap &= CIFS_UNIX_CAP_MASK; - if (vol_info && vol_info->no_psx_acl) + if (ctx && ctx->no_psx_acl) cap &= ~CIFS_UNIX_POSIX_ACL_CAP; else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { cifs_dbg(FYI, "negotiated posix acl support\n"); @@ -3851,7 +3851,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, CIFS_MOUNT_POSIXACL; } - if (vol_info && vol_info->posix_paths == 0) + if (ctx && ctx->posix_paths == 0) cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { cifs_dbg(FYI, "negotiate posix pathnames\n"); @@ -3882,16 +3882,16 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, cifs_dbg(FYI, "mandatory transport encryption cap\n"); #endif /* CIFS_DEBUG2 */ if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { - if (vol_info == NULL) { + if (ctx == NULL) cifs_dbg(FYI, "resetting capabilities failed\n"); - } else + else 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"); } } } -int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, +int cifs_setup_cifs_sb(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb) { INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); @@ -3899,91 +3899,91 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, spin_lock_init(&cifs_sb->tlink_tree_lock); cifs_sb->tlink_tree = RB_ROOT; - cifs_sb->bsize = pvolume_info->bsize; + cifs_sb->bsize = ctx->bsize; /* * Temporarily set r/wsize for matching superblock. If we end up using * new sb then client will later negotiate it downward if needed. */ - cifs_sb->rsize = pvolume_info->rsize; - cifs_sb->wsize = pvolume_info->wsize; + cifs_sb->rsize = ctx->rsize; + cifs_sb->wsize = ctx->wsize; - cifs_sb->mnt_uid = pvolume_info->linux_uid; - cifs_sb->mnt_gid = pvolume_info->linux_gid; - cifs_sb->mnt_file_mode = pvolume_info->file_mode; - cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; + cifs_sb->mnt_uid = ctx->linux_uid; + cifs_sb->mnt_gid = ctx->linux_gid; + cifs_sb->mnt_file_mode = ctx->file_mode; + cifs_sb->mnt_dir_mode = ctx->dir_mode; cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n", cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); - cifs_sb->actimeo = pvolume_info->actimeo; - cifs_sb->local_nls = pvolume_info->local_nls; + cifs_sb->actimeo = ctx->actimeo; + cifs_sb->local_nls = ctx->local_nls; - if (pvolume_info->nodfs) + if (ctx->nodfs) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS; - if (pvolume_info->noperm) + if (ctx->noperm) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; - if (pvolume_info->setuids) + if (ctx->setuids) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; - if (pvolume_info->setuidfromacl) + if (ctx->setuidfromacl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL; - if (pvolume_info->server_ino) + if (ctx->server_ino) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; - if (pvolume_info->remap) + if (ctx->remap) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR; - if (pvolume_info->sfu_remap) + if (ctx->sfu_remap) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; - if (pvolume_info->no_xattr) + if (ctx->no_xattr) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; - if (pvolume_info->sfu_emul) + if (ctx->sfu_emul) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; - if (pvolume_info->nobrl) + if (ctx->nobrl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; - if (pvolume_info->nohandlecache) + if (ctx->nohandlecache) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE; - if (pvolume_info->nostrictsync) + if (ctx->nostrictsync) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; - if (pvolume_info->mand_lock) + if (ctx->mand_lock) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; - if (pvolume_info->rwpidforward) + if (ctx->rwpidforward) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; - if (pvolume_info->mode_ace) + if (ctx->mode_ace) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID; - if (pvolume_info->cifs_acl) + if (ctx->cifs_acl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; - if (pvolume_info->backupuid_specified) { + if (ctx->backupuid_specified) { cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; - cifs_sb->mnt_backupuid = pvolume_info->backupuid; + cifs_sb->mnt_backupuid = ctx->backupuid; } - if (pvolume_info->backupgid_specified) { + if (ctx->backupgid_specified) { cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; - cifs_sb->mnt_backupgid = pvolume_info->backupgid; + cifs_sb->mnt_backupgid = ctx->backupgid; } - if (pvolume_info->override_uid) + if (ctx->override_uid) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; - if (pvolume_info->override_gid) + if (ctx->override_gid) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; - if (pvolume_info->dynperm) + if (ctx->dynperm) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; - if (pvolume_info->fsc) + if (ctx->fsc) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; - if (pvolume_info->multiuser) + if (ctx->multiuser) cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_NO_PERM); - if (pvolume_info->strict_io) + if (ctx->strict_io) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; - if (pvolume_info->direct_io) { + if (ctx->direct_io) { cifs_dbg(FYI, "mounting share using direct i/o\n"); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; } - if (pvolume_info->cache_ro) { + if (ctx->cache_ro) { cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; - } else if (pvolume_info->cache_rw) { + } else if (ctx->cache_rw) { cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n"); cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE); } - if (pvolume_info->mfsymlinks) { - if (pvolume_info->sfu_emul) { + if (ctx->mfsymlinks) { + if (ctx->sfu_emul) { /* * Our SFU ("Services for Unix" emulation does not allow * creating symlinks but does allow reading existing SFU @@ -4000,11 +4000,11 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; } - if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm)) + if ((ctx->cifs_acl) && (ctx->dynperm)) cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n"); - if (pvolume_info->prepath) { - cifs_sb->prepath = kstrdup(pvolume_info->prepath, GFP_KERNEL); + if (ctx->prepath) { + cifs_sb->prepath = kstrdup(ctx->prepath, GFP_KERNEL); if (cifs_sb->prepath == NULL) return -ENOMEM; } @@ -4013,23 +4013,23 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, } void -cifs_cleanup_volume_info_contents(struct smb_vol *volume_info) +cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx) { - kfree(volume_info->username); - kfree_sensitive(volume_info->password); - kfree(volume_info->UNC); - kfree(volume_info->domainname); - kfree(volume_info->iocharset); - kfree(volume_info->prepath); + kfree(ctx->username); + kfree_sensitive(ctx->password); + kfree(ctx->UNC); + kfree(ctx->domainname); + kfree(ctx->iocharset); + kfree(ctx->prepath); } void -cifs_cleanup_volume_info(struct smb_vol *volume_info) +cifs_cleanup_volume_info(struct smb3_fs_context *ctx) { - if (!volume_info) + if (!ctx) return; - cifs_cleanup_volume_info_contents(volume_info); - kfree(volume_info); + cifs_cleanup_volume_info_contents(ctx); + kfree(ctx); } /* Release all succeed connections */ @@ -4051,7 +4051,7 @@ static inline void mount_put_conns(struct cifs_sb_info *cifs_sb, } /* Get connections for tcp, ses and tcon */ -static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, +static int mount_get_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb, unsigned int *xid, struct TCP_Server_Info **nserver, struct cifs_ses **nses, struct cifs_tcon **ntcon) @@ -4068,7 +4068,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, *xid = get_xid(); /* get a reference to a tcp session */ - server = cifs_get_tcp_session(vol); + server = cifs_get_tcp_session(ctx); if (IS_ERR(server)) { rc = PTR_ERR(server); return rc; @@ -4076,13 +4076,13 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, *nserver = server; - if ((vol->max_credits < 20) || (vol->max_credits > 60000)) + if ((ctx->max_credits < 20) || (ctx->max_credits > 60000)) server->max_credits = SMB2_MAX_CREDITS_AVAILABLE; else - server->max_credits = vol->max_credits; + server->max_credits = ctx->max_credits; /* get a reference to a SMB session */ - ses = cifs_get_smb_ses(server, vol); + ses = cifs_get_smb_ses(server, ctx); if (IS_ERR(ses)) { rc = PTR_ERR(ses); return rc; @@ -4090,14 +4090,14 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, *nses = ses; - if ((vol->persistent == true) && (!(ses->server->capabilities & + if ((ctx->persistent == true) && (!(ses->server->capabilities & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) { cifs_server_dbg(VFS, "persistent handles not supported by server\n"); return -EOPNOTSUPP; } /* search for existing tcon to this server share */ - tcon = cifs_get_tcon(ses, vol); + tcon = cifs_get_tcon(ses, ctx); if (IS_ERR(tcon)) { rc = PTR_ERR(tcon); return rc; @@ -4115,7 +4115,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, * reset of caps checks mount to see if unix extensions disabled * for just this mount. */ - reset_cifs_unix_caps(*xid, tcon, cifs_sb, vol); + reset_cifs_unix_caps(*xid, tcon, cifs_sb, ctx); if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && (le64_to_cpu(tcon->fsUnixInfo.Capability) & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) @@ -4137,8 +4137,8 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, } } - cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol); - cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol); + cifs_sb->wsize = server->ops->negotiate_wsize(tcon, ctx); + cifs_sb->rsize = server->ops->negotiate_rsize(tcon, ctx); return 0; } @@ -4175,13 +4175,13 @@ static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, * exiting connection (tcon) */ static char * -build_unc_path_to_root(const struct smb_vol *vol, +build_unc_path_to_root(const struct smb3_fs_context *ctx, const struct cifs_sb_info *cifs_sb, bool useppath) { char *full_path, *pos; - unsigned int pplen = useppath && vol->prepath ? - strlen(vol->prepath) + 1 : 0; - unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); + unsigned int pplen = useppath && ctx->prepath ? + strlen(ctx->prepath) + 1 : 0; + unsigned int unc_len = strnlen(ctx->UNC, MAX_TREE_SIZE + 1); if (unc_len > MAX_TREE_SIZE) return ERR_PTR(-EINVAL); @@ -4190,12 +4190,12 @@ build_unc_path_to_root(const struct smb_vol *vol, if (full_path == NULL) return ERR_PTR(-ENOMEM); - memcpy(full_path, vol->UNC, unc_len); + memcpy(full_path, ctx->UNC, unc_len); pos = full_path + unc_len; if (pplen) { *pos = CIFS_DIR_SEP(cifs_sb); - memcpy(pos + 1, vol->prepath, pplen); + memcpy(pos + 1, ctx->prepath, pplen); pos += pplen; } @@ -4218,7 +4218,7 @@ build_unc_path_to_root(const struct smb_vol *vol, */ static int expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses, - struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb, + struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb, char *ref_path) { int rc; @@ -4228,7 +4228,7 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) return -EREMOTE; - full_path = build_unc_path_to_root(volume_info, cifs_sb, true); + full_path = build_unc_path_to_root(ctx, cifs_sb, true); if (IS_ERR(full_path)) return PTR_ERR(full_path); @@ -4246,8 +4246,8 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses, rc = PTR_ERR(mdata); mdata = NULL; } else { - cifs_cleanup_volume_info_contents(volume_info); - rc = cifs_setup_volume_info(volume_info, mdata, + cifs_cleanup_volume_info_contents(ctx); + rc = cifs_setup_volume_info(ctx, mdata, fake_devname, false); } kfree(fake_devname); @@ -4270,7 +4270,7 @@ static inline int get_next_dfs_tgt(const char *path, } static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it, - struct smb_vol *fake_vol, struct smb_vol *vol) + struct smb3_fs_context *fake_ctx, struct smb3_fs_context *ctx) { const char *tgt = dfs_cache_get_tgt_name(tgt_it); int len = strlen(tgt) + 2; @@ -4281,29 +4281,29 @@ static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it, return -ENOMEM; scnprintf(new_unc, len, "\\%s", tgt); - kfree(vol->UNC); - vol->UNC = new_unc; + kfree(ctx->UNC); + ctx->UNC = new_unc; - if (fake_vol->prepath) { - kfree(vol->prepath); - vol->prepath = fake_vol->prepath; - fake_vol->prepath = NULL; + if (fake_ctx->prepath) { + kfree(ctx->prepath); + ctx->prepath = fake_ctx->prepath; + fake_ctx->prepath = NULL; } - memcpy(&vol->dstaddr, &fake_vol->dstaddr, sizeof(vol->dstaddr)); + memcpy(&ctx->dstaddr, &fake_ctx->dstaddr, sizeof(ctx->dstaddr)); return 0; } static int setup_dfs_tgt_conn(const char *path, const char *full_path, const struct dfs_cache_tgt_iterator *tgt_it, - struct cifs_sb_info *cifs_sb, struct smb_vol *vol, unsigned int *xid, - struct TCP_Server_Info **server, struct cifs_ses **ses, - struct cifs_tcon **tcon) + struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx, + unsigned int *xid, struct TCP_Server_Info **server, + struct cifs_ses **ses, struct cifs_tcon **tcon) { int rc; struct dfs_info3_param ref = {0}; char *mdata = NULL, *fake_devname = NULL; - struct smb_vol fake_vol = {NULL}; + struct smb3_fs_context fake_ctx = {NULL}; cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path); @@ -4319,37 +4319,37 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path, mdata = NULL; } else { cifs_dbg(FYI, "%s: fake_devname: %s\n", __func__, fake_devname); - rc = cifs_setup_volume_info(&fake_vol, mdata, fake_devname, - false); + rc = cifs_setup_volume_info((struct smb3_fs_context *)&fake_ctx, + mdata, fake_devname, false); } kfree(mdata); kfree(fake_devname); if (!rc) { /* - * We use a 'fake_vol' here because we need pass it down to the + * We use a 'fake_ctx' here because we need pass it down to the * mount_{get,put} functions to test connection against new DFS * targets. */ mount_put_conns(cifs_sb, *xid, *server, *ses, *tcon); - rc = mount_get_conns(&fake_vol, cifs_sb, xid, server, ses, + rc = mount_get_conns(&fake_ctx, cifs_sb, xid, server, ses, tcon); if (!rc || (*server && *ses)) { /* * We were able to connect to new target server. - * Update current volume info with new target server. + * Update current context with new target server. */ - rc = update_vol_info(tgt_it, &fake_vol, vol); + rc = update_vol_info(tgt_it, &fake_ctx, ctx); } } - cifs_cleanup_volume_info_contents(&fake_vol); + cifs_cleanup_volume_info_contents((struct smb3_fs_context *)&fake_ctx); return rc; } static int do_dfs_failover(const char *path, const char *full_path, struct cifs_sb_info *cifs_sb, - struct smb_vol *vol, struct cifs_ses *root_ses, unsigned int *xid, - struct TCP_Server_Info **server, struct cifs_ses **ses, - struct cifs_tcon **tcon) + struct smb3_fs_context *ctx, struct cifs_ses *root_ses, + unsigned int *xid, struct TCP_Server_Info **server, + struct cifs_ses **ses, struct cifs_tcon **tcon) { int rc; struct dfs_cache_tgt_list tgt_list; @@ -4368,7 +4368,7 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ if (rc) break; /* Connect to next DFS target */ - rc = setup_dfs_tgt_conn(path, full_path, tgt_it, cifs_sb, vol, xid, server, ses, + rc = setup_dfs_tgt_conn(path, full_path, tgt_it, cifs_sb, ctx, xid, server, ses, tcon); if (!rc || (*server && *ses)) break; @@ -4389,21 +4389,21 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ #endif int -cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, +cifs_setup_volume_info(struct smb3_fs_context *ctx, char *mount_data, const char *devname, bool is_smb3) { int rc = 0; - if (cifs_parse_mount_options(mount_data, devname, volume_info, is_smb3)) + if (cifs_parse_mount_options(mount_data, devname, ctx, is_smb3)) return -EINVAL; - if (volume_info->nullauth) { + if (ctx->nullauth) { cifs_dbg(FYI, "Anonymous login\n"); - kfree(volume_info->username); - volume_info->username = NULL; - } else if (volume_info->username) { + kfree(ctx->username); + ctx->username = NULL; + } else if (ctx->username) { /* BB fixme parse for domain name here */ - cifs_dbg(FYI, "Username: %s\n", volume_info->username); + cifs_dbg(FYI, "Username: %s\n", ctx->username); } else { cifs_dbg(VFS, "No username specified\n"); /* In userspace mount helper we can get user name from alternate @@ -4412,14 +4412,14 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, } /* this is needed for ASCII cp to Unicode converts */ - if (volume_info->iocharset == NULL) { + if (ctx->iocharset == NULL) { /* load_nls_default cannot return null */ - volume_info->local_nls = load_nls_default(); + ctx->local_nls = load_nls_default(); } else { - volume_info->local_nls = load_nls(volume_info->iocharset); - if (volume_info->local_nls == NULL) { + ctx->local_nls = load_nls(ctx->iocharset); + if (ctx->local_nls == NULL) { cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n", - volume_info->iocharset); + ctx->iocharset); return -ELIBACC; } } @@ -4427,23 +4427,23 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, return rc; } -struct smb_vol * +struct smb3_fs_context * cifs_get_volume_info(char *mount_data, const char *devname, bool is_smb3) { int rc; - struct smb_vol *volume_info; + struct smb3_fs_context *ctx; - volume_info = kmalloc(sizeof(struct smb_vol), GFP_KERNEL); - if (!volume_info) + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) return ERR_PTR(-ENOMEM); - rc = cifs_setup_volume_info(volume_info, mount_data, devname, is_smb3); + rc = cifs_setup_volume_info(ctx, mount_data, devname, is_smb3); if (rc) { - cifs_cleanup_volume_info(volume_info); - volume_info = ERR_PTR(rc); + cifs_cleanup_volume_info(ctx); + ctx = ERR_PTR(rc); } - return volume_info; + return ctx; } static int @@ -4497,7 +4497,7 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is, * otherwise 0. */ -static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, +static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx, const unsigned int xid, struct TCP_Server_Info *server, struct cifs_tcon *tcon) @@ -4511,7 +4511,7 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, /* * cifs_build_path_to_root works only when we have a valid tcon */ - full_path = cifs_build_path_to_root(vol, cifs_sb, tcon, + full_path = cifs_build_path_to_root(ctx, cifs_sb, tcon, tcon->Flags & SMB_SHARE_IS_IN_DFS); if (full_path == NULL) return -ENOMEM; @@ -4560,7 +4560,7 @@ static void put_root_ses(struct cifs_ses *ses) } /* Check if a path component is remote and then update @dfs_path accordingly */ -static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, +static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx, const unsigned int xid, struct TCP_Server_Info *server, struct cifs_tcon *tcon, char **dfs_path) { @@ -4571,7 +4571,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, int added_treename = tcon->Flags & SMB_SHARE_IS_IN_DFS; int skip = added_treename; - path = cifs_build_path_to_root(vol, cifs_sb, tcon, added_treename); + path = cifs_build_path_to_root(ctx, cifs_sb, tcon, added_treename); if (!path) return -ENOMEM; @@ -4602,7 +4602,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, *s = 0; rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, path); if (rc && rc == -EREMOTE) { - struct smb_vol v = {NULL}; + struct smb3_fs_context v = {NULL}; /* if @path contains a tree name, skip it in the prefix path */ if (added_treename) { rc = cifs_parse_devname(path, &v); @@ -4612,7 +4612,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, npath = build_unc_path_to_root(&v, cifs_sb, true); cifs_cleanup_volume_info_contents(&v); } else { - v.UNC = vol->UNC; + v.UNC = ctx->UNC; v.prepath = path + 1; npath = build_unc_path_to_root(&v, cifs_sb, true); } @@ -4630,7 +4630,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, return rc; } -int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) +int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) { int rc = 0; unsigned int xid; @@ -4642,7 +4642,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) char *oldmnt = NULL; char *mntdata = NULL; - rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); + rc = mount_get_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon); /* * Unconditionally try to get an DFS referral (even cached) to determine whether it is an * DFS mount. @@ -4650,13 +4650,13 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) * Skip prefix path to provide support for DFS referrals from w2k8 servers which don't seem * to respond with PATH_NOT_COVERED to requests that include the prefix. */ - if (dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), vol->UNC + 1, NULL, + if (dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), ctx->UNC + 1, NULL, NULL)) { /* No DFS referral was returned. Looks like a regular share. */ if (rc) goto error; /* Check if it is fully accessible and then mount it */ - rc = is_path_remote(cifs_sb, vol, xid, server, tcon); + rc = is_path_remote(cifs_sb, ctx, xid, server, tcon); if (!rc) goto out; if (rc != -EREMOTE) @@ -4669,7 +4669,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) goto error; } /* Get path of DFS root */ - ref_path = build_unc_path_to_root(vol, cifs_sb, false); + ref_path = build_unc_path_to_root(ctx, cifs_sb, false); if (IS_ERR(ref_path)) { rc = PTR_ERR(ref_path); ref_path = NULL; @@ -4680,7 +4680,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) do { /* Save full path of last DFS path we used to resolve final target server */ kfree(full_path); - full_path = build_unc_path_to_root(vol, cifs_sb, !!count); + full_path = build_unc_path_to_root(ctx, cifs_sb, !!count); if (IS_ERR(full_path)) { rc = PTR_ERR(full_path); full_path = NULL; @@ -4688,17 +4688,17 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) } /* Chase referral */ oldmnt = cifs_sb->mountdata; - rc = expand_dfs_referral(xid, root_ses, vol, cifs_sb, ref_path + 1); + rc = expand_dfs_referral(xid, root_ses, ctx, cifs_sb, ref_path + 1); if (rc) break; /* Connect to new DFS target only if we were redirected */ if (oldmnt != cifs_sb->mountdata) { mount_put_conns(cifs_sb, xid, server, ses, tcon); - rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); + rc = mount_get_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon); } if (rc && !server && !ses) { /* Failed to connect. Try to connect to other targets in the referral. */ - rc = do_dfs_failover(ref_path + 1, full_path, cifs_sb, vol, root_ses, &xid, + rc = do_dfs_failover(ref_path + 1, full_path, cifs_sb, ctx, root_ses, &xid, &server, &ses, &tcon); } if (rc == -EACCES || rc == -EOPNOTSUPP || !server || !ses) @@ -4711,7 +4711,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) set_root_ses(cifs_sb, ses, &root_ses); } /* Check for remaining path components and then continue chasing them (-EREMOTE) */ - rc = check_dfs_prepath(cifs_sb, vol, xid, server, tcon, &ref_path); + rc = check_dfs_prepath(cifs_sb, ctx, xid, server, tcon, &ref_path); /* Prevent recursion on broken link referrals */ if (rc == -EREMOTE && ++count > MAX_NESTED_LINKS) rc = -ELOOP; @@ -4742,8 +4742,8 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) tcon->remap = cifs_remap(cifs_sb); spin_unlock(&cifs_tcp_ses_lock); - /* Add original volume information for DFS cache to be used when refreshing referrals */ - rc = dfs_cache_add_vol(mntdata, vol, cifs_sb->origin_fullpath); + /* Add original context for DFS cache to be used when refreshing referrals */ + rc = dfs_cache_add_vol(mntdata, ctx, cifs_sb->origin_fullpath); if (rc) goto error; /* @@ -4758,8 +4758,8 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) */ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; kfree(cifs_sb->prepath); - cifs_sb->prepath = vol->prepath; - vol->prepath = NULL; + cifs_sb->prepath = ctx->prepath; + ctx->prepath = NULL; out: free_xid(xid); @@ -4776,7 +4776,7 @@ error: return rc; } #else -int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) +int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) { int rc = 0; unsigned int xid; @@ -4784,12 +4784,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) struct cifs_tcon *tcon; struct TCP_Server_Info *server; - rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, &tcon); + rc = mount_get_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon); if (rc) goto error; if (tcon) { - rc = is_path_remote(cifs_sb, vol, xid, server, tcon); + rc = is_path_remote(cifs_sb, ctx, xid, server, tcon); if (rc == -EREMOTE) rc = -EOPNOTSUPP; if (rc) @@ -5066,15 +5066,15 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, } static int -cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) +cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses) { - vol->sectype = ses->sectype; + ctx->sectype = ses->sectype; /* krb5 is special, since we don't need username or pw */ - if (vol->sectype == Kerberos) + if (ctx->sectype == Kerberos) return 0; - return cifs_set_cifscreds(vol, ses); + return cifs_set_cifscreds(ctx, ses); } static struct cifs_tcon * @@ -5084,31 +5084,31 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb); struct cifs_ses *ses; struct cifs_tcon *tcon = NULL; - struct smb_vol *vol_info; + struct smb3_fs_context *ctx; - vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL); - if (vol_info == NULL) + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (ctx == NULL) return ERR_PTR(-ENOMEM); - vol_info->local_nls = cifs_sb->local_nls; - vol_info->linux_uid = fsuid; - vol_info->cred_uid = fsuid; - vol_info->UNC = master_tcon->treeName; - vol_info->retry = master_tcon->retry; - vol_info->nocase = master_tcon->nocase; - vol_info->nohandlecache = master_tcon->nohandlecache; - vol_info->local_lease = master_tcon->local_lease; - vol_info->no_lease = master_tcon->no_lease; - vol_info->resilient = master_tcon->use_resilient; - vol_info->persistent = master_tcon->use_persistent; - vol_info->handle_timeout = master_tcon->handle_timeout; - vol_info->no_linux_ext = !master_tcon->unix_ext; - vol_info->linux_ext = master_tcon->posix_extensions; - vol_info->sectype = master_tcon->ses->sectype; - vol_info->sign = master_tcon->ses->sign; - vol_info->seal = master_tcon->seal; - - rc = cifs_set_vol_auth(vol_info, master_tcon->ses); + ctx->local_nls = cifs_sb->local_nls; + ctx->linux_uid = fsuid; + ctx->cred_uid = fsuid; + ctx->UNC = master_tcon->treeName; + ctx->retry = master_tcon->retry; + ctx->nocase = master_tcon->nocase; + ctx->nohandlecache = master_tcon->nohandlecache; + ctx->local_lease = master_tcon->local_lease; + ctx->no_lease = master_tcon->no_lease; + ctx->resilient = master_tcon->use_resilient; + ctx->persistent = master_tcon->use_persistent; + ctx->handle_timeout = master_tcon->handle_timeout; + ctx->no_linux_ext = !master_tcon->unix_ext; + ctx->linux_ext = master_tcon->posix_extensions; + ctx->sectype = master_tcon->ses->sectype; + ctx->sign = master_tcon->ses->sign; + ctx->seal = master_tcon->seal; + + rc = cifs_set_vol_auth(ctx, master_tcon->ses); if (rc) { tcon = ERR_PTR(rc); goto out; @@ -5119,26 +5119,26 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) ++master_tcon->ses->server->srv_count; spin_unlock(&cifs_tcp_ses_lock); - ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); + ses = cifs_get_smb_ses(master_tcon->ses->server, ctx); if (IS_ERR(ses)) { tcon = (struct cifs_tcon *)ses; cifs_put_tcp_session(master_tcon->ses->server, 0); goto out; } - tcon = cifs_get_tcon(ses, vol_info); + tcon = cifs_get_tcon(ses, ctx); if (IS_ERR(tcon)) { cifs_put_smb_ses(ses); goto out; } if (cap_unix(ses)) - reset_cifs_unix_caps(0, tcon, NULL, vol_info); + reset_cifs_unix_caps(0, tcon, NULL, ctx); out: - kfree(vol_info->username); - kfree_sensitive(vol_info->password); - kfree(vol_info); + kfree(ctx->username); + kfree_sensitive(ctx->password); + kfree(ctx); return tcon; } diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 6ee849698962..3860241dcc03 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -20,6 +20,7 @@ #include "smb2glob.h" #include "dfs_cache.h" +#include "fs_context.h" #define CACHE_HTABLE_SIZE 32 #define CACHE_MAX_ENTRIES 64 @@ -48,8 +49,8 @@ struct cache_entry { struct vol_info { char *fullpath; - spinlock_t smb_vol_lock; - struct smb_vol smb_vol; + spinlock_t ctx_lock; + struct smb3_fs_context ctx; char *mntdata; struct list_head list; struct list_head rlist; @@ -586,7 +587,7 @@ static void __vol_release(struct vol_info *vi) { kfree(vi->fullpath); kfree(vi->mntdata); - cifs_cleanup_volume_info_contents(&vi->smb_vol); + cifs_cleanup_volume_info_contents(&vi->ctx); kfree(vi); } @@ -1140,43 +1141,43 @@ out_unlock: return rc; } -static int dup_vol(struct smb_vol *vol, struct smb_vol *new) +static int dup_vol(struct smb3_fs_context *ctx, struct smb3_fs_context *new) { - memcpy(new, vol, sizeof(*new)); + memcpy(new, ctx, sizeof(*new)); - if (vol->username) { - new->username = kstrndup(vol->username, strlen(vol->username), + if (ctx->username) { + new->username = kstrndup(ctx->username, strlen(ctx->username), GFP_KERNEL); if (!new->username) return -ENOMEM; } - if (vol->password) { - new->password = kstrndup(vol->password, strlen(vol->password), + if (ctx->password) { + new->password = kstrndup(ctx->password, strlen(ctx->password), GFP_KERNEL); if (!new->password) goto err_free_username; } - if (vol->UNC) { - cifs_dbg(FYI, "%s: vol->UNC: %s\n", __func__, vol->UNC); - new->UNC = kstrndup(vol->UNC, strlen(vol->UNC), GFP_KERNEL); + if (ctx->UNC) { + cifs_dbg(FYI, "%s: ctx->UNC: %s\n", __func__, ctx->UNC); + new->UNC = kstrndup(ctx->UNC, strlen(ctx->UNC), GFP_KERNEL); if (!new->UNC) goto err_free_password; } - if (vol->domainname) { - new->domainname = kstrndup(vol->domainname, - strlen(vol->domainname), GFP_KERNEL); + if (ctx->domainname) { + new->domainname = kstrndup(ctx->domainname, + strlen(ctx->domainname), GFP_KERNEL); if (!new->domainname) goto err_free_unc; } - if (vol->iocharset) { - new->iocharset = kstrndup(vol->iocharset, - strlen(vol->iocharset), GFP_KERNEL); + if (ctx->iocharset) { + new->iocharset = kstrndup(ctx->iocharset, + strlen(ctx->iocharset), GFP_KERNEL); if (!new->iocharset) goto err_free_domainname; } - if (vol->prepath) { - cifs_dbg(FYI, "%s: vol->prepath: %s\n", __func__, vol->prepath); - new->prepath = kstrndup(vol->prepath, strlen(vol->prepath), + if (ctx->prepath) { + cifs_dbg(FYI, "%s: ctx->prepath: %s\n", __func__, ctx->prepath); + new->prepath = kstrndup(ctx->prepath, strlen(ctx->prepath), GFP_KERNEL); if (!new->prepath) goto err_free_iocharset; @@ -1203,17 +1204,17 @@ err_free_username: * DFS cache refresh worker. * * @mntdata: mount data. - * @vol: cifs volume. + * @ctx: cifs context. * @fullpath: origin full path. * * Return zero if volume was set up correctly, otherwise non-zero. */ -int dfs_cache_add_vol(char *mntdata, struct smb_vol *vol, const char *fullpath) +int dfs_cache_add_vol(char *mntdata, struct smb3_fs_context *ctx, const char *fullpath) { int rc; struct vol_info *vi; - if (!vol || !fullpath || !mntdata) + if (!ctx || !fullpath || !mntdata) return -EINVAL; cifs_dbg(FYI, "%s: fullpath: %s\n", __func__, fullpath); @@ -1228,12 +1229,12 @@ int dfs_cache_add_vol(char *mntdata, struct smb_vol *vol, const char *fullpath) goto err_free_vi; } - rc = dup_vol(vol, &vi->smb_vol); + rc = dup_vol(ctx, &vi->ctx); if (rc) goto err_free_fullpath; vi->mntdata = mntdata; - spin_lock_init(&vi->smb_vol_lock); + spin_lock_init(&vi->ctx_lock); kref_init(&vi->refcnt); spin_lock(&vol_list_lock); @@ -1289,10 +1290,10 @@ int dfs_cache_update_vol(const char *fullpath, struct TCP_Server_Info *server) spin_unlock(&vol_list_lock); cifs_dbg(FYI, "%s: updating volume info\n", __func__); - spin_lock(&vi->smb_vol_lock); - memcpy(&vi->smb_vol.dstaddr, &server->dstaddr, - sizeof(vi->smb_vol.dstaddr)); - spin_unlock(&vi->smb_vol_lock); + spin_lock(&vi->ctx_lock); + memcpy(&vi->ctx.dstaddr, &server->dstaddr, + sizeof(vi->ctx.dstaddr)); + spin_unlock(&vi->ctx_lock); kref_put(&vi->refcnt, vol_release); @@ -1445,11 +1446,11 @@ static inline void put_tcp_server(struct TCP_Server_Info *server) cifs_put_tcp_session(server, 0); } -static struct TCP_Server_Info *get_tcp_server(struct smb_vol *vol) +static struct TCP_Server_Info *get_tcp_server(struct smb3_fs_context *ctx) { struct TCP_Server_Info *server; - server = cifs_find_tcp_session(vol); + server = cifs_find_tcp_session(ctx); if (IS_ERR_OR_NULL(server)) return NULL; @@ -1476,7 +1477,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, char *mdata = NULL, *devname = NULL; struct TCP_Server_Info *server; struct cifs_ses *ses; - struct smb_vol vol = {NULL}; + struct smb3_fs_context ctx = {NULL}; rpath = get_dfs_root(path); if (IS_ERR(rpath)) @@ -1510,7 +1511,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, goto out; } - rc = cifs_setup_volume_info(&vol, mdata, devname, false); + rc = cifs_setup_volume_info(&ctx, mdata, devname, false); kfree(devname); if (rc) { @@ -1518,16 +1519,16 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi, goto out; } - server = get_tcp_server(&vol); + server = get_tcp_server(&ctx); if (!server) { ses = ERR_PTR(-EHOSTDOWN); goto out; } - ses = cifs_get_smb_ses(server, &vol); + ses = cifs_get_smb_ses(server, &ctx); out: - cifs_cleanup_volume_info_contents(&vol); + cifs_cleanup_volume_info_contents(&ctx); kfree(mdata); kfree(rpath); @@ -1619,7 +1620,7 @@ static void refresh_cache_worker(struct work_struct *work) */ spin_lock(&vol_list_lock); list_for_each_entry(vi, &vol_list, list) { - server = get_tcp_server(&vi->smb_vol); + server = get_tcp_server(&vi->ctx); if (!server) continue; @@ -1631,9 +1632,9 @@ static void refresh_cache_worker(struct work_struct *work) /* Walk through all TCONs and refresh any expired cache entry */ list_for_each_entry_safe(vi, nvi, &vols, rlist) { - spin_lock(&vi->smb_vol_lock); - server = get_tcp_server(&vi->smb_vol); - spin_unlock(&vi->smb_vol_lock); + spin_lock(&vi->ctx_lock); + server = get_tcp_server(&vi->ctx); + spin_unlock(&vi->ctx_lock); if (!server) goto next_vol; diff --git a/fs/cifs/dfs_cache.h b/fs/cifs/dfs_cache.h index 3d7c05194536..1afc4f590c47 100644 --- a/fs/cifs/dfs_cache.h +++ b/fs/cifs/dfs_cache.h @@ -44,7 +44,7 @@ dfs_cache_noreq_update_tgthint(const char *path, extern int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iterator *it, struct dfs_info3_param *ref); -extern int dfs_cache_add_vol(char *mntdata, struct smb_vol *vol, +extern int dfs_cache_add_vol(char *mntdata, struct smb3_fs_context *ctx, const char *fullpath); extern int dfs_cache_update_vol(const char *fullpath, struct TCP_Server_Info *server); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 398c1eef7190..68900f1629bf 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -33,6 +33,7 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" #include "cifs_unicode.h" +#include "fs_context.h" static void renew_parental_timestamps(struct dentry *direntry) @@ -46,10 +47,10 @@ renew_parental_timestamps(struct dentry *direntry) } char * -cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, +cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, int add_treename) { - int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0; + int pplen = ctx->prepath ? strlen(ctx->prepath) + 1 : 0; int dfsplen; char *full_path = NULL; @@ -71,7 +72,7 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, if (dfsplen) memcpy(full_path, tcon->treeName, dfsplen); full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb); - memcpy(full_path + dfsplen + 1, vol->prepath, pplen); + memcpy(full_path + dfsplen + 1, ctx->prepath, pplen); convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); return full_path; } diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index ad6c2fed4055..3d071c87353e 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -25,7 +25,7 @@ static const match_table_t cifs_smb_version_tokens = { }; int -cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3) +cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3) { substring_t args[MAX_OPT_ARGS]; @@ -41,8 +41,8 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3) return 1; } cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n"); - vol->ops = &smb1_operations; - vol->vals = &smb1_values; + ctx->ops = &smb1_operations; + ctx->vals = &smb1_values; break; case Smb_20: if (disable_legacy_dialects) { @@ -53,8 +53,8 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3) cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n"); return 1; } - vol->ops = &smb20_operations; - vol->vals = &smb20_values; + ctx->ops = &smb20_operations; + ctx->vals = &smb20_values; break; #else case Smb_1: @@ -65,28 +65,28 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3) return 1; #endif /* CIFS_ALLOW_INSECURE_LEGACY */ case Smb_21: - vol->ops = &smb21_operations; - vol->vals = &smb21_values; + ctx->ops = &smb21_operations; + ctx->vals = &smb21_values; break; case Smb_30: - vol->ops = &smb30_operations; - vol->vals = &smb30_values; + ctx->ops = &smb30_operations; + ctx->vals = &smb30_values; break; case Smb_302: - vol->ops = &smb30_operations; /* currently identical with 3.0 */ - vol->vals = &smb302_values; + ctx->ops = &smb30_operations; /* currently identical with 3.0 */ + ctx->vals = &smb302_values; break; case Smb_311: - vol->ops = &smb311_operations; - vol->vals = &smb311_values; + ctx->ops = &smb311_operations; + ctx->vals = &smb311_values; break; case Smb_3any: - vol->ops = &smb30_operations; /* currently identical with 3.0 */ - vol->vals = &smb3any_values; + ctx->ops = &smb30_operations; /* currently identical with 3.0 */ + ctx->vals = &smb3any_values; break; case Smb_default: - vol->ops = &smb30_operations; /* currently identical with 3.0 */ - vol->vals = &smbdefault_values; + ctx->ops = &smb30_operations; /* currently identical with 3.0 */ + ctx->vals = &smbdefault_values; break; default: cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); @@ -112,7 +112,7 @@ static const match_table_t cifs_secflavor_tokens = { { Opt_sec_err, NULL } }; -int cifs_parse_security_flavors(char *value, struct smb_vol *vol) +int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx) { substring_t args[MAX_OPT_ARGS]; @@ -121,44 +121,44 @@ int cifs_parse_security_flavors(char *value, struct smb_vol *vol) * With mount options, the last one should win. Reset any existing * settings back to default. */ - vol->sectype = Unspecified; - vol->sign = false; + ctx->sectype = Unspecified; + ctx->sign = false; switch (match_token(value, cifs_secflavor_tokens, args)) { case Opt_sec_krb5p: cifs_dbg(VFS, "sec=krb5p is not supported!\n"); return 1; case Opt_sec_krb5i: - vol->sign = true; + ctx->sign = true; fallthrough; case Opt_sec_krb5: - vol->sectype = Kerberos; + ctx->sectype = Kerberos; break; case Opt_sec_ntlmsspi: - vol->sign = true; + ctx->sign = true; fallthrough; case Opt_sec_ntlmssp: - vol->sectype = RawNTLMSSP; + ctx->sectype = RawNTLMSSP; break; case Opt_sec_ntlmi: - vol->sign = true; + ctx->sign = true; fallthrough; case Opt_ntlm: - vol->sectype = NTLM; + ctx->sectype = NTLM; break; case Opt_sec_ntlmv2i: - vol->sign = true; + ctx->sign = true; fallthrough; case Opt_sec_ntlmv2: - vol->sectype = NTLMv2; + ctx->sectype = NTLMv2; break; #ifdef CONFIG_CIFS_WEAK_PW_HASH case Opt_sec_lanman: - vol->sectype = LANMAN; + ctx->sectype = LANMAN; break; #endif case Opt_sec_none: - vol->nullauth = 1; + ctx->nullauth = 1; break; default: cifs_dbg(VFS, "bad security option: %s\n", value); @@ -178,40 +178,40 @@ static const match_table_t cifs_cacheflavor_tokens = { }; int -cifs_parse_cache_flavor(char *value, struct smb_vol *vol) +cifs_parse_cache_flavor(char *value, struct smb3_fs_context *ctx) { substring_t args[MAX_OPT_ARGS]; switch (match_token(value, cifs_cacheflavor_tokens, args)) { case Opt_cache_loose: - vol->direct_io = false; - vol->strict_io = false; - vol->cache_ro = false; - vol->cache_rw = false; + ctx->direct_io = false; + ctx->strict_io = false; + ctx->cache_ro = false; + ctx->cache_rw = false; break; case Opt_cache_strict: - vol->direct_io = false; - vol->strict_io = true; - vol->cache_ro = false; - vol->cache_rw = false; + ctx->direct_io = false; + ctx->strict_io = true; + ctx->cache_ro = false; + ctx->cache_rw = false; break; case Opt_cache_none: - vol->direct_io = true; - vol->strict_io = false; - vol->cache_ro = false; - vol->cache_rw = false; + ctx->direct_io = true; + ctx->strict_io = false; + ctx->cache_ro = false; + ctx->cache_rw = false; break; case Opt_cache_ro: - vol->direct_io = false; - vol->strict_io = false; - vol->cache_ro = true; - vol->cache_rw = false; + ctx->direct_io = false; + ctx->strict_io = false; + ctx->cache_ro = true; + ctx->cache_rw = false; break; case Opt_cache_rw: - vol->direct_io = false; - vol->strict_io = false; - vol->cache_ro = false; - vol->cache_rw = true; + ctx->direct_io = false; + ctx->strict_io = false; + ctx->cache_ro = false; + ctx->cache_rw = true; break; default: cifs_dbg(VFS, "bad cache= option: %s\n", value); diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h index 886208a1b0ef..f217bd600c1e 100644 --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -24,7 +24,7 @@ enum smb_version { Smb_version_err }; -int cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3); +int cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3); enum { Opt_cache_loose, @@ -35,7 +35,7 @@ enum { Opt_cache_err }; -int cifs_parse_cache_flavor(char *value, struct smb_vol *vol); +int cifs_parse_cache_flavor(char *value, struct smb3_fs_context *ctx); enum cifs_sec_param { Opt_sec_krb5, @@ -53,6 +53,105 @@ enum cifs_sec_param { Opt_sec_err }; -int cifs_parse_security_flavors(char *value, struct smb_vol *vol); +struct smb3_fs_context { + bool uid_specified; + bool gid_specified; + bool sloppy; + char *nodename; + bool got_ip; + bool got_version; + unsigned short port; + + char *username; + char *password; + char *domainname; + char *UNC; + char *iocharset; /* local code page for mapping to and from Unicode */ + char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ + char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ + kuid_t cred_uid; + kuid_t linux_uid; + kgid_t linux_gid; + kuid_t backupuid; + kgid_t backupgid; + umode_t file_mode; + umode_t dir_mode; + enum securityEnum sectype; /* sectype requested via mnt opts */ + bool sign; /* was signing requested via mnt opts? */ + bool ignore_signature:1; + bool retry:1; + bool intr:1; + bool setuids:1; + bool setuidfromacl:1; + bool override_uid:1; + bool override_gid:1; + bool dynperm:1; + bool noperm:1; + bool nodelete:1; + bool mode_ace:1; + bool no_psx_acl:1; /* set if posix acl support should be disabled */ + bool cifs_acl:1; + bool backupuid_specified; /* mount option backupuid is specified */ + bool backupgid_specified; /* mount option backupgid is specified */ + bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ + bool server_ino:1; /* use inode numbers from server ie UniqueId */ + bool direct_io:1; + bool strict_io:1; /* strict cache behavior */ + bool cache_ro:1; + bool cache_rw:1; + bool remap:1; /* set to remap seven reserved chars in filenames */ + bool sfu_remap:1; /* remap seven reserved chars ala SFU */ + bool posix_paths:1; /* unset to not ask for posix pathnames. */ + bool no_linux_ext:1; + bool linux_ext:1; + bool sfu_emul:1; + bool nullauth:1; /* attempt to authenticate with null user */ + bool nocase:1; /* request case insensitive filenames */ + bool nobrl:1; /* disable sending byte range locks to srv */ + bool nohandlecache:1; /* disable caching dir handles if srvr probs */ + bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ + bool seal:1; /* request transport encryption on share */ + bool nodfs:1; /* Do not request DFS, even if available */ + bool local_lease:1; /* check leases only on local system, not remote */ + bool noblocksnd:1; + bool noautotune:1; + bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ + bool no_lease:1; /* disable requesting leases */ + bool fsc:1; /* enable fscache */ + bool mfsymlinks:1; /* use Minshall+French Symlinks */ + bool multiuser:1; + bool rwpidforward:1; /* pid forward for read/write operations */ + bool nosharesock:1; + bool persistent:1; + bool nopersistent:1; + bool resilient:1; /* noresilient not required since not fored for CA */ + bool domainauto:1; + bool rdma:1; + bool multichannel:1; + bool use_client_guid:1; + /* reuse existing guid for multichannel */ + u8 client_guid[SMB2_CLIENT_GUID_SIZE]; + unsigned int bsize; + unsigned int rsize; + unsigned int wsize; + unsigned int min_offload; + bool sockopt_tcp_nodelay:1; + unsigned long actimeo; /* attribute cache timeout (jiffies) */ + struct smb_version_operations *ops; + struct smb_version_values *vals; + char *prepath; + struct sockaddr_storage dstaddr; /* destination address */ + struct sockaddr_storage srcaddr; /* allow binding to a local IP */ + struct nls_table *local_nls; + unsigned int echo_interval; /* echo interval in secs */ + __u64 snapshot_time; /* needed for timewarp tokens */ + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ + unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ + unsigned int max_channels; + __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ + bool rootfs:1; /* if it's a SMB root file system */ +}; + +int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx); #endif diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 6c2c42f8d893..5c71f2730166 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -32,6 +32,7 @@ #include #include "cifs_spnego.h" #include "smb2proto.h" +#include "fs_context.h" bool is_server_using_iface(struct TCP_Server_Info *server, @@ -170,7 +171,7 @@ int cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) { struct cifs_chan *chan; - struct smb_vol vol = {NULL}; + struct smb3_fs_context ctx = {NULL}; static const char unc_fmt[] = "\\%s\\foo"; char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0}; struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr; @@ -188,7 +189,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) &ipv6->sin6_addr); /* - * Setup a smb_vol with mostly the same info as the existing + * Setup a ctx with mostly the same info as the existing * session and overwrite it with the requested iface data. * * We need to setup at least the fields used for negprot and @@ -200,30 +201,30 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) */ /* Always make new connection for now (TODO?) */ - vol.nosharesock = true; + ctx.nosharesock = true; /* Auth */ - vol.domainauto = ses->domainAuto; - vol.domainname = ses->domainName; - vol.username = ses->user_name; - vol.password = ses->password; - vol.sectype = ses->sectype; - vol.sign = ses->sign; + ctx.domainauto = ses->domainAuto; + ctx.domainname = ses->domainName; + ctx.username = ses->user_name; + ctx.password = ses->password; + ctx.sectype = ses->sectype; + ctx.sign = ses->sign; /* UNC and paths */ /* XXX: Use ses->server->hostname? */ sprintf(unc, unc_fmt, ses->serverName); - vol.UNC = unc; - vol.prepath = ""; + ctx.UNC = unc; + ctx.prepath = ""; /* Reuse same version as master connection */ - vol.vals = ses->server->vals; - vol.ops = ses->server->ops; + ctx.vals = ses->server->vals; + ctx.ops = ses->server->ops; - vol.noblocksnd = ses->server->noblocksnd; - vol.noautotune = ses->server->noautotune; - vol.sockopt_tcp_nodelay = ses->server->tcp_nodelay; - vol.echo_interval = ses->server->echo_interval / HZ; + ctx.noblocksnd = ses->server->noblocksnd; + ctx.noautotune = ses->server->noautotune; + ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay; + ctx.echo_interval = ses->server->echo_interval / HZ; /* * This will be used for encoding/decoding user/domain/pw @@ -234,21 +235,21 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) * stored. This might break when dealing with non-ascii * strings. */ - vol.local_nls = load_nls_default(); + ctx.local_nls = load_nls_default(); /* Use RDMA if possible */ - vol.rdma = iface->rdma_capable; - memcpy(&vol.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage)); + ctx.rdma = iface->rdma_capable; + memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage)); /* reuse master con client guid */ - memcpy(&vol.client_guid, ses->server->client_guid, + memcpy(&ctx.client_guid, ses->server->client_guid, SMB2_CLIENT_GUID_SIZE); - vol.use_client_guid = true; + ctx.use_client_guid = true; mutex_lock(&ses->session_mutex); chan = ses->binding_chan = &ses->chans[ses->chan_count]; - chan->server = cifs_get_tcp_session(&vol); + chan->server = cifs_get_tcp_session(&ctx); if (IS_ERR(chan->server)) { rc = PTR_ERR(chan->server); chan->server = NULL; @@ -274,7 +275,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) if (rc) goto out; - rc = cifs_setup_session(xid, ses, vol.local_nls); + rc = cifs_setup_session(xid, ses, ctx.local_nls); if (rc) goto out; @@ -297,7 +298,7 @@ out: if (rc && chan->server) cifs_put_tcp_session(chan->server, 0); - unload_nls(vol.local_nls); + unload_nls(ctx.local_nls); return rc; } diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 80287c26cfac..359a0ef796de 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -12,6 +12,7 @@ #include "cifs_debug.h" #include "cifspdu.h" #include "cifs_unicode.h" +#include "fs_context.h" /* * An NT cancel request header looks just like the original request except: @@ -428,15 +429,15 @@ cifs_negotiate(const unsigned int xid, struct cifs_ses *ses) } static unsigned int -cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); struct TCP_Server_Info *server = tcon->ses->server; unsigned int wsize; /* start with specified wsize, or default */ - if (volume_info->wsize) - wsize = volume_info->wsize; + if (ctx->wsize) + wsize = ctx->wsize; else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) wsize = CIFS_DEFAULT_IOSIZE; else @@ -463,7 +464,7 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) } static unsigned int -cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability); struct TCP_Server_Info *server = tcon->ses->server; @@ -488,7 +489,7 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) else defsize = server->maxBuf - sizeof(READ_RSP); - rsize = volume_info->rsize ? volume_info->rsize : defsize; + rsize = ctx->rsize ? ctx->rsize : defsize; /* * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 22f1d8dc12b0..940e61e92a8c 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -24,6 +24,7 @@ #include "smb2glob.h" #include "cifs_ioctl.h" #include "smbdirect.h" +#include "fs_context.h" /* Change credits for different ops and return the total number of credits */ static int @@ -339,13 +340,13 @@ smb2_negotiate(const unsigned int xid, struct cifs_ses *ses) } static unsigned int -smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { struct TCP_Server_Info *server = tcon->ses->server; unsigned int wsize; /* start with specified wsize, or default */ - wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE; + wsize = ctx->wsize ? ctx->wsize : CIFS_DEFAULT_IOSIZE; wsize = min_t(unsigned int, wsize, server->max_write); if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE); @@ -354,13 +355,13 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) } static unsigned int -smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { struct TCP_Server_Info *server = tcon->ses->server; unsigned int wsize; /* start with specified wsize, or default */ - wsize = volume_info->wsize ? volume_info->wsize : SMB3_DEFAULT_IOSIZE; + wsize = ctx->wsize ? ctx->wsize : SMB3_DEFAULT_IOSIZE; wsize = min_t(unsigned int, wsize, server->max_write); #ifdef CONFIG_CIFS_SMB_DIRECT if (server->rdma) { @@ -386,13 +387,13 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) } static unsigned int -smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { struct TCP_Server_Info *server = tcon->ses->server; unsigned int rsize; /* start with specified rsize, or default */ - rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE; + rsize = ctx->rsize ? ctx->rsize : CIFS_DEFAULT_IOSIZE; rsize = min_t(unsigned int, rsize, server->max_read); if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU)) @@ -402,13 +403,13 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) } static unsigned int -smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info) +smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx) { struct TCP_Server_Info *server = tcon->ses->server; unsigned int rsize; /* start with specified rsize, or default */ - rsize = volume_info->rsize ? volume_info->rsize : SMB3_DEFAULT_IOSIZE; + rsize = ctx->rsize ? ctx->rsize : SMB3_DEFAULT_IOSIZE; rsize = min_t(unsigned int, rsize, server->max_read); #ifdef CONFIG_CIFS_SMB_DIRECT if (server->rdma) { -- cgit v1.2.3 From 522aa3b575322597efdd64a517c65b2f43fb6b9c Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 14 Dec 2020 16:40:17 +1000 Subject: cifs: move [brw]size from cifs_sb to cifs_sb->ctx Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/cifs_fs_sb.h | 3 --- fs/cifs/cifsfs.c | 11 +++++++---- fs/cifs/connect.c | 21 +++++++++------------ fs/cifs/file.c | 12 ++++++------ fs/cifs/fs_context.c | 3 +++ fs/cifs/fs_context.h | 3 +++ fs/cifs/inode.c | 2 +- fs/cifs/smb1ops.c | 2 +- fs/cifs/smb2ops.c | 2 +- 9 files changed, 31 insertions(+), 28 deletions(-) (limited to 'fs/cifs/smb2ops.c') diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 69d26313d350..aa77edc12212 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -62,9 +62,6 @@ struct cifs_sb_info { struct tcon_link *master_tlink; struct nls_table *local_nls; struct smb3_fs_context *ctx; - unsigned int bsize; - unsigned int rsize; - unsigned int wsize; atomic_t active; unsigned int mnt_cifs_flags; struct delayed_work prune_tlinks; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9c2959f552e0..6a3cb192d75a 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -218,7 +218,7 @@ cifs_read_super(struct super_block *sb) if (rc) goto out_no_root; /* tune readahead according to rsize */ - sb->s_bdi->ra_pages = cifs_sb->rsize / PAGE_SIZE; + sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE; sb->s_blocksize = CIFS_MAX_MSGSIZE; sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ @@ -615,9 +615,12 @@ cifs_show_options(struct seq_file *s, struct dentry *root) from_kgid_munged(&init_user_ns, cifs_sb->ctx->backupgid)); - seq_printf(s, ",rsize=%u", cifs_sb->rsize); - seq_printf(s, ",wsize=%u", cifs_sb->wsize); - seq_printf(s, ",bsize=%u", cifs_sb->bsize); + if (cifs_sb->ctx->got_rsize) + seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize); + if (cifs_sb->ctx->got_wsize) + seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize); + if (cifs_sb->ctx->got_bsize) + seq_printf(s, ",bsize=%u", cifs_sb->ctx->bsize); if (tcon->ses->server->min_offload) seq_printf(s, ",esize=%u", tcon->ses->server->min_offload); seq_printf(s, ",echo_interval=%lu", diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 16d92ff4ae5e..eb036cf0f631 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2248,10 +2248,10 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) * We want to share sb only if we don't specify an r/wsize or * specified r/wsize is greater than or equal to existing one. */ - if (new->wsize && new->wsize < old->wsize) + if (new->ctx->wsize && new->ctx->wsize < old->ctx->wsize) return 0; - if (new->rsize && new->rsize < old->rsize) + if (new->ctx->rsize && new->ctx->rsize < old->ctx->rsize) return 0; if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) || @@ -2714,14 +2714,6 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx, spin_lock_init(&cifs_sb->tlink_tree_lock); cifs_sb->tlink_tree = RB_ROOT; - cifs_sb->bsize = ctx->bsize; - /* - * Temporarily set r/wsize for matching superblock. If we end up using - * new sb then client will later negotiate it downward if needed. - */ - cifs_sb->rsize = ctx->rsize; - cifs_sb->wsize = ctx->wsize; - cifs_dbg(FYI, "file mode: %04ho dir mode: %04ho\n", cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode); @@ -2925,8 +2917,13 @@ static int mount_get_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cif } } - cifs_sb->wsize = server->ops->negotiate_wsize(tcon, ctx); - cifs_sb->rsize = server->ops->negotiate_rsize(tcon, ctx); + /* + * Clamp the rsize/wsize mount arguments if they are too big for the server + */ + if (cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx)) + cifs_sb->ctx->wsize = server->ops->negotiate_wsize(tcon, ctx); + if (cifs_sb->ctx->rsize > server->ops->negotiate_rsize(tcon, ctx)) + cifs_sb->ctx->rsize = server->ops->negotiate_rsize(tcon, ctx); return 0; } diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 583074546e6f..6d001905c8e5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2336,7 +2336,7 @@ static int cifs_writepages(struct address_space *mapping, * If wsize is smaller than the page cache size, default to writing * one page at a time via cifs_writepage */ - if (cifs_sb->wsize < PAGE_SIZE) + if (cifs_sb->ctx->wsize < PAGE_SIZE) return generic_writepages(mapping, wbc); xid = get_xid(); @@ -2369,7 +2369,7 @@ retry: if (rc) get_file_rc = rc; - rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, + rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize, &wsize, credits); if (rc != 0) { done = true; @@ -2911,7 +2911,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, break; } - rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize, + rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize, &wsize, credits); if (rc) break; @@ -3642,7 +3642,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, break; } - rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, + rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize, credits); if (rc) break; @@ -4028,7 +4028,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) cifs_sb = CIFS_FILE_SB(file); /* FIXME: set up handlers for larger reads and/or convert to async */ - rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize); + rsize = min_t(unsigned int, cifs_sb->ctx->rsize, CIFSMaxBufSize); if (file->private_data == NULL) { rc = -EBADF; @@ -4413,7 +4413,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, break; } - rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize, + rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize, credits); if (rc) break; diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 4d8caf5b9519..b7f5633a1c64 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -784,12 +784,15 @@ static int smb3_fs_context_parse_param(struct fs_context *fc, goto cifs_parse_mount_err; } ctx->bsize = result.uint_32; + ctx->got_bsize = true; break; case Opt_rsize: ctx->rsize = result.uint_32; + ctx->got_rsize = true; break; case Opt_wsize: ctx->wsize = result.uint_32; + ctx->got_wsize = true; break; case Opt_actimeo: ctx->actimeo = HZ * result.uint_32; diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h index 4c4c392b9767..7c794df7a874 100644 --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -152,6 +152,9 @@ struct smb3_fs_context { char *nodename; bool got_ip; bool got_version; + bool got_rsize; + bool got_wsize; + bool got_bsize; unsigned short port; char *username; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 240d79e3aa14..a83b3a8ffaac 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2409,7 +2409,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat, } generic_fillattr(inode, stat); - stat->blksize = cifs_sb->bsize; + stat->blksize = cifs_sb->ctx->bsize; stat->ino = CIFS_I(inode)->uniqueid; /* old CIFS Unix Extensions doesn't return create time */ diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 359a0ef796de..e31b939e628c 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -1006,7 +1006,7 @@ cifs_is_read_op(__u32 oplock) static unsigned int cifs_wp_retry_size(struct inode *inode) { - return CIFS_SB(inode->i_sb)->wsize; + return CIFS_SB(inode->i_sb)->ctx->wsize; } static bool diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 940e61e92a8c..a505cc3e58da 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -3951,7 +3951,7 @@ smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key) static unsigned int smb2_wp_retry_size(struct inode *inode) { - return min_t(unsigned int, CIFS_SB(inode->i_sb)->wsize, + return min_t(unsigned int, CIFS_SB(inode->i_sb)->ctx->wsize, SMB2_MAX_BUFFER_SIZE); } -- cgit v1.2.3 From cd7b699b0198a7fc24f6dc79985f6151f589518c Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Thu, 12 Nov 2020 08:56:49 -0800 Subject: cifs: Tracepoints and logs for tracing credit changes. There is at least one suspected bug in crediting changes in cifs.ko which has come up a few times in the discussions and in a customer case. This change adds tracepoints to the code which modifies the server credit values in any way. The goal is to be able to track the changes to the credit values of the session to be able to catch when there is a crediting bug. Signed-off-by: Shyam Prasad N Signed-off-by: Steve French --- fs/cifs/connect.c | 8 ++++++++ fs/cifs/smb2ops.c | 41 +++++++++++++++++++++++++++++++++++++---- fs/cifs/trace.h | 4 ++++ fs/cifs/transport.c | 15 +++++++++++++++ 4 files changed, 64 insertions(+), 4 deletions(-) (limited to 'fs/cifs/smb2ops.c') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 64a41b32fbb1..509a41ff56b8 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -845,6 +845,7 @@ static void smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) { struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buffer; + int scredits = server->credits; /* * SMB1 does not use credits. @@ -857,6 +858,13 @@ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) server->credits += le16_to_cpu(shdr->CreditRequest); spin_unlock(&server->req_lock); wake_up(&server->request_q); + + trace_smb3_add_credits(server->CurrentMid, + server->hostname, scredits, + le16_to_cpu(shdr->CreditRequest)); + cifs_server_dbg(FYI, "%s: added %u credits total=%d\n", + __func__, le16_to_cpu(shdr->CreditRequest), + scredits); } } diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index a505cc3e58da..949cd1177147 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -100,9 +100,10 @@ smb2_add_credits(struct TCP_Server_Info *server, spin_unlock(&server->req_lock); wake_up(&server->request_q); - if (reconnect_detected) + if (reconnect_detected) { cifs_dbg(FYI, "trying to put %d credits from the old server instance %d\n", add, instance); + } if (server->tcpStatus == CifsNeedReconnect || server->tcpStatus == CifsExiting) @@ -124,7 +125,7 @@ smb2_add_credits(struct TCP_Server_Info *server, default: trace_smb3_add_credits(server->CurrentMid, server->hostname, rc, add); - cifs_dbg(FYI, "add %u credits total=%d\n", add, rc); + cifs_dbg(FYI, "%s: added %u credits total=%d\n", __func__, add, rc); } } @@ -136,6 +137,11 @@ smb2_set_credits(struct TCP_Server_Info *server, const int val) if (val == 1) server->reconnect_instance++; spin_unlock(&server->req_lock); + + trace_smb3_set_credits(server->CurrentMid, + server->hostname, val, val); + cifs_dbg(FYI, "%s: set %u credits\n", __func__, val); + /* don't log while holding the lock */ if (val == 1) cifs_dbg(FYI, "set credits to 1 due to smb2 reconnect\n"); @@ -202,6 +208,7 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, DIV_ROUND_UP(*num, SMB2_MAX_BUFFER_SIZE); credits->instance = server->reconnect_instance; server->credits -= credits->value; + scredits = server->credits; server->in_flight++; if (server->in_flight > server->max_in_flight) server->max_in_flight = server->in_flight; @@ -209,6 +216,12 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, } } spin_unlock(&server->req_lock); + + trace_smb3_add_credits(server->CurrentMid, + server->hostname, scredits, -(credits->value)); + cifs_dbg(FYI, "%s: removed %u credits total=%d\n", + __func__, credits->value, scredits); + return rc; } @@ -218,13 +231,17 @@ smb2_adjust_credits(struct TCP_Server_Info *server, const unsigned int payload_size) { int new_val = DIV_ROUND_UP(payload_size, SMB2_MAX_BUFFER_SIZE); + int scredits; if (!credits->value || credits->value == new_val) return 0; if (credits->value < new_val) { - WARN_ONCE(1, "request has less credits (%d) than required (%d)", - credits->value, new_val); + trace_smb3_too_many_credits(server->CurrentMid, + server->hostname, 0, credits->value - new_val); + cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", + credits->value, new_val); + return -ENOTSUPP; } @@ -232,15 +249,24 @@ smb2_adjust_credits(struct TCP_Server_Info *server, if (server->reconnect_instance != credits->instance) { spin_unlock(&server->req_lock); + trace_smb3_reconnect_detected(server->CurrentMid, + server->hostname, 0, 0); cifs_server_dbg(VFS, "trying to return %d credits to old session\n", credits->value - new_val); return -EAGAIN; } server->credits += credits->value - new_val; + scredits = server->credits; spin_unlock(&server->req_lock); wake_up(&server->request_q); credits->value = new_val; + + trace_smb3_add_credits(server->CurrentMid, + server->hostname, scredits, credits->value - new_val); + cifs_dbg(FYI, "%s: adjust added %u credits total=%d\n", + __func__, credits->value - new_val, scredits); + return 0; } @@ -2343,6 +2369,7 @@ static bool smb2_is_status_pending(char *buf, struct TCP_Server_Info *server) { struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; + int scredits; if (shdr->Status != STATUS_PENDING) return false; @@ -2350,8 +2377,14 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server) if (shdr->CreditRequest) { spin_lock(&server->req_lock); server->credits += le16_to_cpu(shdr->CreditRequest); + scredits = server->credits; spin_unlock(&server->req_lock); wake_up(&server->request_q); + + trace_smb3_add_credits(server->CurrentMid, + server->hostname, scredits, le16_to_cpu(shdr->CreditRequest)); + cifs_dbg(FYI, "%s: status pending add %u credits total=%d\n", + __func__, le16_to_cpu(shdr->CreditRequest), scredits); } return true; diff --git a/fs/cifs/trace.h b/fs/cifs/trace.h index 90e0fab69bb8..c3d1a584f251 100644 --- a/fs/cifs/trace.h +++ b/fs/cifs/trace.h @@ -909,8 +909,12 @@ DEFINE_EVENT(smb3_credit_class, smb3_##name, \ TP_ARGS(currmid, hostname, credits, credits_to_add)) DEFINE_SMB3_CREDIT_EVENT(reconnect_with_invalid_credits); +DEFINE_SMB3_CREDIT_EVENT(reconnect_detected); DEFINE_SMB3_CREDIT_EVENT(credit_timeout); +DEFINE_SMB3_CREDIT_EVENT(insufficient_credits); +DEFINE_SMB3_CREDIT_EVENT(too_many_credits); DEFINE_SMB3_CREDIT_EVENT(add_credits); +DEFINE_SMB3_CREDIT_EVENT(set_credits); #endif /* _CIFS_TRACE_H */ diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 36b2ece43403..e9abb41aa89b 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -527,6 +527,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, int *credits; int optype; long int t; + int scredits = server->credits; if (timeout < 0) t = MAX_JIFFY_OFFSET; @@ -624,12 +625,18 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, /* update # of requests on the wire to server */ if ((flags & CIFS_TIMEOUT_MASK) != CIFS_BLOCKING_OP) { *credits -= num_credits; + scredits = *credits; server->in_flight += num_credits; if (server->in_flight > server->max_in_flight) server->max_in_flight = server->in_flight; *instance = server->reconnect_instance; } spin_unlock(&server->req_lock); + + trace_smb3_add_credits(server->CurrentMid, + server->hostname, scredits, -(num_credits)); + cifs_dbg(FYI, "%s: remove %u credits total=%d\n", + __func__, num_credits, scredits); break; } } @@ -649,10 +656,14 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num, const int flags, unsigned int *instance) { int *credits; + int scredits, sin_flight; credits = server->ops->get_credits_field(server, flags & CIFS_OP_MASK); spin_lock(&server->req_lock); + scredits = *credits; + sin_flight = server->in_flight; + if (*credits < num) { /* * Return immediately if not too many requests in flight since @@ -660,6 +671,10 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num, */ if (server->in_flight < num - *credits) { spin_unlock(&server->req_lock); + trace_smb3_insufficient_credits(server->CurrentMid, + server->hostname, scredits, sin_flight); + cifs_dbg(FYI, "%s: %d requests in flight, needed %d total=%d\n", + __func__, sin_flight, num, scredits); return -ENOTSUPP; } } -- cgit v1.2.3