aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c109
1 files changed, 62 insertions, 47 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 39896afc6edf..1406858bae6c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1683,6 +1683,14 @@ static void nfs_state_set_open_stateid(struct nfs4_state *state,
1683 write_sequnlock(&state->seqlock); 1683 write_sequnlock(&state->seqlock);
1684} 1684}
1685 1685
1686static void nfs_state_clear_open_state_flags(struct nfs4_state *state)
1687{
1688 clear_bit(NFS_O_RDWR_STATE, &state->flags);
1689 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
1690 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
1691 clear_bit(NFS_OPEN_STATE, &state->flags);
1692}
1693
1686static void nfs_state_set_delegation(struct nfs4_state *state, 1694static void nfs_state_set_delegation(struct nfs4_state *state,
1687 const nfs4_stateid *deleg_stateid, 1695 const nfs4_stateid *deleg_stateid,
1688 fmode_t fmode) 1696 fmode_t fmode)
@@ -1907,8 +1915,9 @@ _nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
1907 if (data->o_res.delegation_type != 0) 1915 if (data->o_res.delegation_type != 0)
1908 nfs4_opendata_check_deleg(data, state); 1916 nfs4_opendata_check_deleg(data, state);
1909update: 1917update:
1910 update_open_stateid(state, &data->o_res.stateid, NULL, 1918 if (!update_open_stateid(state, &data->o_res.stateid,
1911 data->o_arg.fmode); 1919 NULL, data->o_arg.fmode))
1920 return ERR_PTR(-EAGAIN);
1912 refcount_inc(&state->count); 1921 refcount_inc(&state->count);
1913 1922
1914 return state; 1923 return state;
@@ -1973,8 +1982,11 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
1973 1982
1974 if (data->o_res.delegation_type != 0) 1983 if (data->o_res.delegation_type != 0)
1975 nfs4_opendata_check_deleg(data, state); 1984 nfs4_opendata_check_deleg(data, state);
1976 update_open_stateid(state, &data->o_res.stateid, NULL, 1985 if (!update_open_stateid(state, &data->o_res.stateid,
1977 data->o_arg.fmode); 1986 NULL, data->o_arg.fmode)) {
1987 nfs4_put_open_state(state);
1988 state = ERR_PTR(-EAGAIN);
1989 }
1978out: 1990out:
1979 nfs_release_seqid(data->o_arg.seqid); 1991 nfs_release_seqid(data->o_arg.seqid);
1980 return state; 1992 return state;
@@ -2074,13 +2086,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
2074{ 2086{
2075 int ret; 2087 int ret;
2076 2088
2077 /* Don't trigger recovery in nfs_test_and_clear_all_open_stateid */
2078 clear_bit(NFS_O_RDWR_STATE, &state->flags);
2079 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
2080 clear_bit(NFS_O_RDONLY_STATE, &state->flags);
2081 /* memory barrier prior to reading state->n_* */ 2089 /* memory barrier prior to reading state->n_* */
2082 clear_bit(NFS_DELEGATED_STATE, &state->flags);
2083 clear_bit(NFS_OPEN_STATE, &state->flags);
2084 smp_rmb(); 2090 smp_rmb();
2085 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE); 2091 ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE);
2086 if (ret != 0) 2092 if (ret != 0)
@@ -2156,6 +2162,8 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
2156 ctx = nfs4_state_find_open_context(state); 2162 ctx = nfs4_state_find_open_context(state);
2157 if (IS_ERR(ctx)) 2163 if (IS_ERR(ctx))
2158 return -EAGAIN; 2164 return -EAGAIN;
2165 clear_bit(NFS_DELEGATED_STATE, &state->flags);
2166 nfs_state_clear_open_state_flags(state);
2159 ret = nfs4_do_open_reclaim(ctx, state); 2167 ret = nfs4_do_open_reclaim(ctx, state);
2160 put_nfs_open_context(ctx); 2168 put_nfs_open_context(ctx);
2161 return ret; 2169 return ret;
@@ -2171,18 +2179,17 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
2171 case -ENOENT: 2179 case -ENOENT:
2172 case -EAGAIN: 2180 case -EAGAIN:
2173 case -ESTALE: 2181 case -ESTALE:
2182 case -ETIMEDOUT:
2174 break; 2183 break;
2175 case -NFS4ERR_BADSESSION: 2184 case -NFS4ERR_BADSESSION:
2176 case -NFS4ERR_BADSLOT: 2185 case -NFS4ERR_BADSLOT:
2177 case -NFS4ERR_BAD_HIGH_SLOT: 2186 case -NFS4ERR_BAD_HIGH_SLOT:
2178 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 2187 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
2179 case -NFS4ERR_DEADSESSION: 2188 case -NFS4ERR_DEADSESSION:
2180 set_bit(NFS_DELEGATED_STATE, &state->flags);
2181 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); 2189 nfs4_schedule_session_recovery(server->nfs_client->cl_session, err);
2182 return -EAGAIN; 2190 return -EAGAIN;
2183 case -NFS4ERR_STALE_CLIENTID: 2191 case -NFS4ERR_STALE_CLIENTID:
2184 case -NFS4ERR_STALE_STATEID: 2192 case -NFS4ERR_STALE_STATEID:
2185 set_bit(NFS_DELEGATED_STATE, &state->flags);
2186 /* Don't recall a delegation if it was lost */ 2193 /* Don't recall a delegation if it was lost */
2187 nfs4_schedule_lease_recovery(server->nfs_client); 2194 nfs4_schedule_lease_recovery(server->nfs_client);
2188 return -EAGAIN; 2195 return -EAGAIN;
@@ -2203,7 +2210,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
2203 return -EAGAIN; 2210 return -EAGAIN;
2204 case -NFS4ERR_DELAY: 2211 case -NFS4ERR_DELAY:
2205 case -NFS4ERR_GRACE: 2212 case -NFS4ERR_GRACE:
2206 set_bit(NFS_DELEGATED_STATE, &state->flags);
2207 ssleep(1); 2213 ssleep(1);
2208 return -EAGAIN; 2214 return -EAGAIN;
2209 case -ENOMEM: 2215 case -ENOMEM:
@@ -2219,8 +2225,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct
2219} 2225}
2220 2226
2221int nfs4_open_delegation_recall(struct nfs_open_context *ctx, 2227int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
2222 struct nfs4_state *state, const nfs4_stateid *stateid, 2228 struct nfs4_state *state, const nfs4_stateid *stateid)
2223 fmode_t type)
2224{ 2229{
2225 struct nfs_server *server = NFS_SERVER(state->inode); 2230 struct nfs_server *server = NFS_SERVER(state->inode);
2226 struct nfs4_opendata *opendata; 2231 struct nfs4_opendata *opendata;
@@ -2231,20 +2236,23 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
2231 if (IS_ERR(opendata)) 2236 if (IS_ERR(opendata))
2232 return PTR_ERR(opendata); 2237 return PTR_ERR(opendata);
2233 nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); 2238 nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
2234 nfs_state_clear_delegation(state); 2239 if (!test_bit(NFS_O_RDWR_STATE, &state->flags)) {
2235 switch (type & (FMODE_READ|FMODE_WRITE)) {
2236 case FMODE_READ|FMODE_WRITE:
2237 case FMODE_WRITE:
2238 err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE); 2240 err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE);
2239 if (err) 2241 if (err)
2240 break; 2242 goto out;
2243 }
2244 if (!test_bit(NFS_O_WRONLY_STATE, &state->flags)) {
2241 err = nfs4_open_recover_helper(opendata, FMODE_WRITE); 2245 err = nfs4_open_recover_helper(opendata, FMODE_WRITE);
2242 if (err) 2246 if (err)
2243 break; 2247 goto out;
2244 /* Fall through */ 2248 }
2245 case FMODE_READ: 2249 if (!test_bit(NFS_O_RDONLY_STATE, &state->flags)) {
2246 err = nfs4_open_recover_helper(opendata, FMODE_READ); 2250 err = nfs4_open_recover_helper(opendata, FMODE_READ);
2251 if (err)
2252 goto out;
2247 } 2253 }
2254 nfs_state_clear_delegation(state);
2255out:
2248 nfs4_opendata_put(opendata); 2256 nfs4_opendata_put(opendata);
2249 return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err); 2257 return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err);
2250} 2258}
@@ -2492,6 +2500,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
2492 if (!ctx) { 2500 if (!ctx) {
2493 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1); 2501 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 1);
2494 data->is_recover = true; 2502 data->is_recover = true;
2503 task_setup_data.flags |= RPC_TASK_TIMEOUT;
2495 } else { 2504 } else {
2496 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0); 2505 nfs4_init_sequence(&o_arg->seq_args, &o_res->seq_res, 1, 0);
2497 pnfs_lgopen_prepare(data, ctx); 2506 pnfs_lgopen_prepare(data, ctx);
@@ -2698,6 +2707,7 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
2698{ 2707{
2699 /* NFSv4.0 doesn't allow for delegation recovery on open expire */ 2708 /* NFSv4.0 doesn't allow for delegation recovery on open expire */
2700 nfs40_clear_delegation_stateid(state); 2709 nfs40_clear_delegation_stateid(state);
2710 nfs_state_clear_open_state_flags(state);
2701 return nfs4_open_expired(sp, state); 2711 return nfs4_open_expired(sp, state);
2702} 2712}
2703 2713
@@ -2740,13 +2750,13 @@ out_free:
2740 return -NFS4ERR_EXPIRED; 2750 return -NFS4ERR_EXPIRED;
2741} 2751}
2742 2752
2743static void nfs41_check_delegation_stateid(struct nfs4_state *state) 2753static int nfs41_check_delegation_stateid(struct nfs4_state *state)
2744{ 2754{
2745 struct nfs_server *server = NFS_SERVER(state->inode); 2755 struct nfs_server *server = NFS_SERVER(state->inode);
2746 nfs4_stateid stateid; 2756 nfs4_stateid stateid;
2747 struct nfs_delegation *delegation; 2757 struct nfs_delegation *delegation;
2748 const struct cred *cred = NULL; 2758 const struct cred *cred = NULL;
2749 int status; 2759 int status, ret = NFS_OK;
2750 2760
2751 /* Get the delegation credential for use by test/free_stateid */ 2761 /* Get the delegation credential for use by test/free_stateid */
2752 rcu_read_lock(); 2762 rcu_read_lock();
@@ -2754,20 +2764,15 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
2754 if (delegation == NULL) { 2764 if (delegation == NULL) {
2755 rcu_read_unlock(); 2765 rcu_read_unlock();
2756 nfs_state_clear_delegation(state); 2766 nfs_state_clear_delegation(state);
2757 return; 2767 return NFS_OK;
2758 } 2768 }
2759 2769
2760 nfs4_stateid_copy(&stateid, &delegation->stateid); 2770 nfs4_stateid_copy(&stateid, &delegation->stateid);
2761 if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
2762 rcu_read_unlock();
2763 nfs_state_clear_delegation(state);
2764 return;
2765 }
2766 2771
2767 if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED, 2772 if (!test_and_clear_bit(NFS_DELEGATION_TEST_EXPIRED,
2768 &delegation->flags)) { 2773 &delegation->flags)) {
2769 rcu_read_unlock(); 2774 rcu_read_unlock();
2770 return; 2775 return NFS_OK;
2771 } 2776 }
2772 2777
2773 if (delegation->cred) 2778 if (delegation->cred)
@@ -2777,9 +2782,24 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state)
2777 trace_nfs4_test_delegation_stateid(state, NULL, status); 2782 trace_nfs4_test_delegation_stateid(state, NULL, status);
2778 if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) 2783 if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID)
2779 nfs_finish_clear_delegation_stateid(state, &stateid); 2784 nfs_finish_clear_delegation_stateid(state, &stateid);
2785 else
2786 ret = status;
2780 2787
2781 if (delegation->cred) 2788 put_cred(cred);
2782 put_cred(cred); 2789 return ret;
2790}
2791
2792static void nfs41_delegation_recover_stateid(struct nfs4_state *state)
2793{
2794 nfs4_stateid tmp;
2795
2796 if (test_bit(NFS_DELEGATED_STATE, &state->flags) &&
2797 nfs4_copy_delegation_stateid(state->inode, state->state,
2798 &tmp, NULL) &&
2799 nfs4_stateid_match_other(&state->stateid, &tmp))
2800 nfs_state_set_delegation(state, &tmp, state->state);
2801 else
2802 nfs_state_clear_delegation(state);
2783} 2803}
2784 2804
2785/** 2805/**
@@ -2849,21 +2869,12 @@ static int nfs41_check_open_stateid(struct nfs4_state *state)
2849 const struct cred *cred = state->owner->so_cred; 2869 const struct cred *cred = state->owner->so_cred;
2850 int status; 2870 int status;
2851 2871
2852 if (test_bit(NFS_OPEN_STATE, &state->flags) == 0) { 2872 if (test_bit(NFS_OPEN_STATE, &state->flags) == 0)
2853 if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0) {
2854 if (nfs4_have_delegation(state->inode, state->state))
2855 return NFS_OK;
2856 return -NFS4ERR_OPENMODE;
2857 }
2858 return -NFS4ERR_BAD_STATEID; 2873 return -NFS4ERR_BAD_STATEID;
2859 }
2860 status = nfs41_test_and_free_expired_stateid(server, stateid, cred); 2874 status = nfs41_test_and_free_expired_stateid(server, stateid, cred);
2861 trace_nfs4_test_open_stateid(state, NULL, status); 2875 trace_nfs4_test_open_stateid(state, NULL, status);
2862 if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) { 2876 if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID) {
2863 clear_bit(NFS_O_RDONLY_STATE, &state->flags); 2877 nfs_state_clear_open_state_flags(state);
2864 clear_bit(NFS_O_WRONLY_STATE, &state->flags);
2865 clear_bit(NFS_O_RDWR_STATE, &state->flags);
2866 clear_bit(NFS_OPEN_STATE, &state->flags);
2867 stateid->type = NFS4_INVALID_STATEID_TYPE; 2878 stateid->type = NFS4_INVALID_STATEID_TYPE;
2868 return status; 2879 return status;
2869 } 2880 }
@@ -2876,7 +2887,11 @@ static int nfs41_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
2876{ 2887{
2877 int status; 2888 int status;
2878 2889
2879 nfs41_check_delegation_stateid(state); 2890 status = nfs41_check_delegation_stateid(state);
2891 if (status != NFS_OK)
2892 return status;
2893 nfs41_delegation_recover_stateid(state);
2894
2880 status = nfs41_check_expired_locks(state); 2895 status = nfs41_check_expired_locks(state);
2881 if (status != NFS_OK) 2896 if (status != NFS_OK)
2882 return status; 2897 return status;
@@ -3201,7 +3216,7 @@ static int _nfs4_do_setattr(struct inode *inode,
3201 3216
3202 if (nfs4_copy_delegation_stateid(inode, FMODE_WRITE, &arg->stateid, &delegation_cred)) { 3217 if (nfs4_copy_delegation_stateid(inode, FMODE_WRITE, &arg->stateid, &delegation_cred)) {
3203 /* Use that stateid */ 3218 /* Use that stateid */
3204 } else if (ctx != NULL) { 3219 } else if (ctx != NULL && ctx->state) {
3205 struct nfs_lock_context *l_ctx; 3220 struct nfs_lock_context *l_ctx;
3206 if (!nfs4_valid_open_stateid(ctx->state)) 3221 if (!nfs4_valid_open_stateid(ctx->state))
3207 return -EBADF; 3222 return -EBADF;