@@ -237,7 +237,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
237237 nfs4_reset_creds (original_cred );
238238}
239239
240- typedef int (recdir_func )(struct dentry * , struct dentry * , struct nfsd_net * );
240+ typedef int (recdir_func )(struct dentry * , char * , struct nfsd_net * );
241241
242242struct name_list {
243243 char name [HEXDIR_LEN ];
@@ -291,24 +291,14 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
291291 }
292292
293293 status = iterate_dir (nn -> rec_file , & ctx .ctx );
294- inode_lock_nested (d_inode (dir ), I_MUTEX_PARENT );
295294
296295 list_for_each_entry_safe (entry , tmp , & ctx .names , list ) {
297- if (!status ) {
298- struct dentry * dentry ;
299- dentry = lookup_one (& nop_mnt_idmap ,
300- & QSTR (entry -> name ), dir );
301- if (IS_ERR (dentry )) {
302- status = PTR_ERR (dentry );
303- break ;
304- }
305- status = f (dir , dentry , nn );
306- dput (dentry );
307- }
296+ if (!status )
297+ status = f (dir , entry -> name , nn );
298+
308299 list_del (& entry -> list );
309300 kfree (entry );
310301 }
311- inode_unlock (d_inode (dir ));
312302 nfs4_reset_creds (original_cred );
313303
314304 list_for_each_entry_safe (entry , tmp , & ctx .names , list ) {
@@ -406,18 +396,19 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
406396}
407397
408398static int
409- purge_old (struct dentry * parent , struct dentry * child , struct nfsd_net * nn )
399+ purge_old (struct dentry * parent , char * cname , struct nfsd_net * nn )
410400{
411401 int status ;
402+ struct dentry * child ;
412403 struct xdr_netobj name ;
413404
414- if (child -> d_name . len != HEXDIR_LEN - 1 ) {
415- printk ("%s: illegal name %pd in recovery directory\n" ,
416- __func__ , child );
405+ if (strlen ( cname ) != HEXDIR_LEN - 1 ) {
406+ printk ("%s: illegal name %s in recovery directory\n" ,
407+ __func__ , cname );
417408 /* Keep trying; maybe the others are OK: */
418409 return 0 ;
419410 }
420- name .data = kmemdup_nul ( child -> d_name . name , child -> d_name . len , GFP_KERNEL );
411+ name .data = kstrdup ( cname , GFP_KERNEL );
421412 if (!name .data ) {
422413 dprintk ("%s: failed to allocate memory for name.data!\n" ,
423414 __func__ );
@@ -427,10 +418,17 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
427418 if (nfs4_has_reclaimed_state (name , nn ))
428419 goto out_free ;
429420
430- status = vfs_rmdir (& nop_mnt_idmap , d_inode (parent ), child );
431- if (status )
432- printk ("failed to remove client recovery directory %pd\n" ,
433- child );
421+ inode_lock_nested (d_inode (parent ), I_MUTEX_PARENT );
422+ child = lookup_one (& nop_mnt_idmap , & QSTR (cname ), parent );
423+ if (!IS_ERR (child )) {
424+ status = vfs_rmdir (& nop_mnt_idmap , d_inode (parent ), child );
425+ if (status )
426+ printk ("failed to remove client recovery directory %pd\n" ,
427+ child );
428+ dput (child );
429+ }
430+ inode_unlock (d_inode (parent ));
431+
434432out_free :
435433 kfree (name .data );
436434out :
@@ -461,18 +459,18 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
461459}
462460
463461static int
464- load_recdir (struct dentry * parent , struct dentry * child , struct nfsd_net * nn )
462+ load_recdir (struct dentry * parent , char * cname , struct nfsd_net * nn )
465463{
466464 struct xdr_netobj name ;
467465 struct xdr_netobj princhash = { .len = 0 , .data = NULL };
468466
469- if (child -> d_name . len != HEXDIR_LEN - 1 ) {
470- printk ("%s: illegal name %pd in recovery directory\n" ,
471- __func__ , child );
467+ if (strlen ( cname ) != HEXDIR_LEN - 1 ) {
468+ printk ("%s: illegal name %s in recovery directory\n" ,
469+ __func__ , cname );
472470 /* Keep trying; maybe the others are OK: */
473471 return 0 ;
474472 }
475- name .data = kmemdup_nul ( child -> d_name . name , child -> d_name . len , GFP_KERNEL );
473+ name .data = kstrdup ( cname , GFP_KERNEL );
476474 if (!name .data ) {
477475 dprintk ("%s: failed to allocate memory for name.data!\n" ,
478476 __func__ );
0 commit comments