Skip to content

Commit abdb174

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: get rid of mount options string parsing
After switching to filesystem context support, we no longer need to handle mount options string when chasing dfs referrals. Now, we set the new values directly into smb3_fs_context. Start working on a separate source file to handle most dfs related mount functions as connect.c has already became too big. The remaining functions will be moved gradually in follow-up patches. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 9fd29a5 commit abdb174

File tree

7 files changed

+101
-247
lines changed

7 files changed

+101
-247
lines changed

fs/cifs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ cifs-$(CONFIG_CIFS_XATTR) += xattr.o
2121

2222
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
2323

24-
cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o
24+
cifs-$(CONFIG_CIFS_DFS_UPCALL) += cifs_dfs_ref.o dfs_cache.o dfs.o
2525

2626
cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o cifs_swn.o
2727

fs/cifs/cifs_dfs_ref.c

Lines changed: 1 addition & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void cifs_dfs_release_automount_timer(void)
6060
* Returns pointer to the built string, or a ERR_PTR. Caller is responsible
6161
* for freeing the returned string.
6262
*/
63-
static char *
63+
char *
6464
cifs_build_devname(char *nodename, const char *prepath)
6565
{
6666
size_t pplen;
@@ -119,145 +119,6 @@ cifs_build_devname(char *nodename, const char *prepath)
119119
return dev;
120120
}
121121

122-
123-
/**
124-
* cifs_compose_mount_options - creates mount options for referral
125-
* @sb_mountdata: parent/root DFS mount options (template)
126-
* @fullpath: full path in UNC format
127-
* @ref: optional server's referral
128-
* @devname: return the built cifs device name if passed pointer not NULL
129-
* creates mount options for submount based on template options sb_mountdata
130-
* and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
131-
*
132-
* Returns: pointer to new mount options or ERR_PTR.
133-
* Caller is responsible for freeing returned value if it is not error.
134-
*/
135-
char *cifs_compose_mount_options(const char *sb_mountdata,
136-
const char *fullpath,
137-
const struct dfs_info3_param *ref,
138-
char **devname)
139-
{
140-
int rc;
141-
char *name;
142-
char *mountdata = NULL;
143-
const char *prepath = NULL;
144-
int md_len;
145-
char *tkn_e;
146-
char *srvIP = NULL;
147-
char sep = ',';
148-
int off, noff;
149-
150-
if (sb_mountdata == NULL)
151-
return ERR_PTR(-EINVAL);
152-
153-
if (ref) {
154-
if (WARN_ON_ONCE(!ref->node_name || ref->path_consumed < 0))
155-
return ERR_PTR(-EINVAL);
156-
157-
if (strlen(fullpath) - ref->path_consumed) {
158-
prepath = fullpath + ref->path_consumed;
159-
/* skip initial delimiter */
160-
if (*prepath == '/' || *prepath == '\\')
161-
prepath++;
162-
}
163-
164-
name = cifs_build_devname(ref->node_name, prepath);
165-
if (IS_ERR(name)) {
166-
rc = PTR_ERR(name);
167-
name = NULL;
168-
goto compose_mount_options_err;
169-
}
170-
} else {
171-
name = cifs_build_devname((char *)fullpath, NULL);
172-
if (IS_ERR(name)) {
173-
rc = PTR_ERR(name);
174-
name = NULL;
175-
goto compose_mount_options_err;
176-
}
177-
}
178-
179-
rc = dns_resolve_server_name_to_ip(name, &srvIP, NULL);
180-
if (rc < 0) {
181-
cifs_dbg(FYI, "%s: Failed to resolve server part of %s to IP: %d\n",
182-
__func__, name, rc);
183-
goto compose_mount_options_err;
184-
}
185-
186-
/*
187-
* In most cases, we'll be building a shorter string than the original,
188-
* but we do have to assume that the address in the ip= option may be
189-
* much longer than the original. Add the max length of an address
190-
* string to the length of the original string to allow for worst case.
191-
*/
192-
md_len = strlen(sb_mountdata) + INET6_ADDRSTRLEN;
193-
mountdata = kzalloc(md_len + sizeof("ip=") + 1, GFP_KERNEL);
194-
if (mountdata == NULL) {
195-
rc = -ENOMEM;
196-
goto compose_mount_options_err;
197-
}
198-
199-
/* copy all options except of unc,ip,prefixpath */
200-
off = 0;
201-
if (strncmp(sb_mountdata, "sep=", 4) == 0) {
202-
sep = sb_mountdata[4];
203-
strncpy(mountdata, sb_mountdata, 5);
204-
off += 5;
205-
}
206-
207-
do {
208-
tkn_e = strchr(sb_mountdata + off, sep);
209-
if (tkn_e == NULL)
210-
noff = strlen(sb_mountdata + off);
211-
else
212-
noff = tkn_e - (sb_mountdata + off) + 1;
213-
214-
if (strncasecmp(sb_mountdata + off, "cruid=", 6) == 0) {
215-
off += noff;
216-
continue;
217-
}
218-
if (strncasecmp(sb_mountdata + off, "unc=", 4) == 0) {
219-
off += noff;
220-
continue;
221-
}
222-
if (strncasecmp(sb_mountdata + off, "ip=", 3) == 0) {
223-
off += noff;
224-
continue;
225-
}
226-
if (strncasecmp(sb_mountdata + off, "prefixpath=", 11) == 0) {
227-
off += noff;
228-
continue;
229-
}
230-
strncat(mountdata, sb_mountdata + off, noff);
231-
off += noff;
232-
} while (tkn_e);
233-
strcat(mountdata, sb_mountdata + off);
234-
mountdata[md_len] = '\0';
235-
236-
/* copy new IP and ref share name */
237-
if (mountdata[strlen(mountdata) - 1] != sep)
238-
strncat(mountdata, &sep, 1);
239-
strcat(mountdata, "ip=");
240-
strcat(mountdata, srvIP);
241-
242-
if (devname)
243-
*devname = name;
244-
else
245-
kfree(name);
246-
247-
/*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
248-
/*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
249-
250-
compose_mount_options_out:
251-
kfree(srvIP);
252-
return mountdata;
253-
254-
compose_mount_options_err:
255-
kfree(mountdata);
256-
mountdata = ERR_PTR(rc);
257-
kfree(name);
258-
goto compose_mount_options_out;
259-
}
260-
261122
/*
262123
* Create a vfsmount that we can automount
263124
*/

fs/cifs/cifsfs.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -896,12 +896,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
896896
goto out;
897897
}
898898

