Skip to content

Commit 88388cb

Browse files
author
Al Viro
committed
nfsctl: switch to simple_recursive_removal()
Use simple_recursive_removal() in nfsd_client_rmdir() rather than open-coding it. And use less heavy-handed locking to get from nfsctl inode to its ->i_private... Reviewed-by: Jeff Layton <jlayton@redhat.com> Tested-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent b85ea95 commit 88388cb

File tree

1 file changed

+14
-56
lines changed

1 file changed

+14
-56
lines changed

fs/nfsd/nfsctl.c

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,63 +1236,34 @@ static inline void _nfsd_symlink(struct dentry *parent, const char *name,
12361236

12371237
#endif
12381238

1239-
static void clear_ncl(struct inode *inode)
1239+
static void clear_ncl(struct dentry *dentry)
12401240
{
1241+
struct inode *inode = d_inode(dentry);
12411242
struct nfsdfs_client *ncl = inode->i_private;
12421243

1244+
spin_lock(&inode->i_lock);
12431245
inode->i_private = NULL;
1246+
spin_unlock(&inode->i_lock);
12441247
kref_put(&ncl->cl_ref, ncl->cl_release);
12451248
}
12461249

1247-
static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
1248-
{
1249-
struct nfsdfs_client *nc = inode->i_private;
1250-
1251-
if (nc)
1252-
kref_get(&nc->cl_ref);
1253-
return nc;
1254-
}
1255-
12561250
struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
12571251
{
12581252
struct nfsdfs_client *nc;
12591253

1260-
inode_lock_shared(inode);
1261-
nc = __get_nfsdfs_client(inode);
1262-
inode_unlock_shared(inode);
1254+
spin_lock(&inode->i_lock);
1255+
nc = inode->i_private;
1256+
if (nc)
1257+
kref_get(&nc->cl_ref);
1258+
spin_unlock(&inode->i_lock);
12631259
return nc;
12641260
}
1265-
/* from __rpc_unlink */
1266-
static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry)
1267-
{
1268-
int ret;
1269-
1270-
clear_ncl(d_inode(dentry));
1271-
dget(dentry);
1272-
ret = simple_unlink(dir, dentry);
1273-
d_drop(dentry);
1274-
fsnotify_unlink(dir, dentry);
1275-
dput(dentry);
1276-
WARN_ON_ONCE(ret);
1277-
}
1278-
1279-
static void nfsdfs_remove_files(struct dentry *root)
1280-
{
1281-
struct dentry *dentry, *tmp;
1282-
1283-
list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) {
1284-
if (!simple_positive(dentry)) {
1285-
WARN_ON_ONCE(1); /* I think this can't happen? */
1286-
continue;
1287-
}
1288-
nfsdfs_remove_file(d_inode(root), dentry);
1289-
}
1290-
}
12911261

12921262
/* XXX: cut'n'paste from simple_fill_super; figure out if we could share
12931263
* code instead. */
12941264
static int nfsdfs_create_files(struct dentry *root,
12951265
const struct tree_descr *files,
1266+
struct nfsdfs_client *ncl,
12961267
struct dentry **fdentries)
12971268
{
12981269
struct inode *dir = d_inode(root);
@@ -1311,8 +1282,9 @@ static int nfsdfs_create_files(struct dentry *root,
13111282
dput(dentry);
13121283
goto out;
13131284
}
1285+
kref_get(&ncl->cl_ref);
13141286
inode->i_fop = files->ops;
1315-
inode->i_private = __get_nfsdfs_client(dir);
1287+
inode->i_private = ncl;
13161288
d_add(dentry, inode);
13171289
fsnotify_create(dir, dentry);
13181290
if (fdentries)
@@ -1321,7 +1293,6 @@ static int nfsdfs_create_files(struct dentry *root,
13211293
inode_unlock(dir);
13221294
return 0;
13231295
out:
1324-
nfsdfs_remove_files(root);
13251296
inode_unlock(dir);
13261297
return -ENOMEM;
13271298
}
@@ -1341,7 +1312,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
13411312
dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name);
13421313
if (IS_ERR(dentry)) /* XXX: tossing errors? */
13431314
return NULL;
1344-
ret = nfsdfs_create_files(dentry, files, fdentries);
1315+
ret = nfsdfs_create_files(dentry, files, ncl, fdentries);
13451316
if (ret) {
13461317
nfsd_client_rmdir(dentry);
13471318
return NULL;
@@ -1352,20 +1323,7 @@ struct dentry *nfsd_client_mkdir(struct nfsd_net *nn,
13521323
/* Taken from __rpc_rmdir: */
13531324
void nfsd_client_rmdir(struct dentry *dentry)
13541325
{
1355-
struct inode *dir = d_inode(dentry->d_parent);
1356-
struct inode *inode = d_inode(dentry);
1357-
int ret;
1358-
1359-
inode_lock(dir);
1360-
nfsdfs_remove_files(dentry);
1361-
clear_ncl(inode);
1362-
dget(dentry);
1363-
ret = simple_rmdir(dir, dentry);
1364-
WARN_ON_ONCE(ret);
1365-
d_drop(dentry);
1366-
fsnotify_rmdir(dir, dentry);
1367-
dput(dentry);
1368-
inode_unlock(dir);
1326+
simple_recursive_removal(dentry, clear_ncl);
13691327
}
13701328

13711329
static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)

0 commit comments

Comments
 (0)