@@ -271,7 +271,8 @@ const struct dentry_operations afs_dynroot_dentry_operations = {
271
271
int afs_dynroot_mkdir (struct afs_net * net , struct afs_cell * cell )
272
272
{
273
273
struct super_block * sb = net -> dynroot_sb ;
274
- struct dentry * root , * subdir ;
274
+ struct dentry * root , * subdir , * dsubdir ;
275
+ char * dotname = cell -> name - 1 ;
275
276
int ret ;
276
277
277
278
if (!sb || atomic_read (& sb -> s_active ) == 0 )
@@ -286,34 +287,31 @@ int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
286
287
goto unlock ;
287
288
}
288
289
289
- /* Note that we're retaining an extra ref on the dentry */
290
+ dsubdir = lookup_one_len (dotname , root , cell -> name_len + 1 );
291
+ if (IS_ERR (dsubdir )) {
292
+ ret = PTR_ERR (dsubdir );
293
+ dput (subdir );
294
+ goto unlock ;
295
+ }
296
+
297
+ /* Note that we're retaining extra refs on the dentries. */
290
298
subdir -> d_fsdata = (void * )1UL ;
299
+ dsubdir -> d_fsdata = (void * )1UL ;
291
300
ret = 0 ;
292
301
unlock :
293
302
inode_unlock (root -> d_inode );
294
303
return ret ;
295
304
}
296
305
297
- /*
298
- * Remove a manually added cell mount directory.
299
- * - The caller must hold net->proc_cells_lock
300
- */
301
- void afs_dynroot_rmdir (struct afs_net * net , struct afs_cell * cell )
306
+ static void afs_dynroot_rm_one_dir (struct dentry * root , const char * name , size_t name_len )
302
307
{
303
- struct super_block * sb = net -> dynroot_sb ;
304
- struct dentry * root , * subdir ;
305
-
306
- if (!sb || atomic_read (& sb -> s_active ) == 0 )
307
- return ;
308
-
309
- root = sb -> s_root ;
310
- inode_lock (root -> d_inode );
308
+ struct dentry * subdir ;
311
309
312
310
/* Don't want to trigger a lookup call, which will re-add the cell */
313
- subdir = try_lookup_one_len (cell -> name , root , cell -> name_len );
311
+ subdir = try_lookup_one_len (name , root , name_len );
314
312
if (IS_ERR_OR_NULL (subdir )) {
315
313
_debug ("lookup %ld" , PTR_ERR (subdir ));
316
- goto no_dentry ;
314
+ return ;
317
315
}
318
316
319
317
_debug ("rmdir %pd %u" , subdir , d_count (subdir ));
@@ -324,8 +322,24 @@ void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
324
322
dput (subdir );
325
323
}
326
324
dput (subdir );
327
- no_dentry :
328
- inode_unlock (root -> d_inode );
325
+ }
326
+
327
+ /*
328
+ * Remove a manually added cell mount directory.
329
+ * - The caller must hold net->proc_cells_lock
330
+ */
331
+ void afs_dynroot_rmdir (struct afs_net * net , struct afs_cell * cell )
332
+ {
333
+ struct super_block * sb = net -> dynroot_sb ;
334
+ char * dotname = cell -> name - 1 ;
335
+
336
+ if (!sb || atomic_read (& sb -> s_active ) == 0 )
337
+ return ;
338
+
339
+ inode_lock (sb -> s_root -> d_inode );
340
+ afs_dynroot_rm_one_dir (sb -> s_root , cell -> name , cell -> name_len );
341
+ afs_dynroot_rm_one_dir (sb -> s_root , dotname , cell -> name_len + 1 );
342
+ inode_unlock (sb -> s_root -> d_inode );
329
343
_leave ("" );
330
344
}
331
345
0 commit comments