899-
rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, NULL);
900-
if (rc) {
901-
root = ERR_PTR(rc);
902-
goto out;
903-
}
904-
905899
rc = cifs_setup_cifs_sb(cifs_sb);
906900
if (rc) {
907901
root = ERR_PTR(rc);

fs/cifs/cifsproto.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
7575
struct cifs_tcon *tcon,
7676
int add_treename);
7777
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
78-
extern char *cifs_compose_mount_options(const char *sb_mountdata,
79-
const char *fullpath, const struct dfs_info3_param *ref,
80-
char **devname);
78+
char *cifs_build_devname(char *nodename, const char *prepath);
8179
extern void delete_mid(struct mid_q_entry *mid);
8280
extern void release_mid(struct mid_q_entry *mid);
8381
extern void cifs_wake_up_task(struct mid_q_entry *mid);
@@ -561,9 +559,6 @@ extern int check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
561559
extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
562560
const struct nls_table *codepage);
563561

564-
extern int
565-
cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname);
566-
567562
extern struct TCP_Server_Info *
568563
cifs_find_tcp_session(struct smb3_fs_context *ctx);
569564

fs/cifs/connect.c

Lines changed: 6 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "smbdirect.h"
4747
#include "dns_resolve.h"
4848
#ifdef CONFIG_CIFS_DFS_UPCALL
49+
#include "dfs.h"
4950
#include "dfs_cache.h"
5051
#endif
5152
#include "fs_context.h"
@@ -3397,95 +3398,8 @@ build_unc_path_to_root(const struct smb3_fs_context *ctx,
33973398
cifs_dbg(FYI, "%s: full_path=%s\n", __func__, full_path);
33983399
return full_path;
33993400
}
3400-
3401-
/*
3402-
* expand_dfs_referral - Update cifs_sb from dfs referral path
3403-
*
3404-
* cifs_sb->ctx->mount_options will be (re-)allocated to a string containing updated options for the
3405-
* submount. Otherwise it will be left untouched.
3406-
*/
3407-
static int expand_dfs_referral(struct mount_ctx *mnt_ctx, const char *full_path,
3408-
struct dfs_info3_param *referral)
3409-
{
3410-
int rc;
3411-
struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
3412-
struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
3413-
char *fake_devname = NULL, *mdata = NULL;
3414-
3415-
mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options, full_path + 1, referral,
3416-
&fake_devname);
3417-
if (IS_ERR(mdata)) {
3418-
rc = PTR_ERR(mdata);
3419-
mdata = NULL;
3420-
} else {
3421-
/*
3422-
* We can not clear out the whole structure since we no longer have an explicit
3423-
* function to parse a mount-string. Instead we need to clear out the individual
3424-
* fields that are no longer valid.
3425-
*/
3426-
kfree(ctx->prepath);
3427-
ctx->prepath = NULL;
3428-
rc = cifs_setup_volume_info(ctx, mdata, fake_devname);
3429-
}
3430-
kfree(fake_devname);
3431-
kfree(cifs_sb->ctx->mount_options);
3432-
cifs_sb->ctx->mount_options = mdata;
3433-
3434-
return rc;
3435-
}
34363401
#endif
34373402

3438-
/* TODO: all callers to this are broken. We are not parsing mount_options here
3439-
* we should pass a clone of the original context?
3440-
*/
3441-
int
3442-
cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname)
3443-
{
3444-
int rc;
3445-
3446-
if (devname) {
3447-
cifs_dbg(FYI, "%s: devname=%s\n", __func__, devname);
3448-
rc = smb3_parse_devname(devname, ctx);
3449-
if (rc) {
3450-
cifs_dbg(VFS, "%s: failed to parse %s: %d\n", __func__, devname, rc);
3451-
return rc;
3452-
}
3453-
}
3454-
3455-
if (mntopts) {
3456-
char *ip;
3457-
3458-
rc = smb3_parse_opt(mntopts, "ip", &ip);
3459-
if (rc) {
3460-
cifs_dbg(VFS, "%s: failed to parse ip options: %d\n", __func__, rc);
3461-
return rc;
3462-
}
3463-
3464-
rc = cifs_convert_address((struct sockaddr *)&ctx->dstaddr, ip, strlen(ip));
3465-
kfree(ip);
3466-
if (!rc) {
3467-
cifs_dbg(VFS, "%s: failed to convert ip address\n", __func__);
3468-
return -EINVAL;
3469-
}
3470-
}
3471-
3472-
if (ctx->nullauth) {
3473-
cifs_dbg(FYI, "Anonymous login\n");
3474-
kfree(ctx->username);
3475-
ctx->username = NULL;
3476-
} else if (ctx->username) {
3477-
/* BB fixme parse for domain name here */
3478-
cifs_dbg(FYI, "Username: %s\n", ctx->username);
3479-
} else {
3480-
cifs_dbg(VFS, "No username specified\n");
3481-
/* In userspace mount helper we can get user name from alternate
3482-
locations such as env variables and files on disk */
3483-
return -EINVAL;
3484-
}
3485-
3486-
return 0;
3487-
}
3488-
34893403
static int
34903404
cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
34913405
unsigned int xid,
@@ -3630,7 +3544,6 @@ static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path,
36303544
int rc;
36313545
struct dfs_info3_param ref = {};
36323546
struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
3633-
char *oldmnt = cifs_sb->ctx->mount_options;
36343547

36353548
cifs_dbg(FYI, "%s: full_path=%s ref_path=%s target=%s\n", __func__, full_path, ref_path,
36363549
dfs_cache_get_tgt_name(tit));
@@ -3639,15 +3552,14 @@ static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path,
36393552
if (rc)
36403553
goto out;
36413554

3642-
rc = expand_dfs_referral(mnt_ctx, full_path, &ref);
3555+
rc = dfs_parse_target_referral(full_path + 1, &ref, mnt_ctx->fs_ctx);
36433556
if (rc)
36443557
goto out;
36453558

3646-
/* Connect to new target only if we were redirected (e.g. mount options changed) */
3647-
if (oldmnt != cifs_sb->ctx->mount_options) {
3648-
mount_put_conns(mnt_ctx);
3649-
rc = mount_get_dfs_conns(mnt_ctx);
3650-
}
3559+
/* XXX: maybe check if we were actually redirected and avoid reconnecting? */
3560+
mount_put_conns(mnt_ctx);
3561+
rc = mount_get_dfs_conns(mnt_ctx);
3562+
36513563
if (!rc) {
36523564
if (cifs_is_referral_server(mnt_ctx->tcon, &ref))
36533565
set_root_ses(mnt_ctx);

0 commit comments

Comments
 (0)