diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 7a7cda9f7912d1a7a05baa4e78b3507e1492d23e..db8a404a51dd03436653c0a52d0a6e5330bbe5bc 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -549,8 +549,8 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) char *s, *p; char sep; - full_path = cifs_build_path_to_root(vol, cifs_sb, - cifs_sb_master_tcon(cifs_sb)); + full_path = build_path_to_root(vol, cifs_sb, + cifs_sb_master_tcon(cifs_sb)); if (full_path == NULL) return ERR_PTR(-ENOMEM); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 2b1234599e727d4c37959939a3596d245d768281..340dce0ed07b1397e09a8203a90c63dbeba3fd03 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -164,6 +164,7 @@ struct cifs_ses; struct cifs_tcon; struct dfs_info3_param; struct cifs_fattr; +struct smb_vol; struct smb_version_operations { int (*send_cancel)(struct TCP_Server_Info *, void *, @@ -227,6 +228,9 @@ struct smb_version_operations { int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const char *, u64 *uniqueid, FILE_ALL_INFO *); + /* build a full path to the root of the mount */ + char * (*build_path_to_root)(struct smb_vol *, struct cifs_sb_info *, + struct cifs_tcon *); }; struct smb_version_values { @@ -803,6 +807,15 @@ convert_delimiter(char *path, char delim) } } +static inline char * +build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, + struct cifs_tcon *tcon) +{ + if (!vol->ops->build_path_to_root) + return NULL; + return vol->ops->build_path_to_root(vol, cifs_sb, tcon); +} + #ifdef CONFIG_CIFS_STATS #define cifs_stats_inc atomic_inc diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 8e93de01c79d66db43c4f23a771a4c6d44384ccd..334b867a81ff8cbf73f06df589e526347f707e4c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -57,9 +57,6 @@ extern int init_cifs_idmap(void); extern void exit_cifs_idmap(void); extern void cifs_destroy_idmaptrees(void); extern char *build_path_from_dentry(struct dentry *); -extern char *cifs_build_path_to_root(struct smb_vol *vol, - struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *cifs_compose_mount_options(const char *sb_mountdata, const char *fullpath, const struct dfs_info3_param *ref, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 34588fe11c5755756cbcccb4fd3afa80f61b525d..7b4bc1e0b08eaf95da0212890c35d7f11e617ce6 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3684,7 +3684,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) goto mount_fail_check; } /* build_path_to_root works only when we have a valid tcon */ - full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon); + full_path = build_path_to_root(volume_info, cifs_sb, tcon); if (full_path == NULL) { rc = -ENOMEM; goto mount_fail_check; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index df071fb2567fbfa0a64bea19d6de85f3a5ed83d4..def10064fe9d536f345333dc6bc575c2e99c5ed0 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -731,38 +731,6 @@ static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; -char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, - struct cifs_tcon *tcon) -{ - int pplen = vol->prepath ? strlen(vol->prepath) : 0; - int dfsplen; - char *full_path = NULL; - - /* if no prefix path, simply set path to the root of share to "" */ - if (pplen == 0) { - full_path = kmalloc(1, GFP_KERNEL); - if (full_path) - full_path[0] = 0; - return full_path; - } - - if (tcon->Flags & SMB_SHARE_IS_IN_DFS) - dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); - else - dfsplen = 0; - - full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); - if (full_path == NULL) - return full_path; - - if (dfsplen) - strncpy(full_path, tcon->treeName, dfsplen); - strncpy(full_path + dfsplen, vol->prepath, pplen); - convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); - full_path[dfsplen + pplen] = 0; /* add trailing null */ - return full_path; -} - static int cifs_find_inode(struct inode *inode, void *opaque) { diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index fa210010358d269e1c8bc1b1b2826282c5454af8..7195fadf1cfaeb6dd5f59ca7f609a7a23a1742a1 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -489,6 +489,37 @@ cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon, CIFS_MOUNT_MAP_SPECIAL_CHR); } +static char * +cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, + struct cifs_tcon *tcon) +{ + int pplen = vol->prepath ? strlen(vol->prepath) : 0; + int dfsplen; + char *full_path = NULL; + + /* if no prefix path, simply set path to the root of share to "" */ + if (pplen == 0) { + full_path = kzalloc(1, GFP_KERNEL); + return full_path; + } + + if (tcon->Flags & SMB_SHARE_IS_IN_DFS) + dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); + else + dfsplen = 0; + + full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); + if (full_path == NULL) + return full_path; + + if (dfsplen) + strncpy(full_path, tcon->treeName, dfsplen); + strncpy(full_path + dfsplen, vol->prepath, pplen); + convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); + full_path[dfsplen + pplen] = 0; /* add trailing null */ + return full_path; +} + struct smb_version_operations smb1_operations = { .send_cancel = send_nt_cancel, .compare_fids = cifs_compare_fids, @@ -518,6 +549,7 @@ struct smb_version_operations smb1_operations = { .is_path_accessible = cifs_is_path_accessible, .query_path_info = cifs_query_path_info, .get_srv_inum = cifs_get_srv_inum, + .build_path_to_root = cifs_build_path_to_root, }; struct smb_version_values smb1_values = {