Skip to content

Commit 0157d02

Browse files
Stanislav KinsburskyTrond Myklebust
authored andcommitted
SUNRPC: handle RPC client pipefs dentries by network namespace aware routines
v2: 1) "Over-put" of PipeFS mount point fixed. Fix is ugly, but allows to bisect the patch set. And it will be removed later in the series. This patch makes RPC clients PipeFs dentries allocations in it's owner network namespace context. RPC client pipefs dentries creation logic has been changed: 1) Pipefs dentries creation by sb was moved to separated function, which will be used for handling PipeFS mount notification. 2) Initial value of RPC client PipeFS dir dentry is set no NULL now. RPC client pipefs dentries cleanup logic has been changed: 1) Cleanup is done now in separated rpc_remove_pipedir() function, which takes care about pipefs superblock locking. Also this patch removes slashes from cb_program.pipe_dir_name and from NFS_PIPE_DIRNAME to make rpc_d_lookup_sb() work. This doesn't affect vfs_path_lookup() results in nfs4blocklayout_init() since this slash is cutted off anyway in link_path_walk(). Signed-off-by: Stanislav Kinsbursky <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent c239d83 commit 0157d02

File tree

3 files changed

+66
-35
lines changed

3 files changed

+66
-35
lines changed

fs/nfsd/nfs4callback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ static struct rpc_program cb_program = {
622622
.nrvers = ARRAY_SIZE(nfs_cb_version),
623623
.version = nfs_cb_version,
624624
.stats = &cb_stats,
625-
.pipe_dir_name = "/nfsd4_cb",
625+
.pipe_dir_name = "nfsd4_cb",
626626
};
627627

628628
static int max_cb_time(void)

include/linux/nfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#define NFS_MNT_VERSION 1
3030
#define NFS_MNT3_VERSION 3
3131

32-
#define NFS_PIPE_DIRNAME "/nfs"
32+
#define NFS_PIPE_DIRNAME "nfs"
3333

3434
/*
3535
* NFS stats. The good thing with these values is that NFSv3 errors are

net/sunrpc/clnt.c

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -93,52 +93,89 @@ static void rpc_unregister_client(struct rpc_clnt *clnt)
9393
spin_unlock(&rpc_client_lock);
9494
}
9595

96-
static int
97-
rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
96+
static void __rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
97+
{
98+
if (clnt->cl_path.dentry)
99+
rpc_remove_client_dir(clnt->cl_path.dentry);
100+
clnt->cl_path.dentry = NULL;
101+
}
102+
103+
static void rpc_clnt_remove_pipedir(struct rpc_clnt *clnt)
104+
{
105+
struct super_block *pipefs_sb;
106+
int put_mnt = 0;
107+
108+
pipefs_sb = rpc_get_sb_net(clnt->cl_xprt->xprt_net);
109+
if (pipefs_sb) {
110+
if (clnt->cl_path.dentry)
111+
put_mnt = 1;
112+
__rpc_clnt_remove_pipedir(clnt);
113+
rpc_put_sb_net(clnt->cl_xprt->xprt_net);
114+
}
115+
if (put_mnt)
116+
rpc_put_mount();
117+
}
118+
119+
static struct dentry *rpc_setup_pipedir_sb(struct super_block *sb,
120+
struct rpc_clnt *clnt, char *dir_name)
98121
{
99122
static uint32_t clntid;
100-
struct path path, dir;
101123
char name[15];
102124
struct qstr q = {
103125
.name = name,
104126
};
127+
struct dentry *dir, *dentry;
105128
int error;
106129

107-
clnt->cl_path.mnt = ERR_PTR(-ENOENT);
108-
clnt->cl_path.dentry = ERR_PTR(-ENOENT);
109-
if (dir_name == NULL)
110-
return 0;
111-
112-
path.mnt = rpc_get_mount();
113-
if (IS_ERR(path.mnt))
114-
return PTR_ERR(path.mnt);
115-
error = vfs_path_lookup(path.mnt->mnt_root, path.mnt, dir_name, 0, &dir);
116-
if (error)
117-
goto err;
118-
130+
dir = rpc_d_lookup_sb(sb, dir_name);
131+
if (dir == NULL)
132+
return dir;
119133
for (;;) {
120134
q.len = snprintf(name, sizeof(name), "clnt%x", (unsigned int)clntid++);
121135
name[sizeof(name) - 1] = '\0';
122136
q.hash = full_name_hash(q.name, q.len);
123-
path.dentry = rpc_create_client_dir(dir.dentry, &q, clnt);
124-
if (!IS_ERR(path.dentry))
137+
dentry = rpc_create_client_dir(dir, &q, clnt);
138+
if (!IS_ERR(dentry))
125139
break;
126-
error = PTR_ERR(path.dentry);
140+
error = PTR_ERR(dentry);
127141
if (error != -EEXIST) {
128142
printk(KERN_INFO "RPC: Couldn't create pipefs entry"
129143
" %s/%s, error %d\n",
130144
dir_name, name, error);
131-
goto err_path_put;
145+
break;
132146
}
133147
}
134-
path_put(&dir);
148+
dput(dir);
149+
return dentry;
150+
}
151+
152+
static int
153+
rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
154+
{
155+
struct super_block *pipefs_sb;
156+
struct path path;
157+
158+
clnt->cl_path.mnt = ERR_PTR(-ENOENT);
159+
clnt->cl_path.dentry = NULL;
160+
if (dir_name == NULL)
161+
return 0;
162+
163+
path.mnt = rpc_get_mount();
164+
if (IS_ERR(path.mnt))
165+
return PTR_ERR(path.mnt);
166+
pipefs_sb = rpc_get_sb_net(clnt->cl_xprt->xprt_net);
167+
if (!pipefs_sb) {
168+
rpc_put_mount();
169+
return -ENOENT;
170+
}
171+
path.dentry = rpc_setup_pipedir_sb(pipefs_sb, clnt, dir_name);
172+
rpc_put_sb_net(clnt->cl_xprt->xprt_net);
173+
if (IS_ERR(path.dentry)) {
174+
rpc_put_mount();
175+
return PTR_ERR(path.dentry);
176+
}
135177
clnt->cl_path = path;
136178
return 0;
137-
err_path_put:
138-
path_put(&dir);
139-
err:
140-
rpc_put_mount();
141-
return error;
142179
}
143180

144181
static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt)
@@ -246,10 +283,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
246283
return clnt;
247284

248285
out_no_auth:
249-
if (!IS_ERR(clnt->cl_path.dentry)) {
250-
rpc_remove_client_dir(clnt->cl_path.dentry);
251-
rpc_put_mount();
252-
}
286+
rpc_clnt_remove_pipedir(clnt);
253287
out_no_path:
254288
kfree(clnt->cl_principal);
255289
out_no_principal:
@@ -474,10 +508,7 @@ rpc_free_client(struct rpc_clnt *clnt)
474508
{
475509
dprintk("RPC: destroying %s client for %s\n",
476510
clnt->cl_protname, clnt->cl_server);
477-
if (!IS_ERR(clnt->cl_path.dentry)) {
478-
rpc_remove_client_dir(clnt->cl_path.dentry);
479-
rpc_put_mount();
480-
}
511+
rpc_clnt_remove_pipedir(clnt);
481512
if (clnt->cl_parent != clnt) {
482513
rpc_release_client(clnt->cl_parent);
483514
goto out_free;

0 commit comments

Comments
 (0)