Skip to content

Commit 41020b6

Browse files
trondmypdamschuma-ntap
authored andcommitted
NFSv4.x: Allow callers of nfs_remove_bad_delegation() to specify a stateid
Allow the callers of nfs_remove_bad_delegation() to specify the stateid that needs to be marked as bad. Signed-off-by: Trond Myklebust <[email protected]> Tested-by: Oleg Drokin <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 4586f6e commit 41020b6

File tree

4 files changed

+33
-15
lines changed

4 files changed

+33
-15
lines changed

fs/nfs/delegation.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -652,23 +652,39 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
652652
rcu_read_unlock();
653653
}
654654

655-
static void nfs_revoke_delegation(struct inode *inode)
655+
static void nfs_mark_delegation_revoked(struct nfs_server *server,
656+
struct nfs_delegation *delegation)
657+
{
658+
set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
659+
nfs_mark_return_delegation(server, delegation);
660+
}
661+
662+
static bool nfs_revoke_delegation(struct inode *inode,
663+
const nfs4_stateid *stateid)
656664
{
657665
struct nfs_delegation *delegation;
666+
bool ret = false;
667+
658668
rcu_read_lock();
659669
delegation = rcu_dereference(NFS_I(inode)->delegation);
660-
if (delegation != NULL) {
661-
set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
662-
nfs_mark_return_delegation(NFS_SERVER(inode), delegation);
663-
}
670+
if (delegation == NULL)
671+
goto out;
672+
if (stateid && !nfs4_stateid_match(stateid, &delegation->stateid))
673+
goto out;
674+
nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
675+
ret = true;
676+
out:
664677
rcu_read_unlock();
678+
return ret;
665679
}
666680

667-
void nfs_remove_bad_delegation(struct inode *inode)
681+
void nfs_remove_bad_delegation(struct inode *inode,
682+
const nfs4_stateid *stateid)
668683
{
669684
struct nfs_delegation *delegation;
670685

671-
nfs_revoke_delegation(inode);
686+
if (!nfs_revoke_delegation(inode, stateid))
687+
return;
672688
delegation = nfs_inode_detach_delegation(inode);
673689
if (delegation) {
674690
nfs_inode_find_state_and_recover(inode, &delegation->stateid);

fs/nfs/delegation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags);
4747
void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
4848
int nfs_client_return_marked_delegations(struct nfs_client *clp);
4949
int nfs_delegations_present(struct nfs_client *clp);
50-
void nfs_remove_bad_delegation(struct inode *inode);
50+
void nfs_remove_bad_delegation(struct inode *inode, const nfs4_stateid *stateid);
5151

5252
void nfs_delegation_mark_reclaim(struct nfs_client *clp);
5353
void nfs_delegation_reap_unclaimed(struct nfs_client *clp);

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
10801080
case -NFS4ERR_BAD_STATEID:
10811081
if (state == NULL)
10821082
break;
1083-
nfs_remove_bad_delegation(state->inode);
1083+
nfs_remove_bad_delegation(state->inode, NULL);
10841084
case -NFS4ERR_OPENMODE:
10851085
if (state == NULL)
10861086
break;

fs/nfs/nfs4proc.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,9 +2385,10 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
23852385
return ret;
23862386
}
23872387

2388-
static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state)
2388+
static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state,
2389+
const nfs4_stateid *stateid)
23892390
{
2390-
nfs_remove_bad_delegation(state->inode);
2391+
nfs_remove_bad_delegation(state->inode, stateid);
23912392
write_seqlock(&state->seqlock);
23922393
nfs4_stateid_copy(&state->stateid, &state->open_stateid);
23932394
write_sequnlock(&state->seqlock);
@@ -2397,7 +2398,7 @@ static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state)
23972398
static void nfs40_clear_delegation_stateid(struct nfs4_state *state)
23982399
{
23992400
if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL)
2400-
nfs_finish_clear_delegation_stateid(state);
2401+
nfs_finish_clear_delegation_stateid(state, NULL);
24012402
}
24022403

24032404
static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
@@ -2443,19 +2444,20 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
24432444
rcu_read_unlock();
24442445
return;
24452446
}
2447+
2448+
nfs4_stateid_copy(&stateid, &delegation->stateid);
24462449
if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
24472450
rcu_read_unlock();
2448-
nfs_finish_clear_delegation_stateid(state);
2451+
nfs_finish_clear_delegation_stateid(state, &stateid);
24492452
return;
24502453
}
24512454

2452-
nfs4_stateid_copy(&stateid, &delegation->stateid);
24532455
cred = get_rpccred(delegation->cred);
24542456
rcu_read_unlock();
24552457
status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
24562458
trace_nfs4_test_delegation_stateid(state, NULL, status);
24572459
if (status != NFS_OK)
2458-
nfs_finish_clear_delegation_stateid(state);
2460+
nfs_finish_clear_delegation_stateid(state, &stateid);
24592461

24602462
put_rpccred(cred);
24612463
}

0 commit comments

Comments
 (0)