diff options
| author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-07-22 04:54:29 -0400 |
|---|---|---|
| committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-08-04 22:35:40 -0400 |
| commit | c34fae003c79570b6c930b425fea3f0b7b1e7056 (patch) | |
| tree | 1ff4f0eb398bfa7d4eb2553651f31ce8981f45d9 | |
| parent | 86dbd08b32838dc8940ccab2eebd47cf80224494 (diff) | |
NFSv4: When recovering state fails with EAGAIN, retry the same recovery
If the server returns with EAGAIN when we're trying to recover from
a server reboot, we currently delay for 1 second, but then mark the
stateid as needing recovery after the grace period has expired.
Instead, we should just retry the same recovery process immediately
after the 1 second delay. Break out of the loop after 10 retries.
Fixes: 35a61606a612 ("NFS: Reduce indentation of the switch statement...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
| -rw-r--r-- | fs/nfs/nfs4state.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index a71a61e5fe2c..d03b9cf42bd0 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -1607,6 +1607,7 @@ static int __nfs4_reclaim_open_state(struct nfs4_state_owner *sp, struct nfs4_st | |||
| 1607 | static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops) | 1607 | static int nfs4_reclaim_open_state(struct nfs4_state_owner *sp, const struct nfs4_state_recovery_ops *ops) |
| 1608 | { | 1608 | { |
| 1609 | struct nfs4_state *state; | 1609 | struct nfs4_state *state; |
| 1610 | unsigned int loop = 0; | ||
| 1610 | int status = 0; | 1611 | int status = 0; |
| 1611 | 1612 | ||
| 1612 | /* Note: we rely on the sp->so_states list being ordered | 1613 | /* Note: we rely on the sp->so_states list being ordered |
| @@ -1633,8 +1634,10 @@ restart: | |||
| 1633 | 1634 | ||
| 1634 | switch (status) { | 1635 | switch (status) { |
| 1635 | default: | 1636 | default: |
| 1636 | if (status >= 0) | 1637 | if (status >= 0) { |
| 1638 | loop = 0; | ||
| 1637 | break; | 1639 | break; |
| 1640 | } | ||
| 1638 | printk(KERN_ERR "NFS: %s: unhandled error %d\n", __func__, status); | 1641 | printk(KERN_ERR "NFS: %s: unhandled error %d\n", __func__, status); |
| 1639 | /* Fall through */ | 1642 | /* Fall through */ |
| 1640 | case -ENOENT: | 1643 | case -ENOENT: |
| @@ -1648,6 +1651,10 @@ restart: | |||
| 1648 | break; | 1651 | break; |
| 1649 | case -EAGAIN: | 1652 | case -EAGAIN: |
| 1650 | ssleep(1); | 1653 | ssleep(1); |
| 1654 | if (loop++ < 10) { | ||
| 1655 | set_bit(ops->state_flag_bit, &state->flags); | ||
| 1656 | break; | ||
| 1657 | } | ||
| 1651 | /* Fall through */ | 1658 | /* Fall through */ |
| 1652 | case -NFS4ERR_ADMIN_REVOKED: | 1659 | case -NFS4ERR_ADMIN_REVOKED: |
| 1653 | case -NFS4ERR_STALE_STATEID: | 1660 | case -NFS4ERR_STALE_STATEID: |
