diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-09-22 13:38:58 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-09-27 14:33:37 -0400 |
commit | 41020b671aa553f31e766fd1e9d38598eba72bd6 (patch) | |
tree | 1733c68445df37fda9424a27bf9866335bcdb47d /fs | |
parent | 4586f6e2832776e070cc5eb88c2b2f0177e928ae (diff) |
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 <trond.myklebust@primarydata.com>
Tested-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/delegation.c | 30 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 2 | ||||
-rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 14 |
4 files changed, 33 insertions, 15 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index b9c65421ed81..e5212e5c73d2 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -652,23 +652,39 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl | |||
652 | rcu_read_unlock(); | 652 | rcu_read_unlock(); |
653 | } | 653 | } |
654 | 654 | ||
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) | ||
656 | { | 664 | { |
657 | struct nfs_delegation *delegation; | 665 | struct nfs_delegation *delegation; |
666 | bool ret = false; | ||
667 | |||
658 | rcu_read_lock(); | 668 | rcu_read_lock(); |
659 | delegation = rcu_dereference(NFS_I(inode)->delegation); | 669 | delegation = rcu_dereference(NFS_I(inode)->delegation); |
660 | if (delegation != NULL) { | 670 | if (delegation == NULL) |
661 | set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); | 671 | goto out; |
662 | nfs_mark_return_delegation(NFS_SERVER(inode), delegation); | 672 | if (stateid && !nfs4_stateid_match(stateid, &delegation->stateid)) |
663 | } | 673 | goto out; |
674 | nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation); | ||
675 | ret = true; | ||
676 | out: | ||
664 | rcu_read_unlock(); | 677 | rcu_read_unlock(); |
678 | return ret; | ||
665 | } | 679 | } |
666 | 680 | ||
667 | void nfs_remove_bad_delegation(struct inode *inode) | 681 | void nfs_remove_bad_delegation(struct inode *inode, |
682 | const nfs4_stateid *stateid) | ||
668 | { | 683 | { |
669 | struct nfs_delegation *delegation; | 684 | struct nfs_delegation *delegation; |
670 | 685 | ||
671 | nfs_revoke_delegation(inode); | 686 | if (!nfs_revoke_delegation(inode, stateid)) |
687 | return; | ||
672 | delegation = nfs_inode_detach_delegation(inode); | 688 | delegation = nfs_inode_detach_delegation(inode); |
673 | if (delegation) { | 689 | if (delegation) { |
674 | nfs_inode_find_state_and_recover(inode, &delegation->stateid); | 690 | nfs_inode_find_state_and_recover(inode, &delegation->stateid); |
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 64724d252a79..d40827af5913 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
@@ -47,7 +47,7 @@ void nfs_expire_unused_delegation_types(struct nfs_client *clp, fmode_t flags); | |||
47 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); | 47 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); |
48 | int nfs_client_return_marked_delegations(struct nfs_client *clp); | 48 | int nfs_client_return_marked_delegations(struct nfs_client *clp); |
49 | int nfs_delegations_present(struct nfs_client *clp); | 49 | 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); |
51 | 51 | ||
52 | void nfs_delegation_mark_reclaim(struct nfs_client *clp); | 52 | void nfs_delegation_mark_reclaim(struct nfs_client *clp); |
53 | void nfs_delegation_reap_unclaimed(struct nfs_client *clp); | 53 | void nfs_delegation_reap_unclaimed(struct nfs_client *clp); |
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 51b51369704c..98ace127bf86 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
@@ -1080,7 +1080,7 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task, | |||
1080 | case -NFS4ERR_BAD_STATEID: | 1080 | case -NFS4ERR_BAD_STATEID: |
1081 | if (state == NULL) | 1081 | if (state == NULL) |
1082 | break; | 1082 | break; |
1083 | nfs_remove_bad_delegation(state->inode); | 1083 | nfs_remove_bad_delegation(state->inode, NULL); |
1084 | case -NFS4ERR_OPENMODE: | 1084 | case -NFS4ERR_OPENMODE: |
1085 | if (state == NULL) | 1085 | if (state == NULL) |
1086 | break; | 1086 | break; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 04baee4327b2..4cc86001220a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2385,9 +2385,10 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
2385 | return ret; | 2385 | return ret; |
2386 | } | 2386 | } |
2387 | 2387 | ||
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) | ||
2389 | { | 2390 | { |
2390 | nfs_remove_bad_delegation(state->inode); | 2391 | nfs_remove_bad_delegation(state->inode, stateid); |
2391 | write_seqlock(&state->seqlock); | 2392 | write_seqlock(&state->seqlock); |
2392 | nfs4_stateid_copy(&state->stateid, &state->open_stateid); | 2393 | nfs4_stateid_copy(&state->stateid, &state->open_stateid); |
2393 | write_sequnlock(&state->seqlock); | 2394 | write_sequnlock(&state->seqlock); |
@@ -2397,7 +2398,7 @@ static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state) | |||
2397 | static void nfs40_clear_delegation_stateid(struct nfs4_state *state) | 2398 | static void nfs40_clear_delegation_stateid(struct nfs4_state *state) |
2398 | { | 2399 | { |
2399 | if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL) | 2400 | 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); |
2401 | } | 2402 | } |
2402 | 2403 | ||
2403 | static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) | 2404 | 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) | |||
2443 | rcu_read_unlock(); | 2444 | rcu_read_unlock(); |
2444 | return; | 2445 | return; |
2445 | } | 2446 | } |
2447 | |||
2448 | nfs4_stateid_copy(&stateid, &delegation->stateid); | ||
2446 | if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { | 2449 | if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { |
2447 | rcu_read_unlock(); | 2450 | rcu_read_unlock(); |
2448 | nfs_finish_clear_delegation_stateid(state); | 2451 | nfs_finish_clear_delegation_stateid(state, &stateid); |
2449 | return; | 2452 | return; |
2450 | } | 2453 | } |
2451 | 2454 | ||
2452 | nfs4_stateid_copy(&stateid, &delegation->stateid); | ||
2453 | cred = get_rpccred(delegation->cred); | 2455 | cred = get_rpccred(delegation->cred); |
2454 | rcu_read_unlock(); | 2456 | rcu_read_unlock(); |
2455 | status = nfs41_test_and_free_expired_stateid(server, &stateid, cred); | 2457 | status = nfs41_test_and_free_expired_stateid(server, &stateid, cred); |
2456 | trace_nfs4_test_delegation_stateid(state, NULL, status); | 2458 | trace_nfs4_test_delegation_stateid(state, NULL, status); |
2457 | if (status != NFS_OK) | 2459 | if (status != NFS_OK) |
2458 | nfs_finish_clear_delegation_stateid(state); | 2460 | nfs_finish_clear_delegation_stateid(state, &stateid); |
2459 | 2461 | ||
2460 | put_rpccred(cred); | 2462 | put_rpccred(cred); |
2461 | } | 2463 | } |