Commit 2e5b29f0 authored by Trond Myklebust's avatar Trond Myklebust

pNFS/flexfiles: Don't prevent flexfiles client from retrying LAYOUTGET

Fix a bug in which flexfiles clients are falling back to I/O through the
MDS even when the FF_FLAGS_NO_IO_THRU_MDS flag is set.

The flexfiles client will always report errors through the LAYOUTRETURN
and/or LAYOUTERROR mechanisms, so it should normally be safe for it
to retry the LAYOUTGET until it fails or succeeds.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 141b9b59
...@@ -1399,11 +1399,9 @@ static int ff_layout_write_done_cb(struct rpc_task *task, ...@@ -1399,11 +1399,9 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
switch (err) { switch (err) {
case -NFS4ERR_RESET_TO_PNFS: case -NFS4ERR_RESET_TO_PNFS:
pnfs_set_retry_layoutget(hdr->lseg->pls_layout);
ff_layout_reset_write(hdr, true); ff_layout_reset_write(hdr, true);
return task->tk_status; return task->tk_status;
case -NFS4ERR_RESET_TO_MDS: case -NFS4ERR_RESET_TO_MDS:
pnfs_clear_retry_layoutget(hdr->lseg->pls_layout);
ff_layout_reset_write(hdr, false); ff_layout_reset_write(hdr, false);
return task->tk_status; return task->tk_status;
case -EAGAIN: case -EAGAIN:
...@@ -1438,11 +1436,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task, ...@@ -1438,11 +1436,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
switch (err) { switch (err) {
case -NFS4ERR_RESET_TO_PNFS: case -NFS4ERR_RESET_TO_PNFS:
pnfs_set_retry_layoutget(data->lseg->pls_layout);
pnfs_generic_prepare_to_resend_writes(data); pnfs_generic_prepare_to_resend_writes(data);
return -EAGAIN; return -EAGAIN;
case -NFS4ERR_RESET_TO_MDS: case -NFS4ERR_RESET_TO_MDS:
pnfs_clear_retry_layoutget(data->lseg->pls_layout);
pnfs_generic_prepare_to_resend_writes(data); pnfs_generic_prepare_to_resend_writes(data);
return -EAGAIN; return -EAGAIN;
case -EAGAIN: case -EAGAIN:
......
...@@ -429,22 +429,14 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx, ...@@ -429,22 +429,14 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
mirror, lseg->pls_range.offset, mirror, lseg->pls_range.offset,
lseg->pls_range.length, NFS4ERR_NXIO, lseg->pls_range.length, NFS4ERR_NXIO,
OP_ILLEGAL, GFP_NOIO); OP_ILLEGAL, GFP_NOIO);
if (fail_return) { if (!fail_return) {
pnfs_error_mark_layout_for_return(ino, lseg);
if (ff_layout_has_available_ds(lseg))
pnfs_set_retry_layoutget(lseg->pls_layout);
else
pnfs_clear_retry_layoutget(lseg->pls_layout);
} else {
if (ff_layout_has_available_ds(lseg)) if (ff_layout_has_available_ds(lseg))
set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
&lseg->pls_layout->plh_flags); &lseg->pls_layout->plh_flags);
else { else
pnfs_error_mark_layout_for_return(ino, lseg); pnfs_error_mark_layout_for_return(ino, lseg);
pnfs_clear_retry_layoutget(lseg->pls_layout); } else
} pnfs_error_mark_layout_for_return(ino, lseg);
}
} }
out_update_creds: out_update_creds:
if (ff_layout_update_mirror_cred(mirror, ds)) if (ff_layout_update_mirror_cred(mirror, ds))
......
...@@ -618,7 +618,6 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) ...@@ -618,7 +618,6 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
pnfs_get_layout_hdr(lo); pnfs_get_layout_hdr(lo);
pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
pnfs_clear_retry_layoutget(lo);
spin_unlock(&nfsi->vfs_inode.i_lock); spin_unlock(&nfsi->vfs_inode.i_lock);
pnfs_free_lseg_list(&tmp_list); pnfs_free_lseg_list(&tmp_list);
pnfs_put_layout_hdr(lo); pnfs_put_layout_hdr(lo);
...@@ -1094,7 +1093,6 @@ bool pnfs_roc(struct inode *ino) ...@@ -1094,7 +1093,6 @@ bool pnfs_roc(struct inode *ino)
&lo->plh_flags)) &lo->plh_flags))
layoutreturn = pnfs_prepare_layoutreturn(lo); layoutreturn = pnfs_prepare_layoutreturn(lo);
pnfs_clear_retry_layoutget(lo);
list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list) list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list)
/* If we are sending layoutreturn, invalidate all valid lsegs */ /* If we are sending layoutreturn, invalidate all valid lsegs */
if (layoutreturn || test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) { if (layoutreturn || test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) {
...@@ -1457,25 +1455,15 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx, ...@@ -1457,25 +1455,15 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
return ret; return ret;
} }
/* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */
static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode)
{
if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags))
return 1;
return nfs_wait_bit_killable(key, mode);
}
static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
{ {
if (!pnfs_should_retry_layoutget(lo))
return false;
/* /*
* send layoutcommit as it can hold up layoutreturn due to lseg * send layoutcommit as it can hold up layoutreturn due to lseg
* reference * reference
*/ */
pnfs_layoutcommit_inode(lo->plh_inode, false); pnfs_layoutcommit_inode(lo->plh_inode, false);
return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN, return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
pnfs_layoutget_retry_bit_wait, nfs_wait_bit_killable,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
...@@ -1550,8 +1538,7 @@ pnfs_update_layout(struct inode *ino, ...@@ -1550,8 +1538,7 @@ pnfs_update_layout(struct inode *ino,
} }
/* if LAYOUTGET already failed once we don't try again */ /* if LAYOUTGET already failed once we don't try again */
if (pnfs_layout_io_test_failed(lo, iomode) && if (pnfs_layout_io_test_failed(lo, iomode)) {
!pnfs_should_retry_layoutget(lo)) {
trace_pnfs_update_layout(ino, pos, count, iomode, lo, trace_pnfs_update_layout(ino, pos, count, iomode, lo,
PNFS_UPDATE_LAYOUT_IO_TEST_FAIL); PNFS_UPDATE_LAYOUT_IO_TEST_FAIL);
goto out_unlock; goto out_unlock;
...@@ -1628,7 +1615,6 @@ pnfs_update_layout(struct inode *ino, ...@@ -1628,7 +1615,6 @@ pnfs_update_layout(struct inode *ino,
arg.length = PAGE_CACHE_ALIGN(arg.length); arg.length = PAGE_CACHE_ALIGN(arg.length);
lseg = send_layoutget(lo, ctx, &arg, gfp_flags); lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
pnfs_clear_retry_layoutget(lo);
atomic_dec(&lo->plh_outstanding); atomic_dec(&lo->plh_outstanding);
trace_pnfs_update_layout(ino, pos, count, iomode, lo, trace_pnfs_update_layout(ino, pos, count, iomode, lo,
PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
......
...@@ -98,7 +98,6 @@ enum { ...@@ -98,7 +98,6 @@ enum {
NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */ NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
NFS_LAYOUT_RETRY_LAYOUTGET, /* Retry layoutget */
}; };
enum layoutdriver_policy_flags { enum layoutdriver_policy_flags {
...@@ -379,26 +378,6 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d) ...@@ -379,26 +378,6 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d)
return d; return d;
} }
static inline void pnfs_set_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (!test_and_set_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags))
atomic_inc(&lo->plh_refcount);
}
static inline void pnfs_clear_retry_layoutget(struct pnfs_layout_hdr *lo)
{
if (test_and_clear_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags)) {
atomic_dec(&lo->plh_refcount);
/* wake up waiters for LAYOUTRETURN as that is not needed */
wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
}
}
static inline bool pnfs_should_retry_layoutget(struct pnfs_layout_hdr *lo)
{
return test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags);
}
static inline struct pnfs_layout_segment * static inline struct pnfs_layout_segment *
pnfs_get_lseg(struct pnfs_layout_segment *lseg) pnfs_get_lseg(struct pnfs_layout_segment *lseg)
{ {
......
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