@@ -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-
12561250struct 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. */
12941264static 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 ;
13231295out :
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: */
13531324void 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
13711329static int nfsd_fill_super (struct super_block * sb , struct fs_context * fc )
0 commit comments