Skip to content

Commit ddf52f1

Browse files
committed
Merge tag 'pull-rpc_pipefs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull rpc_pipefs updates from Al Viro: "Massage rpc_pipefs to use saner primitives and clean up the APIs provided to the rest of the kernel" * tag 'pull-rpc_pipefs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: rpc_create_client_dir(): return 0 or -E... rpc_create_client_dir(): don't bother with rpc_populate() rpc_new_dir(): the last argument is always NULL rpc_pipe: expand the calls of rpc_mkdir_populate() rpc_gssd_dummy_populate(): don't bother with rpc_populate() rpc_mkpipe_dentry(): switch to simple_start_creating() rpc_pipe: saner primitive for creating regular files rpc_pipe: saner primitive for creating subdirectories rpc_pipe: don't overdo directory locking rpc_mkpipe_dentry(): saner calling conventions rpc_unlink(): saner calling conventions rpc_populate(): lift cleanup into callers rpc_unlink(): use simple_recursive_removal() rpc_{rmdir_,}depopulate(): use simple_recursive_removal() instead rpc_pipe: clean failure exits in fill_super new helper: simple_start_creating()
2 parents 1959e18 + 350db61 commit ddf52f1

11 files changed

Lines changed: 227 additions & 536 deletions

File tree

fs/debugfs/inode.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -384,27 +384,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
384384
if (!parent)
385385
parent = debugfs_mount->mnt_root;
386386

387-
inode_lock(d_inode(parent));
388-
if (unlikely(IS_DEADDIR(d_inode(parent))))
389-
dentry = ERR_PTR(-ENOENT);
390-
else
391-
dentry = lookup_noperm(&QSTR(name), parent);
392-
if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
393-
if (d_is_dir(dentry))
394-
pr_err("Directory '%s' with parent '%s' already present!\n",
395-
name, parent->d_name.name);
396-
else
397-
pr_err("File '%s' in directory '%s' already present!\n",
398-
name, parent->d_name.name);
399-
dput(dentry);
400-
dentry = ERR_PTR(-EEXIST);
401-
}
402-
387+
dentry = simple_start_creating(parent, name);
403388
if (IS_ERR(dentry)) {
404-
inode_unlock(d_inode(parent));
389+
if (dentry == ERR_PTR(-EEXIST))
390+
pr_err("'%s' already exists in '%pd'\n", name, parent);
405391
simple_release_fs(&debugfs_mount, &debugfs_mount_count);
406392
}
407-
408393
return dentry;
409394
}
410395

fs/libfs.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,3 +2272,28 @@ void stashed_dentry_prune(struct dentry *dentry)
22722272
*/
22732273
cmpxchg(stashed, dentry, NULL);
22742274
}
2275+
2276+
/* parent must be held exclusive */
2277+
struct dentry *simple_start_creating(struct dentry *parent, const char *name)
2278+
{
2279+
struct dentry *dentry;
2280+
struct inode *dir = d_inode(parent);
2281+
2282+
inode_lock(dir);
2283+
if (unlikely(IS_DEADDIR(dir))) {
2284+
inode_unlock(dir);
2285+
return ERR_PTR(-ENOENT);
2286+
}
2287+
dentry = lookup_noperm(&QSTR(name), parent);
2288+
if (IS_ERR(dentry)) {
2289+
inode_unlock(dir);
2290+
return dentry;
2291+
}
2292+
if (dentry->d_inode) {
2293+
dput(dentry);
2294+
inode_unlock(dir);
2295+
return ERR_PTR(-EEXIST);
2296+
}
2297+
return dentry;
2298+
}
2299+
EXPORT_SYMBOL(simple_start_creating);

fs/nfs/blocklayout/rpc_pipefs.c

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -141,24 +141,18 @@ static const struct rpc_pipe_ops bl_upcall_ops = {
141141
.destroy_msg = bl_pipe_destroy_msg,
142142
};
143143

