diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/callback_proc.c | 4 | ||||
-rw-r--r-- | fs/nfs/delegation.c | 11 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 10 |
3 files changed, 17 insertions, 8 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index fa515d5ea5ba..7b861bbc0b43 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -66,7 +66,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp, | |||
66 | out_iput: | 66 | out_iput: |
67 | rcu_read_unlock(); | 67 | rcu_read_unlock(); |
68 | trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status)); | 68 | trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status)); |
69 | iput(inode); | 69 | nfs_iput_and_deactive(inode); |
70 | out: | 70 | out: |
71 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status)); | 71 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status)); |
72 | return res->status; | 72 | return res->status; |
@@ -108,7 +108,7 @@ __be32 nfs4_callback_recall(void *argp, void *resp, | |||
108 | } | 108 | } |
109 | trace_nfs4_cb_recall(cps->clp, &args->fh, inode, | 109 | trace_nfs4_cb_recall(cps->clp, &args->fh, inode, |
110 | &args->stateid, -ntohl(res)); | 110 | &args->stateid, -ntohl(res)); |
111 | iput(inode); | 111 | nfs_iput_and_deactive(inode); |
112 | out: | 112 | out: |
113 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); | 113 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); |
114 | return res; | 114 | return res; |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 07b839560576..6ec2f78c1e19 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -850,16 +850,23 @@ nfs_delegation_find_inode_server(struct nfs_server *server, | |||
850 | const struct nfs_fh *fhandle) | 850 | const struct nfs_fh *fhandle) |
851 | { | 851 | { |
852 | struct nfs_delegation *delegation; | 852 | struct nfs_delegation *delegation; |
853 | struct inode *res = NULL; | 853 | struct inode *freeme, *res = NULL; |
854 | 854 | ||
855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
856 | spin_lock(&delegation->lock); | 856 | spin_lock(&delegation->lock); |
857 | if (delegation->inode != NULL && | 857 | if (delegation->inode != NULL && |
858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { | 858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { |
859 | res = igrab(delegation->inode); | 859 | freeme = igrab(delegation->inode); |
860 | if (freeme && nfs_sb_active(freeme->i_sb)) | ||
861 | res = freeme; | ||
860 | spin_unlock(&delegation->lock); | 862 | spin_unlock(&delegation->lock); |
861 | if (res != NULL) | 863 | if (res != NULL) |
862 | return res; | 864 | return res; |
865 | if (freeme) { | ||
866 | rcu_read_unlock(); | ||
867 | iput(freeme); | ||
868 | rcu_read_lock(); | ||
869 | } | ||
863 | return ERR_PTR(-EAGAIN); | 870 | return ERR_PTR(-EAGAIN); |
864 | } | 871 | } |
865 | spin_unlock(&delegation->lock); | 872 | spin_unlock(&delegation->lock); |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 62ae0fd345ad..ffea57885394 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -2601,11 +2601,12 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
2601 | nfs4_clear_state_manager_bit(clp); | 2601 | nfs4_clear_state_manager_bit(clp); |
2602 | /* Did we race with an attempt to give us more work? */ | 2602 | /* Did we race with an attempt to give us more work? */ |
2603 | if (clp->cl_state == 0) | 2603 | if (clp->cl_state == 0) |
2604 | break; | 2604 | return; |
2605 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | 2605 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
2606 | break; | 2606 | return; |
2607 | } while (refcount_read(&clp->cl_count) > 1); | 2607 | } while (refcount_read(&clp->cl_count) > 1 && !signalled()); |
2608 | return; | 2608 | goto out_drain; |
2609 | |||
2609 | out_error: | 2610 | out_error: |
2610 | if (strlen(section)) | 2611 | if (strlen(section)) |
2611 | section_sep = ": "; | 2612 | section_sep = ": "; |
@@ -2613,6 +2614,7 @@ out_error: | |||
2613 | " with error %d\n", section_sep, section, | 2614 | " with error %d\n", section_sep, section, |
2614 | clp->cl_hostname, -status); | 2615 | clp->cl_hostname, -status); |
2615 | ssleep(1); | 2616 | ssleep(1); |
2617 | out_drain: | ||
2616 | nfs4_end_drain_session(clp); | 2618 | nfs4_end_drain_session(clp); |
2617 | nfs4_clear_state_manager_bit(clp); | 2619 | nfs4_clear_state_manager_bit(clp); |
2618 | } | 2620 | } |