@@ -229,7 +229,6 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *
229
229
delegation -> cred ,
230
230
& delegation -> stateid ,
231
231
issync );
232
- nfs_free_delegation (delegation );
233
232
return res ;
234
233
}
235
234
@@ -302,7 +301,6 @@ nfs_detach_delegation_locked(struct nfs_inode *nfsi,
302
301
spin_unlock (& delegation -> lock );
303
302
return NULL ;
304
303
}
305
- set_bit (NFS_DELEGATION_RETURNING , & delegation -> flags );
306
304
list_del_rcu (& delegation -> super_list );
307
305
delegation -> inode = NULL ;
308
306
rcu_assign_pointer (nfsi -> delegation , NULL );
@@ -329,10 +327,12 @@ nfs_inode_detach_delegation(struct inode *inode)
329
327
struct nfs_server * server = NFS_SERVER (inode );
330
328
struct nfs_delegation * delegation ;
331
329
332
- delegation = nfs_start_delegation_return (nfsi );
333
- if (delegation == NULL )
334
- return NULL ;
335
- return nfs_detach_delegation (nfsi , delegation , server );
330
+ rcu_read_lock ();
331
+ delegation = rcu_dereference (nfsi -> delegation );
332
+ if (delegation != NULL )
333
+ delegation = nfs_detach_delegation (nfsi , delegation , server );
334
+ rcu_read_unlock ();
335
+ return delegation ;
336
336
}
337
337
338
338
static void
@@ -384,16 +384,18 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
384
384
spin_lock (& clp -> cl_lock );
385
385
old_delegation = rcu_dereference_protected (nfsi -> delegation ,
386
386
lockdep_is_held (& clp -> cl_lock ));
387
- if (old_delegation != NULL ) {
388
- /* Is this an update of the existing delegation? */
389
- if (nfs4_stateid_match_other (& old_delegation -> stateid ,
390
- & delegation -> stateid )) {
391
- spin_lock (& old_delegation -> lock );
392
- nfs_update_inplace_delegation (old_delegation ,
393
- delegation );
394
- spin_unlock (& old_delegation -> lock );
395
- goto out ;
396
- }
387
+ if (old_delegation == NULL )
388
+ goto add_new ;
389
+ /* Is this an update of the existing delegation? */
390
+ if (nfs4_stateid_match_other (& old_delegation -> stateid ,
391
+ & delegation -> stateid )) {
392
+ spin_lock (& old_delegation -> lock );
393
+ nfs_update_inplace_delegation (old_delegation ,
394
+ delegation );
395
+ spin_unlock (& old_delegation -> lock );
396
+ goto out ;
397
+ }
398
+ if (!test_bit (NFS_DELEGATION_REVOKED , & old_delegation -> flags )) {
397
399
/*
398
400
* Deal with broken servers that hand out two
399
401
* delegations for the same file.
@@ -412,11 +414,11 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
412
414
if (test_and_set_bit (NFS_DELEGATION_RETURNING ,
413
415
& old_delegation -> flags ))
414
416
goto out ;
415
- freeme = nfs_detach_delegation_locked (nfsi ,
416
- old_delegation , clp );
417
- if (freeme == NULL )
418
- goto out ;
419
417
}
418
+ freeme = nfs_detach_delegation_locked (nfsi , old_delegation , clp );
419
+ if (freeme == NULL )
420
+ goto out ;
421
+ add_new :
420
422
list_add_tail_rcu (& delegation -> super_list , & server -> delegations );
421
423
rcu_assign_pointer (nfsi -> delegation , delegation );
422
424
delegation = NULL ;
@@ -431,8 +433,10 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
431
433
spin_unlock (& clp -> cl_lock );
432
434
if (delegation != NULL )
433
435
nfs_free_delegation (delegation );
434
- if (freeme != NULL )
436
+ if (freeme != NULL ) {
435
437
nfs_do_return_delegation (inode , freeme , 0 );
438
+ nfs_free_delegation (freeme );
439
+ }
436
440
return status ;
437
441
}
438
442
@@ -442,7 +446,6 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
442
446
static int nfs_end_delegation_return (struct inode * inode , struct nfs_delegation * delegation , int issync )
443
447
{
444
448
struct nfs_client * clp = NFS_SERVER (inode )-> nfs_client ;
445
- struct nfs_inode * nfsi = NFS_I (inode );
446
449
int err = 0 ;
447
450
448
451
if (delegation == NULL )
@@ -464,8 +467,6 @@ static int nfs_end_delegation_return(struct inode *inode, struct nfs_delegation
464
467
nfs_abort_delegation_return (delegation , clp );
465
468
goto out ;
466
469
}
467
- if (!nfs_detach_delegation (nfsi , delegation , NFS_SERVER (inode )))
468
- goto out ;
469
470
470
471
err = nfs_do_return_delegation (inode , delegation , issync );
471
472
out :
@@ -608,6 +609,7 @@ void nfs_inode_evict_delegation(struct inode *inode)
608
609
if (delegation != NULL ) {
609
610
set_bit (NFS_DELEGATION_INODE_FREEING , & delegation -> flags );
610
611
nfs_do_return_delegation (inode , delegation , 1 );
612
+ nfs_free_delegation (delegation );
611
613
}
612
614
}
613
615
@@ -763,10 +765,9 @@ static void nfs_mark_delegation_revoked(struct nfs_server *server,
763
765
{
764
766
set_bit (NFS_DELEGATION_REVOKED , & delegation -> flags );
765
767
delegation -> stateid .type = NFS4_INVALID_STATEID_TYPE ;
766
- nfs_mark_return_delegation (server , delegation );
767
768
}
768
769
769
- static bool nfs_revoke_delegation (struct inode * inode ,
770
+ static void nfs_revoke_delegation (struct inode * inode ,
770
771
const nfs4_stateid * stateid )
771
772
{
772
773
struct nfs_delegation * delegation ;
@@ -799,19 +800,12 @@ static bool nfs_revoke_delegation(struct inode *inode,
799
800
rcu_read_unlock ();
800
801
if (ret )
801
802
nfs_inode_find_state_and_recover (inode , stateid );
802
- return ret ;
803
803
}
804
804
805
805
void nfs_remove_bad_delegation (struct inode * inode ,
806
806
const nfs4_stateid * stateid )
807
807
{
808
- struct nfs_delegation * delegation ;
809
-
810
- if (!nfs_revoke_delegation (inode , stateid ))
811
- return ;
812
- delegation = nfs_inode_detach_delegation (inode );
813
- if (delegation )
814
- nfs_free_delegation (delegation );
808
+ nfs_revoke_delegation (inode , stateid );
815
809
}
816
810
EXPORT_SYMBOL_GPL (nfs_remove_bad_delegation );
817
811
@@ -839,7 +833,7 @@ void nfs_delegation_mark_returned(struct inode *inode,
839
833
delegation -> stateid .seqid = stateid -> seqid ;
840
834
}
841
835
842
- set_bit ( NFS_DELEGATION_REVOKED , & delegation -> flags );
836
+ nfs_mark_delegation_revoked ( NFS_SERVER ( inode ), delegation );
843
837
844
838
out_clear_returning :
845
839
clear_bit (NFS_DELEGATION_RETURNING , & delegation -> flags );
0 commit comments