144-
static struct dentry *nfs4blocklayout_register_sb(struct super_block *sb,
144+
static int nfs4blocklayout_register_sb(struct super_block *sb,
145145
struct rpc_pipe *pipe)
146146
{
147-
struct dentry *dir, *dentry;
147+
struct dentry *dir;
148+
int err;
148149

149150
dir = rpc_d_lookup_sb(sb, NFS_PIPE_DIRNAME);
150151
if (dir == NULL)
151-
return ERR_PTR(-ENOENT);
152-
dentry = rpc_mkpipe_dentry(dir, "blocklayout", NULL, pipe);
152+
return -ENOENT;
153+
err = rpc_mkpipe_dentry(dir, "blocklayout", NULL, pipe);
153154
dput(dir);
154-
return dentry;
155-
}
156-
157-
static void nfs4blocklayout_unregister_sb(struct super_block *sb,
158-
struct rpc_pipe *pipe)
159-
{
160-
if (pipe->dentry)
161-
rpc_unlink(pipe->dentry);
155+
return err;
162156
}
163157

164158
static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
@@ -167,7 +161,6 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
167161
struct super_block *sb = ptr;
168162
struct net *net = sb->s_fs_info;
169163
struct nfs_net *nn = net_generic(net, nfs_net_id);
170-
struct dentry *dentry;
171164
int ret = 0;
172165

173166
if (!try_module_get(THIS_MODULE))
@@ -180,16 +173,10 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event,
180173

181174
switch (event) {
182175
case RPC_PIPEFS_MOUNT:
183-
dentry = nfs4blocklayout_register_sb(sb, nn->bl_device_pipe);
184-
if (IS_ERR(dentry)) {
185-
ret = PTR_ERR(dentry);
186-
break;
187-
}
188-
nn->bl_device_pipe->dentry = dentry;
176+
ret = nfs4blocklayout_register_sb(sb, nn->bl_device_pipe);
189177
break;
190178
case RPC_PIPEFS_UMOUNT:
191-
if (nn->bl_device_pipe->dentry)
192-
nfs4blocklayout_unregister_sb(sb, nn->bl_device_pipe);
179+
rpc_unlink(nn->bl_device_pipe);
193180
break;
194181
default:
195182
ret = -ENOTSUPP;
@@ -203,18 +190,17 @@ static struct notifier_block nfs4blocklayout_block = {
203190
.notifier_call = rpc_pipefs_event,
204191
};
205192

206-
static struct dentry *nfs4blocklayout_register_net(struct net *net,
207-
struct rpc_pipe *pipe)
193+
static int nfs4blocklayout_register_net(struct net *net, struct rpc_pipe *pipe)
208194
{
209195
struct super_block *pipefs_sb;
210-
struct dentry *dentry;
196+
int ret;
211197

212198
pipefs_sb = rpc_get_sb_net(net);
213199
if (!pipefs_sb)
214-
return NULL;
215-
dentry = nfs4blocklayout_register_sb(pipefs_sb, pipe);
200+
return 0;
201+
ret = nfs4blocklayout_register_sb(pipefs_sb, pipe);
216202
rpc_put_sb_net(net);
217-
return dentry;
203+
return ret;
218204
}
219205

220206
static void nfs4blocklayout_unregister_net(struct net *net,
@@ -224,28 +210,25 @@ static void nfs4blocklayout_unregister_net(struct net *net,
224210

225211
pipefs_sb = rpc_get_sb_net(net);
226212
if (pipefs_sb) {
227-
nfs4blocklayout_unregister_sb(pipefs_sb, pipe);
213+
rpc_unlink(pipe);
228214
rpc_put_sb_net(net);
229215
}
230216
}
231217

232218
static int nfs4blocklayout_net_init(struct net *net)
233219
{
234220
struct nfs_net *nn = net_generic(net, nfs_net_id);
235-
struct dentry *dentry;
221+
int err;
236222

237223
mutex_init(&nn->bl_mutex);
238224
init_waitqueue_head(&nn->bl_wq);
239225
nn->bl_device_pipe = rpc_mkpipe_data(&bl_upcall_ops, 0);
240226
if (IS_ERR(nn->bl_device_pipe))
241227
return PTR_ERR(nn->bl_device_pipe);
242-
dentry = nfs4blocklayout_register_net(net, nn->bl_device_pipe);
243-
if (IS_ERR(dentry)) {
228+
err = nfs4blocklayout_register_net(net, nn->bl_device_pipe);
229+
if (unlikely(err))
244230
rpc_destroy_pipe_data(nn->bl_device_pipe);
245-
return PTR_ERR(dentry);
246-
}
247-
nn->bl_device_pipe->dentry = dentry;
248-
return 0;
231+
return err;
249232
}
250233

251234
static void nfs4blocklayout_net_exit(struct net *net)

fs/nfs/nfs4idmap.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -424,26 +424,16 @@ static void nfs_idmap_pipe_destroy(struct dentry *dir,
424424
struct rpc_pipe_dir_object *pdo)
425425
{
426426
struct idmap *idmap = pdo->pdo_data;
427-
struct rpc_pipe *pipe = idmap->idmap_pipe;
428427

429-
if (pipe->dentry) {
430-
rpc_unlink(pipe->dentry);
431-
pipe->dentry = NULL;
432-
}
428+
rpc_unlink(idmap->idmap_pipe);
433429
}
434430

435431
static int nfs_idmap_pipe_create(struct dentry *dir,
436432
struct rpc_pipe_dir_object *pdo)
437433
{
438434
struct idmap *idmap = pdo->pdo_data;
439-
struct rpc_pipe *pipe = idmap->idmap_pipe;
440-
struct dentry *dentry;
441435

442-
dentry = rpc_mkpipe_dentry(dir, "idmap", idmap, pipe);
443-
if (IS_ERR(dentry))
444-
return PTR_ERR(dentry);
445-
pipe->dentry = dentry;
446-
return 0;
436+
return rpc_mkpipe_dentry(dir, "idmap", idmap, idmap->idmap_pipe);
447437
}
448438

449439
static const struct rpc_pipe_dir_object_ops nfs_idmap_pipe_dir_object_ops = {

fs/nfsd/nfs4recover.c

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -950,38 +950,32 @@ static const struct rpc_pipe_ops cld_upcall_ops = {
950950
.destroy_msg = cld_pipe_destroy_msg,
951951
};
952952

953-
static struct dentry *
953+
static int
954954
nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
955955
{
956-
struct dentry *dir, *dentry;
956+
struct dentry *dir;
957+
int err;
957958

958959
dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
959960
if (dir == NULL)
960-
return ERR_PTR(-ENOENT);
961-
dentry = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
961+
return -ENOENT;
962+
err = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
962963
dput(dir);
963-
return dentry;
964+
return err;
964965
}
965966

966-
static void
967-
nfsd4_cld_unregister_sb(struct rpc_pipe *pipe)
968-
{
969-
if (pipe->dentry)
970-
rpc_unlink(pipe->dentry);
971-
}
972-
973-
static struct dentry *
967+
static int
974968
nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
975969
{
976970
struct super_block *sb;
977-
struct dentry *dentry;
971+
int err;
978972

979973
sb = rpc_get_sb_net(net);
980974
if (!sb)
981-
return NULL;
982-
dentry = nfsd4_cld_register_sb(sb, pipe);
975+
return 0;
976+
err = nfsd4_cld_register_sb(sb, pipe);
983977
rpc_put_sb_net(net);
984-
return dentry;
978+
return err;
985979
}
986980

987981
static void
@@ -991,7 +985,7 @@ nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
991985

992986
sb = rpc_get_sb_net(net);
993987
if (sb) {
994-
nfsd4_cld_unregister_sb(pipe);
988+
rpc_unlink(pipe);
995989
rpc_put_sb_net(net);
996990
}
997991
}
@@ -1001,7 +995,6 @@ static int
1001995
__nfsd4_init_cld_pipe(struct net *net)
1002996
{
1003997
int ret;
1004-
struct dentry *dentry;
1005998
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1006999
struct cld_net *cn;
10071000

@@ -1022,13 +1015,10 @@ __nfsd4_init_cld_pipe(struct net *net)
10221015
spin_lock_init(&cn->cn_lock);
10231016
INIT_LIST_HEAD(&cn->cn_list);
10241017

1025-
dentry = nfsd4_cld_register_net(net, cn->cn_pipe);
1026-
if (IS_ERR(dentry)) {
1027-
ret = PTR_ERR(dentry);
1018+
ret = nfsd4_cld_register_net(net, cn->cn_pipe);
1019+
if (unlikely(ret))
10281020
goto err_destroy_data;
1029-
}
10301021

1031-
cn->cn_pipe->dentry = dentry;
10321022
#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
10331023
cn->cn_has_legacy = false;
10341024
#endif
@@ -2121,7 +2111,6 @@ rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
21212111
struct net *net = sb->s_fs_info;
21222112
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
21232113
struct cld_net *cn = nn->cld_net;
2124-
struct dentry *dentry;
21252114
int ret = 0;
21262115

21272116
if (!try_module_get(THIS_MODULE))
@@ -2134,16 +2123,10 @@ rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
21342123

21352124
switch (event) {
21362125
case RPC_PIPEFS_MOUNT:
2137-
dentry = nfsd4_cld_register_sb(sb, cn->cn_pipe);
2138-
if (IS_ERR(dentry)) {
2139-
ret = PTR_ERR(dentry);
2140-
break;
2141-
}
2142-
cn->cn_pipe->dentry = dentry;
2126+
ret = nfsd4_cld_register_sb(sb, cn->cn_pipe);
21432127
break;
21442128
case RPC_PIPEFS_UMOUNT:
2145-
if (cn->cn_pipe->dentry)
2146-
nfsd4_cld_unregister_sb(cn->cn_pipe);
2129+
rpc_unlink(cn->cn_pipe);
21472130
break;
21482131
default:
21492132
ret = -ENOTSUPP;

fs/tracefs/inode.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -562,20 +562,9 @@ struct dentry *tracefs_start_creating(const char *name, struct dentry *parent)
562562
if (!parent)
563563
parent = tracefs_mount->mnt_root;
564564

565-
inode_lock(d_inode(parent));
566-
if (unlikely(IS_DEADDIR(d_inode(parent))))
567-
dentry = ERR_PTR(-ENOENT);
568-
else
569-
dentry = lookup_noperm(&QSTR(name), parent);
570-
if (!IS_ERR(dentry) && d_inode(dentry)) {
571-
dput(dentry);
572-
dentry = ERR_PTR(-EEXIST);
573-
}
574-
575-
if (IS_ERR(dentry)) {
576-
inode_unlock(d_inode(parent));
565+
dentry = simple_start_creating(parent, name);
566+
if (IS_ERR(dentry))
577567
simple_release_fs(&tracefs_mount, &tracefs_mount_count);
578-
}
579568

580569
return dentry;
581570
}

include/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3627,6 +3627,7 @@ extern int simple_fill_super(struct super_block *, unsigned long,
36273627
const struct tree_descr *);
36283628
extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
36293629
extern void simple_release_fs(struct vfsmount **mount, int *count);
3630+
struct dentry *simple_start_creating(struct dentry *, const char *);
36303631

36313632
extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
36323633
loff_t *ppos, const void *from, size_t available);

include/linux/sunrpc/rpc_pipe_fs.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static inline bool rpc_msg_is_inflight(const struct rpc_pipe_msg *msg) {
9898
}
9999

100100
struct rpc_clnt;
101-
extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
101+
extern int rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
102102
extern int rpc_remove_client_dir(struct rpc_clnt *);
103103

104104
extern void rpc_init_pipe_dir_head(struct rpc_pipe_dir_head *pdh);
@@ -127,9 +127,9 @@ extern void rpc_remove_cache_dir(struct dentry *);
127127

128128
struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags);
129129
void rpc_destroy_pipe_data(struct rpc_pipe *pipe);
130-
extern struct dentry *rpc_mkpipe_dentry(struct dentry *, const char *, void *,
130+
extern int rpc_mkpipe_dentry(struct dentry *, const char *, void *,
131131
struct rpc_pipe *);
132-
extern int rpc_unlink(struct dentry *);
132+
extern void rpc_unlink(struct rpc_pipe *);
133133
extern int register_rpc_pipefs(void);
134134
extern void unregister_rpc_pipefs(void);
135135

net/sunrpc/auth_gss/auth_gss.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -887,25 +887,16 @@ static void gss_pipe_dentry_destroy(struct dentry *dir,
887887
struct rpc_pipe_dir_object *pdo)
888888
{
889889
struct gss_pipe *gss_pipe = pdo->pdo_data;
890-
struct rpc_pipe *pipe = gss_pipe->pipe;
891890

892-
if (pipe->dentry != NULL) {
893-
rpc_unlink(pipe->dentry);
894-
pipe->dentry = NULL;
895-
}
891+
rpc_unlink(gss_pipe->pipe);
896892
}
897893

898894
static int gss_pipe_dentry_create(struct dentry *dir,
899895
struct rpc_pipe_dir_object *pdo)
900896
{
901897
struct gss_pipe *p = pdo->pdo_data;
902-
struct dentry *dentry;
903898

904-
dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
905-
if (IS_ERR(dentry))
906-
return PTR_ERR(dentry);
907-
p->pipe->dentry = dentry;
908-
return 0;
899+
return rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
909900
}
910901

911902
static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = {

0 commit comments

Comments
 (0)