diff options
| -rw-r--r-- | include/linux/sunrpc/clnt.h | 1 | ||||
| -rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 2 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 24 | ||||
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 22 |
4 files changed, 35 insertions, 14 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index e37c06128e51..8fe9f35eba31 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h | |||
| @@ -60,6 +60,7 @@ struct rpc_clnt { | |||
| 60 | int cl_nodelen; /* nodename length */ | 60 | int cl_nodelen; /* nodename length */ |
| 61 | char cl_nodename[UNX_MAXNODENAME]; | 61 | char cl_nodename[UNX_MAXNODENAME]; |
| 62 | char cl_pathname[30];/* Path in rpc_pipe_fs */ | 62 | char cl_pathname[30];/* Path in rpc_pipe_fs */ |
| 63 | struct vfsmount * cl_vfsmnt; | ||
| 63 | struct dentry * cl_dentry; /* inode */ | 64 | struct dentry * cl_dentry; /* inode */ |
| 64 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ | 65 | struct rpc_clnt * cl_parent; /* Points to parent of clones */ |
| 65 | struct rpc_rtt cl_rtt_default; | 66 | struct rpc_rtt cl_rtt_default; |
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index 63929349571f..2c2189cb30aa 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h | |||
| @@ -45,6 +45,8 @@ extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); | |||
| 45 | extern int rpc_rmdir(char *); | 45 | extern int rpc_rmdir(char *); |
| 46 | extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); | 46 | extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); |
| 47 | extern int rpc_unlink(char *); | 47 | extern int rpc_unlink(char *); |
| 48 | extern struct vfsmount *rpc_get_mount(void); | ||
| 49 | extern void rpc_put_mount(void); | ||
| 48 | 50 | ||
| 49 | #endif | 51 | #endif |
| 50 | #endif | 52 | #endif |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 0bb23e8e9d0c..9f775302d1df 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -70,8 +70,15 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | |||
| 70 | static uint32_t clntid; | 70 | static uint32_t clntid; |
| 71 | int error; | 71 | int error; |
| 72 | 72 | ||
| 73 | clnt->cl_vfsmnt = ERR_PTR(-ENOENT); | ||
| 74 | clnt->cl_dentry = ERR_PTR(-ENOENT); | ||
| 73 | if (dir_name == NULL) | 75 | if (dir_name == NULL) |
| 74 | return 0; | 76 | return 0; |
| 77 | |||
| 78 | clnt->cl_vfsmnt = rpc_get_mount(); | ||
| 79 | if (IS_ERR(clnt->cl_vfsmnt)) | ||
| 80 | return PTR_ERR(clnt->cl_vfsmnt); | ||
| 81 | |||
| 75 | for (;;) { | 82 | for (;;) { |
| 76 | snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), | 83 | snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname), |
| 77 | "%s/clnt%x", dir_name, | 84 | "%s/clnt%x", dir_name, |
| @@ -84,6 +91,7 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name) | |||
| 84 | if (error != -EEXIST) { | 91 | if (error != -EEXIST) { |
| 85 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", | 92 | printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n", |
| 86 | clnt->cl_pathname, error); | 93 | clnt->cl_pathname, error); |
| 94 | rpc_put_mount(); | ||
| 87 | return error; | 95 | return error; |
| 88 | } | 96 | } |
| 89 | } | 97 | } |
| @@ -175,7 +183,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
| 175 | return clnt; | 183 | return clnt; |
| 176 | 184 | ||
| 177 | out_no_auth: | 185 | out_no_auth: |
| 178 | rpc_rmdir(clnt->cl_pathname); | 186 | if (!IS_ERR(clnt->cl_dentry)) { |
| 187 | rpc_rmdir(clnt->cl_pathname); | ||
| 188 | dput(clnt->cl_dentry); | ||
| 189 | rpc_put_mount(); | ||
| 190 | } | ||
| 179 | out_no_path: | 191 | out_no_path: |
| 180 | if (clnt->cl_server != clnt->cl_inline_name) | 192 | if (clnt->cl_server != clnt->cl_inline_name) |
| 181 | kfree(clnt->cl_server); | 193 | kfree(clnt->cl_server); |
| @@ -240,13 +252,15 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
| 240 | new->cl_autobind = 0; | 252 | new->cl_autobind = 0; |
| 241 | new->cl_oneshot = 0; | 253 | new->cl_oneshot = 0; |
| 242 | new->cl_dead = 0; | 254 | new->cl_dead = 0; |
| 243 | dget(new->cl_dentry); | 255 | if (!IS_ERR(new->cl_dentry)) { |
| 256 | dget(new->cl_dentry); | ||
| 257 | rpc_get_mount(); | ||
| 258 | } | ||
| 244 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); | 259 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); |
| 245 | if (new->cl_auth) | 260 | if (new->cl_auth) |
| 246 | atomic_inc(&new->cl_auth->au_count); | 261 | atomic_inc(&new->cl_auth->au_count); |
| 247 | new->cl_pmap = &new->cl_pmap_default; | 262 | new->cl_pmap = &new->cl_pmap_default; |
| 248 | new->cl_metrics = rpc_alloc_iostats(clnt); | 263 | new->cl_metrics = rpc_alloc_iostats(clnt); |
| 249 | rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait"); | ||
| 250 | return new; | 264 | return new; |
| 251 | out_no_clnt: | 265 | out_no_clnt: |
| 252 | printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); | 266 | printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); |
| @@ -318,8 +332,10 @@ rpc_destroy_client(struct rpc_clnt *clnt) | |||
| 318 | out_free: | 332 | out_free: |
| 319 | rpc_free_iostats(clnt->cl_metrics); | 333 | rpc_free_iostats(clnt->cl_metrics); |
| 320 | clnt->cl_metrics = NULL; | 334 | clnt->cl_metrics = NULL; |
| 321 | if (clnt->cl_dentry) | 335 | if (!IS_ERR(clnt->cl_dentry)) { |
| 322 | dput(clnt->cl_dentry); | 336 | dput(clnt->cl_dentry); |
| 337 | rpc_put_mount(); | ||
| 338 | } | ||
| 323 | kfree(clnt); | 339 | kfree(clnt); |
| 324 | return 0; | 340 | return 0; |
| 325 | } | 341 | } |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 72b22172f0af..391d2bfc71aa 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -435,14 +435,17 @@ static struct rpc_filelist authfiles[] = { | |||
| 435 | }, | 435 | }, |
| 436 | }; | 436 | }; |
| 437 | 437 | ||
| 438 | static int | 438 | struct vfsmount *rpc_get_mount(void) |
| 439 | rpc_get_mount(void) | ||
| 440 | { | 439 | { |
| 441 | return simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); | 440 | int err; |
| 441 | |||
| 442 | err = simple_pin_fs("rpc_pipefs", &rpc_mount, &rpc_mount_count); | ||
| 443 | if (err != 0) | ||
| 444 | return ERR_PTR(err); | ||
| 445 | return rpc_mount; | ||
| 442 | } | 446 | } |
| 443 | 447 | ||
| 444 | static void | 448 | void rpc_put_mount(void) |
| 445 | rpc_put_mount(void) | ||
| 446 | { | 449 | { |
| 447 | simple_release_fs(&rpc_mount, &rpc_mount_count); | 450 | simple_release_fs(&rpc_mount, &rpc_mount_count); |
| 448 | } | 451 | } |
| @@ -452,12 +455,13 @@ rpc_lookup_parent(char *path, struct nameidata *nd) | |||
| 452 | { | 455 | { |
| 453 | if (path[0] == '\0') | 456 | if (path[0] == '\0') |
| 454 | return -ENOENT; | 457 | return -ENOENT; |
| 455 | if (rpc_get_mount()) { | 458 | nd->mnt = rpc_get_mount(); |
| 459 | if (IS_ERR(nd->mnt)) { | ||
| 456 | printk(KERN_WARNING "%s: %s failed to mount " | 460 | printk(KERN_WARNING "%s: %s failed to mount " |
| 457 | "pseudofilesystem \n", __FILE__, __FUNCTION__); | 461 | "pseudofilesystem \n", __FILE__, __FUNCTION__); |
| 458 | return -ENODEV; | 462 | return PTR_ERR(nd->mnt); |
| 459 | } | 463 | } |
| 460 | nd->mnt = mntget(rpc_mount); | 464 | mntget(nd->mnt); |
| 461 | nd->dentry = dget(rpc_mount->mnt_root); | 465 | nd->dentry = dget(rpc_mount->mnt_root); |
| 462 | nd->last_type = LAST_ROOT; | 466 | nd->last_type = LAST_ROOT; |
| 463 | nd->flags = LOOKUP_PARENT; | 467 | nd->flags = LOOKUP_PARENT; |
| @@ -594,7 +598,6 @@ __rpc_mkdir(struct inode *dir, struct dentry *dentry) | |||
| 594 | d_instantiate(dentry, inode); | 598 | d_instantiate(dentry, inode); |
| 595 | dir->i_nlink++; | 599 | dir->i_nlink++; |
| 596 | inode_dir_notify(dir, DN_CREATE); | 600 | inode_dir_notify(dir, DN_CREATE); |
| 597 | rpc_get_mount(); | ||
| 598 | return 0; | 601 | return 0; |
| 599 | out_err: | 602 | out_err: |
| 600 | printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", | 603 | printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n", |
| @@ -615,7 +618,6 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 615 | if (!error) { | 618 | if (!error) { |
| 616 | inode_dir_notify(dir, DN_DELETE); | 619 | inode_dir_notify(dir, DN_DELETE); |
| 617 | d_drop(dentry); | 620 | d_drop(dentry); |
| 618 | rpc_put_mount(); | ||
| 619 | } | 621 | } |
| 620 | return 0; | 622 | return 0; |
| 621 | } | 623 | } |
