@@ -169,13 +169,34 @@ legacy_recdir_name_error(struct nfs4_client *clp, int error)
169
169
}
170
170
}
171
171
172
+ static void
173
+ __nfsd4_create_reclaim_record_grace (struct nfs4_client * clp ,
174
+ const char * dname , int len , struct nfsd_net * nn )
175
+ {
176
+ struct xdr_netobj name ;
177
+ struct nfs4_client_reclaim * crp ;
178
+
179
+ name .data = kmemdup (dname , len , GFP_KERNEL );
180
+ if (!name .data ) {
181
+ dprintk ("%s: failed to allocate memory for name.data!\n" ,
182
+ __func__ );
183
+ return ;
184
+ }
185
+ name .len = len ;
186
+ crp = nfs4_client_to_reclaim (name , nn );
187
+ if (!crp ) {
188
+ kfree (name .data );
189
+ return ;
190
+ }
191
+ crp -> cr_clp = clp ;
192
+ }
193
+
172
194
static void
173
195
nfsd4_create_clid_dir (struct nfs4_client * clp )
174
196
{
175
197
const struct cred * original_cred ;
176
198
char dname [HEXDIR_LEN ];
177
199
struct dentry * dir , * dentry ;
178
- struct nfs4_client_reclaim * crp ;
179
200
int status ;
180
201
struct nfsd_net * nn = net_generic (clp -> net , nfsd_net_id );
181
202
@@ -221,11 +242,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
221
242
out_unlock :
222
243
inode_unlock (d_inode (dir ));
223
244
if (status == 0 ) {
224
- if (nn -> in_grace ) {
225
- crp = nfs4_client_to_reclaim (dname , nn );
226
- if (crp )
227
- crp -> cr_clp = clp ;
228
- }
245
+ if (nn -> in_grace )
246
+ __nfsd4_create_reclaim_record_grace (clp , dname ,
247
+ HEXDIR_LEN , nn );
229
248
vfs_fsync (nn -> rec_file , 0 );
230
249
} else {
231
250
printk (KERN_ERR "NFSD: failed to write recovery record"
@@ -345,11 +364,30 @@ nfsd4_unlink_clid_dir(char *name, int namlen, struct nfsd_net *nn)
345
364
return status ;
346
365
}
347
366
367
+ static void
368
+ __nfsd4_remove_reclaim_record_grace (const char * dname , int len ,
369
+ struct nfsd_net * nn )
370
+ {
371
+ struct xdr_netobj name ;
372
+ struct nfs4_client_reclaim * crp ;
373
+
374
+ name .data = kmemdup (dname , len , GFP_KERNEL );
375
+ if (!name .data ) {
376
+ dprintk ("%s: failed to allocate memory for name.data!\n" ,
377
+ __func__ );
378
+ return ;
379
+ }
380
+ name .len = len ;
381
+ crp = nfsd4_find_reclaim_client (name , nn );
382
+ kfree (name .data );
383
+ if (crp )
384
+ nfs4_remove_reclaim_record (crp , nn );
385
+ }
386
+
348
387
static void
349
388
nfsd4_remove_clid_dir (struct nfs4_client * clp )
350
389
{
351
390
const struct cred * original_cred ;
352
- struct nfs4_client_reclaim * crp ;
353
391
char dname [HEXDIR_LEN ];
354
392
int status ;
355
393
struct nfsd_net * nn = net_generic (clp -> net , nfsd_net_id );
@@ -374,12 +412,9 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
374
412
nfs4_reset_creds (original_cred );
375
413
if (status == 0 ) {
376
414
vfs_fsync (nn -> rec_file , 0 );
377
- if (nn -> in_grace ) {
378
- /* remove reclaim record */
379
- crp = nfsd4_find_reclaim_client (dname , nn );
380
- if (crp )
381
- nfs4_remove_reclaim_record (crp , nn );
382
- }
415
+ if (nn -> in_grace )
416
+ __nfsd4_remove_reclaim_record_grace (dname ,
417
+ HEXDIR_LEN , nn );
383
418
}
384
419
out_drop_write :
385
420
mnt_drop_write_file (nn -> rec_file );
@@ -393,14 +428,31 @@ static int
393
428
purge_old (struct dentry * parent , struct dentry * child , struct nfsd_net * nn )
394
429
{
395
430
int status ;
431
+ struct xdr_netobj name ;
396
432
397
- if (nfs4_has_reclaimed_state (child -> d_name .name , nn ))
433
+ if (child -> d_name .len != HEXDIR_LEN - 1 ) {
434
+ printk ("%s: illegal name %pd in recovery directory\n" ,
435
+ __func__ , child );
436
+ /* Keep trying; maybe the others are OK: */
398
437
return 0 ;
438
+ }
439
+ name .data = kmemdup_nul (child -> d_name .name , child -> d_name .len , GFP_KERNEL );
440
+ if (!name .data ) {
441
+ dprintk ("%s: failed to allocate memory for name.data!\n" ,
442
+ __func__ );
443
+ goto out ;
444
+ }
445
+ name .len = HEXDIR_LEN ;
446
+ if (nfs4_has_reclaimed_state (name , nn ))
447
+ goto out_free ;
399
448
400
449
status = vfs_rmdir (d_inode (parent ), child );
401
450
if (status )
402
451
printk ("failed to remove client recovery directory %pd\n" ,
403
452
child );
453
+ out_free :
454
+ kfree (name .data );
455
+ out :
404
456
/* Keep trying, success or failure: */
405
457
return 0 ;
406
458
}
@@ -430,13 +482,24 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
430
482
static int
431
483
load_recdir (struct dentry * parent , struct dentry * child , struct nfsd_net * nn )
432
484
{
485
+ struct xdr_netobj name ;
486
+
433
487
if (child -> d_name .len != HEXDIR_LEN - 1 ) {
434
- printk ("nfsd4 : illegal name %pd in recovery directory\n" ,
435
- child );
488
+ printk ("%s : illegal name %pd in recovery directory\n" ,
489
+ __func__ , child );
436
490
/* Keep trying; maybe the others are OK: */
437
491
return 0 ;
438
492
}
439
- nfs4_client_to_reclaim (child -> d_name .name , nn );
493
+ name .data = kmemdup_nul (child -> d_name .name , child -> d_name .len , GFP_KERNEL );
494
+ if (!name .data ) {
495
+ dprintk ("%s: failed to allocate memory for name.data!\n" ,
496
+ __func__ );
497
+ goto out ;
498
+ }
499
+ name .len = HEXDIR_LEN ;
500
+ if (!nfs4_client_to_reclaim (name , nn ))
501
+ kfree (name .data );
502
+ out :
440
503
return 0 ;
441
504
}
442
505
@@ -616,6 +679,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
616
679
char dname [HEXDIR_LEN ];
617
680
struct nfs4_client_reclaim * crp ;
618
681
struct nfsd_net * nn = net_generic (clp -> net , nfsd_net_id );
682
+ struct xdr_netobj name ;
619
683
620
684
/* did we already find that this client is stable? */
621
685
if (test_bit (NFSD4_CLIENT_STABLE , & clp -> cl_flags ))
@@ -628,13 +692,22 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
628
692
}
629
693
630
694
/* look for it in the reclaim hashtable otherwise */
631
- crp = nfsd4_find_reclaim_client (dname , nn );
695
+ name .data = kmemdup (dname , HEXDIR_LEN , GFP_KERNEL );
696
+ if (!name .data ) {
697
+ dprintk ("%s: failed to allocate memory for name.data!\n" ,
698
+ __func__ );
699
+ goto out_enoent ;
700
+ }
701
+ name .len = HEXDIR_LEN ;
702
+ crp = nfsd4_find_reclaim_client (name , nn );
703
+ kfree (name .data );
632
704
if (crp ) {
633
705
set_bit (NFSD4_CLIENT_STABLE , & clp -> cl_flags );
634
706
crp -> cr_clp = clp ;
635
707
return 0 ;
636
708
}
637
709
710
+ out_enoent :
638
711
return - ENOENT ;
639
712
}
640
713
0 commit comments