Commit 91876b13 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Fix another reboot recovery race

If the open_context for the file is not yet fully initialised,
then open recovery cannot succeed, and since nfs4_state_find_open_context
returns an ENOENT, we end up treating the file as being irrecoverable.

What we really want to do, is just defer the recovery until later.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6e3cf241
...@@ -1373,7 +1373,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta ...@@ -1373,7 +1373,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta
ctx = nfs4_state_find_open_context(state); ctx = nfs4_state_find_open_context(state);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return -EAGAIN;
ret = nfs4_do_open_reclaim(ctx, state); ret = nfs4_do_open_reclaim(ctx, state);
put_nfs_open_context(ctx); put_nfs_open_context(ctx);
return ret; return ret;
...@@ -1814,7 +1814,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta ...@@ -1814,7 +1814,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta
ctx = nfs4_state_find_open_context(state); ctx = nfs4_state_find_open_context(state);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
return PTR_ERR(ctx); return -EAGAIN;
ret = nfs4_do_open_expired(ctx, state); ret = nfs4_do_open_expired(ctx, state);
put_nfs_open_context(ctx); put_nfs_open_context(ctx);
return ret; return ret;
...@@ -1936,10 +1936,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, ...@@ -1936,10 +1936,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
if (ret != 0) if (ret != 0)
goto out; goto out;
if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) { if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
nfs4_schedule_stateid_recovery(server, state); nfs4_schedule_stateid_recovery(server, state);
nfs4_wait_clnt_recover(server->nfs_client);
}
*res = state; *res = state;
out: out:
return ret; return ret;
......
...@@ -1476,6 +1476,8 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs ...@@ -1476,6 +1476,8 @@ static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs
*/ */
nfs4_state_mark_recovery_failed(state, status); nfs4_state_mark_recovery_failed(state, status);
break; break;
case -EAGAIN:
ssleep(1);
case -NFS4ERR_ADMIN_REVOKED: case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_STALE_STATEID: case -NFS4ERR_STALE_STATEID:
case -NFS4ERR_BAD_STATEID: case -NFS4ERR_BAD_STATEID:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment