Loading include/linux/sunrpc/clnt.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct rpc_clnt { int cl_nodelen; /* nodename length */ char cl_nodename[UNX_MAXNODENAME]; char cl_pathname[30];/* Path in rpc_pipe_fs */ struct vfsmount * cl_vfsmnt; struct dentry * cl_dentry; /* inode */ struct rpc_clnt * cl_parent; /* Points to parent of clones */ struct rpc_rtt cl_rtt_default; Loading include/linux/sunrpc/rpc_pipe_fs.h +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); extern int rpc_rmdir(char *); extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); extern int rpc_unlink(char *); extern struct vfsmount *rpc_get_mount(void); extern void rpc_put_mount(void); #endif #endif net/sunrpc/clnt.c +20 −4 Original line number Diff line number Diff line Loading @@ -70,8 +70,15 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) static uint32_t clntid; int error; clnt->cl_vfsmnt = ERR_PTR(-ENOENT); clnt->cl_dentry = ERR_PTR(-ENOENT); if (dir_name == NULL) return 0; clnt->cl_vfsmnt = rpc_get_mount(); if (IS_ERR(clnt->cl_vfsmnt)) return PTR_ERR(clnt->cl_vfsmnt); for (;;) { snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), "%s/clnt%x", dir_name, Loading @@ -84,6 +91,7 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) if (error != -EEXIST) { printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", clnt->cl_pathname, error); rpc_put_mount(); return error; } } Loading Loading @@ -175,7 +183,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, return clnt; out_no_auth: if (!IS_ERR(clnt->cl_dentry)) { rpc_rmdir(clnt->cl_pathname); dput(clnt->cl_dentry); rpc_put_mount(); } out_no_path: if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); Loading Loading @@ -240,13 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt) new->cl_autobind = 0; new->cl_oneshot = 0; new->cl_dead = 0; if (!IS_ERR(new->cl_dentry)) { dget(new->cl_dentry); rpc_get_mount(); } rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); new->cl_pmap = &new->cl_pmap_default; new->cl_metrics = rpc_alloc_iostats(clnt); rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); return new; out_no_clnt: printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); Loading Loading @@ -318,8 +332,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) out_free: rpc_free_iostats(clnt->cl_metrics); clnt->cl_metrics = NULL; if (clnt->cl_dentry) if (!IS_ERR(clnt->cl_dentry)) { dput(clnt->cl_dentry); rpc_put_mount(); } kfree(clnt); return 0; } Loading net/sunrpc/rpc_pipe.c +12 −10 Original line number Diff line number Diff line Loading @@ -435,14 +435,17 @@ static struct rpc_filelist authfiles[] = { }, }; static int rpc_get_mount(void) struct vfsmount *rpc_get_mount(void) { return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); int err; err = simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); if (err != 0) return ERR_PTR(err); return rpc_mount; } static void rpc_put_mount(void) void rpc_put_mount(void) { simple_release_fs(&rpc_mount, &rpc_mount_count); } Loading @@ -452,12 +455,13 @@ rpc_lookup_parent(char *path, struct nameidata *nd) { if (path[0] == '\0') return -ENOENT; if (rpc_get_mount()) { nd->mnt = rpc_get_mount(); if (IS_ERR(nd->mnt)) { printk(KERN_WARNING "%s: %s failed to mount " "pseudofilesystem \n", __FILE__, __FUNCTION__); return -ENODEV; return PTR_ERR(nd->mnt); } nd->mnt = mntget(rpc_mount); mntget(nd->mnt); nd->dentry = dget(rpc_mount->mnt_root); nd->last_type = LAST_ROOT; nd->flags = LOOKUP_PARENT; Loading Loading @@ -594,7 +598,6 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry) d_instantiate(dentry, inode); dir->i_nlink++; inode_dir_notify(dir, DN_CREATE); rpc_get_mount(); return 0; out_err: printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", Loading @@ -615,7 +618,6 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) if (!error) { inode_dir_notify(dir, DN_DELETE); d_drop(dentry); rpc_put_mount(); } return 0; } Loading Loading
include/linux/sunrpc/clnt.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ struct rpc_clnt { int cl_nodelen; /* nodename length */ char cl_nodename[UNX_MAXNODENAME]; char cl_pathname[30];/* Path in rpc_pipe_fs */ struct vfsmount * cl_vfsmnt; struct dentry * cl_dentry; /* inode */ struct rpc_clnt * cl_parent; /* Points to parent of clones */ struct rpc_rtt cl_rtt_default; Loading
include/linux/sunrpc/rpc_pipe_fs.h +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); extern int rpc_rmdir(char *); extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); extern int rpc_unlink(char *); extern struct vfsmount *rpc_get_mount(void); extern void rpc_put_mount(void); #endif #endif
net/sunrpc/clnt.c +20 −4 Original line number Diff line number Diff line Loading @@ -70,8 +70,15 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) static uint32_t clntid; int error; clnt->cl_vfsmnt = ERR_PTR(-ENOENT); clnt->cl_dentry = ERR_PTR(-ENOENT); if (dir_name == NULL) return 0; clnt->cl_vfsmnt = rpc_get_mount(); if (IS_ERR(clnt->cl_vfsmnt)) return PTR_ERR(clnt->cl_vfsmnt); for (;;) { snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), "%s/clnt%x", dir_name, Loading @@ -84,6 +91,7 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) if (error != -EEXIST) { printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", clnt->cl_pathname, error); rpc_put_mount(); return error; } } Loading Loading @@ -175,7 +183,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, return clnt; out_no_auth: if (!IS_ERR(clnt->cl_dentry)) { rpc_rmdir(clnt->cl_pathname); dput(clnt->cl_dentry); rpc_put_mount(); } out_no_path: if (clnt->cl_server != clnt->cl_inline_name) kfree(clnt->cl_server); Loading Loading @@ -240,13 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt) new->cl_autobind = 0; new->cl_oneshot = 0; new->cl_dead = 0; if (!IS_ERR(new->cl_dentry)) { dget(new->cl_dentry); rpc_get_mount(); } rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); new->cl_pmap = &new->cl_pmap_default; new->cl_metrics = rpc_alloc_iostats(clnt); rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); return new; out_no_clnt: printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); Loading Loading @@ -318,8 +332,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) out_free: rpc_free_iostats(clnt->cl_metrics); clnt->cl_metrics = NULL; if (clnt->cl_dentry) if (!IS_ERR(clnt->cl_dentry)) { dput(clnt->cl_dentry); rpc_put_mount(); } kfree(clnt); return 0; } Loading
net/sunrpc/rpc_pipe.c +12 −10 Original line number Diff line number Diff line Loading @@ -435,14 +435,17 @@ static struct rpc_filelist authfiles[] = { }, }; static int rpc_get_mount(void) struct vfsmount *rpc_get_mount(void) { return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); int err; err = simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); if (err != 0) return ERR_PTR(err); return rpc_mount; } static void rpc_put_mount(void) void rpc_put_mount(void) { simple_release_fs(&rpc_mount, &rpc_mount_count); } Loading @@ -452,12 +455,13 @@ rpc_lookup_parent(char *path, struct nameidata *nd) { if (path[0] == '\0') return -ENOENT; if (rpc_get_mount()) { nd->mnt = rpc_get_mount(); if (IS_ERR(nd->mnt)) { printk(KERN_WARNING "%s: %s failed to mount " "pseudofilesystem \n", __FILE__, __FUNCTION__); return -ENODEV; return PTR_ERR(nd->mnt); } nd->mnt = mntget(rpc_mount); mntget(nd->mnt); nd->dentry = dget(rpc_mount->mnt_root); nd->last_type = LAST_ROOT; nd->flags = LOOKUP_PARENT; Loading Loading @@ -594,7 +598,6 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry) d_instantiate(dentry, inode); dir->i_nlink++; inode_dir_notify(dir, DN_CREATE); rpc_get_mount(); return 0; out_err: printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", Loading @@ -615,7 +618,6 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) if (!error) { inode_dir_notify(dir, DN_DELETE); d_drop(dentry); rpc_put_mount(); } return 0; } Loading