1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2020, Microsoft Corporation.
*
* Author(s): Steve French <stfrench@microsoft.com>
* David Howells <dhowells@redhat.com>
*/
#ifndef _FS_CONTEXT_H
#define _FS_CONTEXT_H
#include "cifsglob.h"
#include <linux/parser.h>
#include <linux/fs_parser.h>
/* Log errors in fs_context (new mount api) but also in dmesg (old style) */
#define cifs_errorf(fc, fmt, ...) \
do { \
errorf(fc, fmt, ## __VA_ARGS__); \
cifs_dbg(VFS, fmt, ## __VA_ARGS__); \
} while (0)
static inline size_t cifs_io_align(struct fs_context *fc,
const char *name, size_t size)
{
if (!size || !IS_ALIGNED(size, PAGE_SIZE)) {
cifs_errorf(fc, "unaligned %s, making it a multiple of %lu bytes\n",
name, PAGE_SIZE);
size = umax(round_down(size, PAGE_SIZE), PAGE_SIZE);
}
return size;
}
#define CIFS_ALIGN_WSIZE(_fc, _size) cifs_io_align(_fc, "wsize", _size)
#define CIFS_ALIGN_RSIZE(_fc, _size) cifs_io_align(_fc, "rsize", _size)
#define CIFS_ALIGN_BSIZE(_fc, _size) cifs_io_align(_fc, "bsize", _size)
enum smb_version {
Smb_1 = 1,
Smb_20,
Smb_21,
Smb_30,
Smb_302,
Smb_311,
Smb_3any,
Smb_default,
Smb_version_err
};
enum {
Opt_cache_loose,
Opt_cache_strict,
Opt_cache_none,
Opt_cache_ro,
Opt_cache_rw,
Opt_cache_err
};
enum cifs_reparse_parm {
Opt_reparse_default,
Opt_reparse_none,
Opt_reparse_nfs,
Opt_reparse_wsl,
Opt_reparse_err
};
enum cifs_symlink_parm {
Opt_symlink_default,
Opt_symlink_none,
Opt_symlink_native,
Opt_symlink_unix,
Opt_symlink_mfsymlinks,
Opt_symlink_sfu,
Opt_symlink_nfs,
Opt_symlink_wsl,
Opt_symlink_err
};
enum cifs_sec_param {
Opt_sec_krb5,
Opt_sec_krb5i,
Opt_sec_krb5p,
Opt_sec_ntlmsspi,
Opt_sec_ntlmssp,
Opt_sec_ntlmv2,
Opt_sec_ntlmv2i,
Opt_sec_none,
Opt_sec_err
};
enum cifs_upcall_target_param {
Opt_upcall_target_mount,
Opt_upcall_target_application,
Opt_upcall_target_err
};
enum cifs_param {
/* Mount options that take no arguments */
Opt_user_xattr,
Opt_forceuid,
Opt_forcegid,
Opt_noblocksend,
Opt_noautotune,
Opt_nolease,
Opt_nosparse,
Opt_hard,
Opt_soft,
Opt_perm,
Opt_nodelete,
Opt_mapposix,
Opt_mapchars,
Opt_nomapchars,
Opt_sfu,
Opt_nodfs,
Opt_posixpaths,
Opt_unix,
Opt_nocase,
Opt_brl,
Opt_handlecache,
Opt_forcemandatorylock,
Opt_setuidfromacl,
Opt_setuids,
Opt_dynperm,
Opt_intr,
Opt_strictsync,
Opt_serverino,
Opt_rwpidforward,
Opt_cifsacl,
Opt_acl,
Opt_locallease,
Opt_sign,
Opt_ignore_signature,
Opt_seal,
Opt_noac,
Opt_fsc,
Opt_mfsymlinks,
Opt_multiuser,
Opt_sloppy,
Opt_nosharesock,
Opt_persistent,
Opt_resilient,
Opt_tcp_nodelay,
Opt_domainauto,
Opt_rdma,
Opt_modesid,
Opt_rootfs,
Opt_multichannel,
Opt_compress,
Opt_witness,
Opt_is_upcall_target_mount,
Opt_is_upcall_target_application,
Opt_unicode,
/* Mount options which take numeric value */
Opt_backupuid,
Opt_backupgid,
Opt_uid,
Opt_cruid,
Opt_gid,
Opt_port,
Opt_file_mode,
Opt_dirmode,
Opt_min_enc_offload,
Opt_retrans,
Opt_blocksize,
Opt_rasize,
Opt_rsize,
Opt_wsize,
Opt_actimeo,
Opt_acdirmax,
Opt_acregmax,
Opt_closetimeo,
Opt_echo_interval,
Opt_max_credits,
Opt_max_cached_dirs,
Opt_snapshot,
Opt_max_channels,
Opt_handletimeout,
/* Mount options which take string value */
Opt_source,
Opt_user,
Opt_pass,
Opt_pass2,
Opt_ip,
Opt_domain,
Opt_srcaddr,
Opt_iocharset,
Opt_netbiosname,
Opt_servern,
Opt_nbsessinit,
Opt_ver,
Opt_vers,
Opt_sec,
Opt_cache,
Opt_reparse,
Opt_upcalltarget,
Opt_nativesocket,
Opt_symlink,
Opt_symlinkroot,
/* Mount options to be ignored */
Opt_ignore,
Opt_err
};
struct smb3_fs_context {
bool forceuid_specified;
bool forcegid_specified;
bool uid_specified;
bool cruid_specified;
bool gid_specified;
bool sloppy;
bool got_ip;
bool got_version;
bool got_rsize;
bool got_wsize;
bool got_bsize;
unsigned short port;
char *username;
char *password;
char *password2;
char *domainname;
char *source;
char *server_hostname;
char *UNC;
char *nodename;
char workstation_name[CIFS_MAX_WORKSTATION_LEN];
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 */
int rfc1001_sessinit;
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 */
enum upcall_target_enum upcall_target; /* where to upcall for mount */
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 no_sparse:1; /* do not attempt to set files sparse */
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];
/* User-specified original r/wsize value */
unsigned int vol_rsize;
unsigned int vol_wsize;
unsigned int bsize;
unsigned int rasize;
unsigned int rsize;
unsigned int wsize;
unsigned int min_offload;
unsigned int retrans;
bool sockopt_tcp_nodelay:1;
/* attribute cache timeout for files and directories in jiffies */
unsigned long acregmax;
unsigned long acdirmax;
/* timeout for deferred close of files in jiffies */
unsigned long closetimeo;
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; /* This is a copy of the pointer in cifs_sb */
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;
unsigned int max_cached_dirs;
bool compress; /* enable SMB2 messages (READ/WRITE) de/compression */
bool rootfs:1; /* if it's a SMB root file system */
bool witness:1; /* use witness protocol */
int unicode;
char *leaf_fullpath;
struct cifs_ses *dfs_root_ses;
bool dfs_automount:1; /* set for dfs automount only */
enum cifs_reparse_type reparse_type;
enum cifs_symlink_type symlink_type;
bool nonativesocket:1;
bool dfs_conn:1; /* set for dfs mounts */
char *dns_dom;
char *symlinkroot; /* top level directory for native SMB symlinks in absolute format */
};
extern const struct fs_parameter_spec smb3_fs_parameters[];
static inline enum cifs_symlink_type cifs_symlink_type(struct cifs_sb_info *cifs_sb)
{
bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions;
if (cifs_sb->ctx->symlink_type != CIFS_SYMLINK_TYPE_DEFAULT)
return cifs_sb->ctx->symlink_type;
if (cifs_sb->ctx->mfsymlinks)
return CIFS_SYMLINK_TYPE_MFSYMLINKS;
else if (cifs_sb->ctx->sfu_emul)
return CIFS_SYMLINK_TYPE_SFU;
else if (cifs_sb->ctx->linux_ext && !cifs_sb->ctx->no_linux_ext)
return posix ? CIFS_SYMLINK_TYPE_NATIVE : CIFS_SYMLINK_TYPE_UNIX;
else if (cifs_sb->ctx->reparse_type != CIFS_REPARSE_TYPE_NONE)
return CIFS_SYMLINK_TYPE_NATIVE;
return CIFS_SYMLINK_TYPE_NONE;
}
extern int smb3_init_fs_context(struct fs_context *fc);
extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);
extern void smb3_cleanup_fs_context(struct smb3_fs_context *ctx);
static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *fc)
{
return fc->fs_private;
}
extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
/*
* max deferred close timeout (jiffies) - 2^30
*/
#define SMB3_MAX_DCLOSETIMEO (1 << 30)
#define SMB3_DEF_DCLOSETIMEO (1 * HZ) /* even 1 sec enough to help eg open/write/close/open/read */
#define MAX_CACHED_FIDS 16
extern char *cifs_sanitize_prepath(char *prepath, gfp_t gfp);
extern struct mutex cifs_mount_mutex;
static inline void cifs_mount_lock(void)
{
mutex_lock(&cifs_mount_mutex);
}
static inline void cifs_mount_unlock(void)
{
mutex_unlock(&cifs_mount_mutex);
}
static inline void cifs_negotiate_rsize(struct TCP_Server_Info *server,
struct smb3_fs_context *ctx,
struct cifs_tcon *tcon)
{
unsigned int size;
size = umax(server->ops->negotiate_rsize(tcon, ctx), PAGE_SIZE);
if (ctx->rsize)
size = umax(umin(ctx->rsize, size), PAGE_SIZE);
ctx->rsize = round_down(size, PAGE_SIZE);
}
static inline void cifs_negotiate_wsize(struct TCP_Server_Info *server,
struct smb3_fs_context *ctx,
struct cifs_tcon *tcon)
{
unsigned int size;
size = umax(server->ops->negotiate_wsize(tcon, ctx), PAGE_SIZE);
if (ctx->wsize)
size = umax(umin(ctx->wsize, size), PAGE_SIZE);
ctx->wsize = round_down(size, PAGE_SIZE);
}
static inline void cifs_negotiate_iosize(struct TCP_Server_Info *server,
struct smb3_fs_context *ctx,
struct cifs_tcon *tcon)
{
cifs_negotiate_rsize(server, ctx, tcon);
cifs_negotiate_wsize(server, ctx, tcon);
}
#endif
|