diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-03-28 14:01:33 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-03-28 16:22:16 -0400 |
commit | 91876b13b8b3cbff5cca8476d4b4eebe5f6038cc (patch) | |
tree | 3a1493eff67c3403392ce7264f5c91f186d41184 /fs/nfs/nfs4proc.c | |
parent | 6e3cf2415269894895074f139ef2e95ef14ddd5d (diff) |
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 3e7d42fb775c..81343944e096 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1373,7 +1373,7 @@ static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
1373 | 1373 | ||
1374 | ctx = nfs4_state_find_open_context(state); | 1374 | ctx = nfs4_state_find_open_context(state); |
1375 | if (IS_ERR(ctx)) | 1375 | if (IS_ERR(ctx)) |
1376 | return PTR_ERR(ctx); | 1376 | return -EAGAIN; |
1377 | ret = nfs4_do_open_reclaim(ctx, state); | 1377 | ret = nfs4_do_open_reclaim(ctx, state); |
1378 | put_nfs_open_context(ctx); | 1378 | put_nfs_open_context(ctx); |
1379 | return ret; | 1379 | return ret; |
@@ -1814,7 +1814,7 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta | |||
1814 | 1814 | ||
1815 | ctx = nfs4_state_find_open_context(state); | 1815 | ctx = nfs4_state_find_open_context(state); |
1816 | if (IS_ERR(ctx)) | 1816 | if (IS_ERR(ctx)) |
1817 | return PTR_ERR(ctx); | 1817 | return -EAGAIN; |
1818 | ret = nfs4_do_open_expired(ctx, state); | 1818 | ret = nfs4_do_open_expired(ctx, state); |
1819 | put_nfs_open_context(ctx); | 1819 | put_nfs_open_context(ctx); |
1820 | return ret; | 1820 | return ret; |
@@ -1936,10 +1936,8 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | |||
1936 | if (ret != 0) | 1936 | if (ret != 0) |
1937 | goto out; | 1937 | goto out; |
1938 | 1938 | ||
1939 | if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) { | 1939 | if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) |
1940 | nfs4_schedule_stateid_recovery(server, state); | 1940 | nfs4_schedule_stateid_recovery(server, state); |
1941 | nfs4_wait_clnt_recover(server->nfs_client); | ||
1942 | } | ||
1943 | *res = state; | 1941 | *res = state; |
1944 | out: | 1942 | out: |
1945 | return ret; | 1943 | return ret; |