summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/pnfs.c15
-rw-r--r--fs/nfs/pnfs.h1
2 files changed, 15 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index f46f9bc4f76..2c59da5511d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -35,6 +35,7 @@
#include "iostat.h"
#define NFSDBG_FACILITY NFSDBG_PNFS
+#define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
/* Locking:
*
@@ -248,6 +249,7 @@ pnfs_iomode_to_fail_bit(u32 iomode)
static void
pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
{
+ lo->plh_retry_timestamp = jiffies;
set_bit(pnfs_iomode_to_fail_bit(iomode), &lo->plh_flags);
dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
iomode == IOMODE_RW ? "RW" : "READ");
@@ -256,7 +258,18 @@ pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
static bool
pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode)
{
- return test_bit(pnfs_iomode_to_fail_bit(iomode), &lo->plh_flags) != 0;
+ unsigned long start, end;
+ if (test_bit(pnfs_iomode_to_fail_bit(iomode), &lo->plh_flags) == 0)
+ return false;
+ end = jiffies;
+ start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT;
+ if (!time_in_range(lo->plh_retry_timestamp, start, end)) {
+ /* It is time to retry the failed layoutgets */
+ clear_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags);
+ clear_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags);
+ return false;
+ }
+ return true;
}
static void
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index e3eb7d1b17a..bc8e5001203 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -140,6 +140,7 @@ struct pnfs_layout_hdr {
atomic_t plh_outstanding; /* number of RPCs out */
unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */
u32 plh_barrier; /* ignore lower seqids */
+ unsigned long plh_retry_timestamp;
unsigned long plh_flags;
loff_t plh_lwb; /* last write byte for layoutcommit */
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */