Skip to content

Commit 6642d60

Browse files
committed
Merge tag '5.11-rc5-smb3' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French: "Four cifs patches found in additional testing of the conversion to the new mount API: three small option processing ones, and one fixing domain based DFS referrals" * tag '5.11-rc5-smb3' of git://git.samba.org/sfrench/cifs-2.6: cifs: fix dfs domain referrals cifs: returning mount parm processing errors correctly cifs: fix mounts to subdirectories of target cifs: ignore auto and noauto options if given
2 parents ad8b3c1 + 0d4873f commit 6642d60

6 files changed

Lines changed: 81 additions & 20 deletions

File tree

fs/cifs/cifs_dfs_ref.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,9 @@ cifs_build_devname(char *nodename, const char *prepath)
133133
* Caller is responsible for freeing returned value if it is not error.
134134
*/
135135
char *cifs_compose_mount_options(const char *sb_mountdata,
136-
const char *fullpath,
137-
const struct dfs_info3_param *ref)
136+
const char *fullpath,
137+
const struct dfs_info3_param *ref,
138+
char **devname)
138139
{
139140
int rc;
140141
char *name;
@@ -231,7 +232,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
231232
strcat(mountdata, "ip=");
232233
strcat(mountdata, srvIP);
233234

234-
kfree(name);
235+
if (devname)
236+
*devname = name;
237+
else
238+
kfree(name);
235239

236240
/*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
237241
/*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
@@ -278,7 +282,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
278282

279283
/* strip first '\' from fullpath */
280284
mountdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
281-
fullpath + 1, NULL);
285+
fullpath + 1, NULL, NULL);
282286
if (IS_ERR(mountdata)) {
283287
kfree(devname);
284288
return (struct vfsmount *)mountdata;

fs/cifs/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
822822
goto out;
823823
}
824824

825-
rc = cifs_setup_volume_info(cifs_sb->ctx);
825+
rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC);
826826
if (rc) {
827827
root = ERR_PTR(rc);
828828
goto out;

fs/cifs/cifsproto.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
7878
int add_treename);
7979
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
8080
extern char *cifs_compose_mount_options(const char *sb_mountdata,
81-
const char *fullpath, const struct dfs_info3_param *ref);
81+
const char *fullpath, const struct dfs_info3_param *ref,
82+
char **devname);
8283
/* extern void renew_parental_timestamps(struct dentry *direntry);*/
8384
extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
8485
struct TCP_Server_Info *server);
@@ -89,6 +90,7 @@ extern void cifs_wake_up_task(struct mid_q_entry *mid);
8990
extern int cifs_handle_standard(struct TCP_Server_Info *server,
9091
struct mid_q_entry *mid);
9192
extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
93+
extern int smb3_parse_opt(const char *options, const char *key, char **val);
9294
extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
9395
extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
9496
extern int cifs_call_async(struct TCP_Server_Info *server,
@@ -549,7 +551,7 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
549551
unsigned char *p24);
550552

551553
extern int
552-
cifs_setup_volume_info(struct smb3_fs_context *ctx);
554+
cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
553555

554556
extern struct TCP_Server_Info *
555557
cifs_find_tcp_session(struct smb3_fs_context *ctx);

fs/cifs/connect.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,17 +2972,20 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
29722972
rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
29732973
ref_path, &referral, NULL);
29742974
if (!rc) {
2975+
char *fake_devname = NULL;
2976+
29752977
mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
2976-
full_path + 1, &referral);
2978+
full_path + 1, &referral,
2979+
&fake_devname);
29772980
free_dfs_info_param(&referral);
29782981

29792982
if (IS_ERR(mdata)) {
29802983
rc = PTR_ERR(mdata);
29812984
mdata = NULL;
29822985
} else {
2983-
smb3_cleanup_fs_context_contents(ctx);
2984-
rc = cifs_setup_volume_info(ctx);
2986+
rc = cifs_setup_volume_info(ctx, mdata, fake_devname);
29852987
}
2988+
kfree(fake_devname);
29862989
kfree(cifs_sb->ctx->mount_options);
29872990
cifs_sb->ctx->mount_options = mdata;
29882991
}
@@ -3036,6 +3039,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
30363039
struct dfs_info3_param ref = {0};
30373040
char *mdata = NULL;
30383041
struct smb3_fs_context fake_ctx = {NULL};
3042+
char *fake_devname = NULL;
30393043

30403044
cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path);
30413045

@@ -3044,16 +3048,18 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
30443048
return rc;
30453049

30463050
mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
3047-
full_path + 1, &ref);
3051+
full_path + 1, &ref,
3052+
&fake_devname);
30483053
free_dfs_info_param(&ref);
30493054

30503055
if (IS_ERR(mdata)) {
30513056
rc = PTR_ERR(mdata);
30523057
mdata = NULL;
30533058
} else
3054-
rc = cifs_setup_volume_info(&fake_ctx);
3059+
rc = cifs_setup_volume_info(&fake_ctx, mdata, fake_devname);
30553060

30563061
kfree(mdata);
3062+
kfree(fake_devname);
30573063

30583064
if (!rc) {
30593065
/*
@@ -3122,10 +3128,24 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_
31223128
* we should pass a clone of the original context?
31233129
*/
31243130
int
3125-
cifs_setup_volume_info(struct smb3_fs_context *ctx)
3131+
cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname)
31263132
{
31273133
int rc = 0;
31283134

3135+
smb3_parse_devname(devname, ctx);
3136+
3137+
if (mntopts) {
3138+
char *ip;
3139+
3140+
cifs_dbg(FYI, "%s: mntopts=%s\n", __func__, mntopts);
3141+
rc = smb3_parse_opt(mntopts, "ip", &ip);
3142+
if (!rc && !cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip,
3143+
strlen(ip))) {
3144+
cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__);
3145+
return -EINVAL;
3146+
}
3147+
}
3148+
31293149
if (ctx->nullauth) {
31303150
cifs_dbg(FYI, "Anonymous login\n");
31313151
kfree(ctx->username);

fs/cifs/dfs_cache.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
14171417
int rc;
14181418
struct cache_entry *ce;
14191419
struct dfs_info3_param ref = {0};
1420-
char *mdata = NULL;
1420+
char *mdata = NULL, *devname = NULL;
14211421
struct TCP_Server_Info *server;
14221422
struct cifs_ses *ses;
14231423
struct smb3_fs_context ctx = {NULL};
@@ -1444,7 +1444,8 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
14441444

14451445
up_read(&htable_rw_lock);
14461446

1447-
mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref);
1447+
mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref,
1448+
&devname);
14481449
free_dfs_info_param(&ref);
14491450

14501451
if (IS_ERR(mdata)) {
@@ -1453,7 +1454,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
14531454
goto out;
14541455
}
14551456

1456-
rc = cifs_setup_volume_info(&ctx);
1457+
rc = cifs_setup_volume_info(&ctx, NULL, devname);
14571458

14581459
if (rc) {
14591460
ses = ERR_PTR(rc);
@@ -1472,6 +1473,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
14721473
smb3_cleanup_fs_context_contents(&ctx);
14731474
kfree(mdata);
14741475
kfree(rpath);
1476+
kfree(devname);
14751477

14761478
return ses;
14771479
}

fs/cifs/fs_context.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,10 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
175175
fsparam_flag_no("exec", Opt_ignore),
176176
fsparam_flag_no("dev", Opt_ignore),
177177
fsparam_flag_no("mand", Opt_ignore),
178+
fsparam_flag_no("auto", Opt_ignore),
178179
fsparam_string("cred", Opt_ignore),
179180
fsparam_string("credentials", Opt_ignore),
181+
fsparam_string("prefixpath", Opt_ignore),
180182
{}
181183
};
182184

@@ -399,6 +401,37 @@ cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3)
399401
return 0;
400402
}
401403

404+
int smb3_parse_opt(const char *options, const char *key, char **val)
405+
{
406+
int rc = -ENOENT;
407+
char *opts, *orig, *p;
408+
409+
orig = opts = kstrdup(options, GFP_KERNEL);
410+
if (!opts)
411+
return -ENOMEM;
412+
413+
while ((p = strsep(&opts, ","))) {
414+
char *nval;
415+
416+
if (!*p)
417+
continue;
418+
if (strncasecmp(p, key, strlen(key)))
419+
continue;
420+
nval = strchr(p, '=');
421+
if (nval) {
422+
if (nval == p)
423+
continue;
424+
*nval++ = 0;
425+
*val = kstrndup(nval, strlen(nval), GFP_KERNEL);
426+
rc = !*val ? -ENOMEM : 0;
427+
goto out;
428+
}
429+
}
430+
out:
431+
kfree(orig);
432+
return rc;
433+
}
434+
402435
/*
403436
* Parse a devname into substrings and populate the ctx->UNC and ctx->prepath
404437
* fields with the result. Returns 0 on success and an error otherwise
@@ -531,7 +564,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
531564

532565
if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) {
533566
cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
534-
return -1;
567+
return -EOPNOTSUPP;
535568
}
536569

537570
#ifndef CONFIG_KEYS
@@ -554,7 +587,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
554587
/* make sure UNC has a share name */
555588
if (strlen(ctx->UNC) < 3 || !strchr(ctx->UNC + 3, '\\')) {
556589
cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
557-
return -1;
590+
return -ENOENT;
558591
}
559592

560593
if (!ctx->got_ip) {
@@ -568,7 +601,7 @@ static int smb3_fs_context_validate(struct fs_context *fc)
568601
if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
569602
&ctx->UNC[2], len)) {
570603
pr_err("Unable to determine destination address\n");
571-
return -1;
604+
return -EHOSTUNREACH;
572605
}
573606
}
574607

@@ -1263,7 +1296,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
12631296
return 0;
12641297

12651298
cifs_parse_mount_err:
1266-
return 1;
1299+
return -EINVAL;
12671300
}
12681301

12691302
int smb3_init_fs_context(struct fs_context *fc)

0 commit comments

Comments
 (0)