Commit eb90e8ec authored by Paulo Alcantara's avatar Paulo Alcantara Committed by Steve French
Browse files

smb: client: introduce reparse mount option



Allow the user to create special files and symlinks by choosing
between WSL and NFS reparse points via 'reparse={nfs,wsl}' mount
options.  If unset or 'reparse=default', the client will default to
creating them via NFS reparse points.

Creating WSL reparse points isn't supported yet, so simply return
error when attempting to mount with 'reparse=wsl' for now.

Signed-off-by: default avatarPaulo Alcantara <pc@manguebit.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 71f15c90
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -153,6 +153,12 @@ enum securityEnum {
	Kerberos,		/* Kerberos via SPNEGO */
};

enum cifs_reparse_type {
	CIFS_REPARSE_TYPE_NFS,
	CIFS_REPARSE_TYPE_WSL,
	CIFS_REPARSE_TYPE_DEFAULT = CIFS_REPARSE_TYPE_NFS,
};

struct session_key {
	unsigned int len;
	char *response;
+2 −0
Original line number Diff line number Diff line
@@ -2803,6 +2803,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
		return 0;
	if (old->ctx->closetimeo != new->ctx->closetimeo)
		return 0;
	if (old->ctx->reparse_type != new->ctx->reparse_type)
		return 0;

	return 1;
}
+35 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
	fsparam_string("vers", Opt_vers),
	fsparam_string("sec", Opt_sec),
	fsparam_string("cache", Opt_cache),
	fsparam_string("reparse", Opt_reparse),

	/* Arguments that should be ignored */
	fsparam_flag("guest", Opt_ignore),
@@ -296,6 +297,35 @@ cifs_parse_cache_flavor(struct fs_context *fc, char *value, struct smb3_fs_conte
	return 0;
}

static const match_table_t reparse_flavor_tokens = {
	{ Opt_reparse_default,	"default" },
	{ Opt_reparse_nfs,	"nfs" },
	{ Opt_reparse_wsl,	"wsl" },
	{ Opt_reparse_err,	NULL },
};

static int parse_reparse_flavor(struct fs_context *fc, char *value,
				struct smb3_fs_context *ctx)
{
	substring_t args[MAX_OPT_ARGS];

	switch (match_token(value, reparse_flavor_tokens, args)) {
	case Opt_reparse_default:
		ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT;
		break;
	case Opt_reparse_nfs:
		ctx->reparse_type = CIFS_REPARSE_TYPE_NFS;
		break;
	case Opt_reparse_wsl:
		cifs_errorf(fc, "unsupported reparse= option: %s\n", value);
		return 1;
	default:
		cifs_errorf(fc, "bad reparse= option: %s\n", value);
		return 1;
	}
	return 0;
}

#define DUP_CTX_STR(field)						\
do {									\
	if (ctx->field) {						\
@@ -1566,6 +1596,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
	case Opt_rdma:
		ctx->rdma = true;
		break;
	case Opt_reparse:
		if (parse_reparse_flavor(fc, param->string, ctx))
			goto cifs_parse_mount_err;
		break;
	}
	/* case Opt_ignore: - is ignored as expected ... */

@@ -1652,6 +1686,7 @@ int smb3_init_fs_context(struct fs_context *fc)
	ctx->backupgid_specified = false; /* no backup intent for a group */

	ctx->retrans = 1;
	ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT;

/*
 *	short int override_uid = -1;
+9 −0
Original line number Diff line number Diff line
@@ -41,6 +41,13 @@ enum {
	Opt_cache_err
};

enum cifs_reparse_parm {
	Opt_reparse_default,
	Opt_reparse_nfs,
	Opt_reparse_wsl,
	Opt_reparse_err
};

enum cifs_sec_param {
	Opt_sec_krb5,
	Opt_sec_krb5i,
@@ -148,6 +155,7 @@ enum cifs_param {
	Opt_vers,
	Opt_sec,
	Opt_cache,
	Opt_reparse,

	/* Mount options to be ignored */
	Opt_ignore,
@@ -271,6 +279,7 @@ struct smb3_fs_context {
	char *leaf_fullpath;
	struct cifs_ses *dfs_root_ses;
	bool dfs_automount:1; /* set for dfs automount only */
	enum cifs_reparse_type reparse_type;
};

extern const struct fs_parameter_spec smb3_fs_parameters[];