aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-12-14 16:25:11 -0500
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-12-28 14:32:40 -0500
commit2e5b29f0448be9ea8da3ee0412a2043fee59e131 (patch)
treebba96a3ec2ae66890652f52552aeab9472824950 /fs/nfs
parent141b9b59ed8ae2602b2c285149ec8d4f6b05c4d9 (diff)
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: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c4
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayoutdev.c16
-rw-r--r--fs/nfs/pnfs.c18
-rw-r--r--fs/nfs/pnfs.h21
4 files changed, 6 insertions, 53 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 5ede5c26c757..1da19d709458 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1399,11 +1399,9 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
1399 1399
1400 switch (err) { 1400 switch (err) {
1401 case -NFS4ERR_RESET_TO_PNFS: 1401 case -NFS4ERR_RESET_TO_PNFS:
1402 pnfs_set_retry_layoutget(hdr->lseg->pls_layout);
1403 ff_layout_reset_write(hdr, true); 1402 ff_layout_reset_write(hdr, true);
1404 return task->tk_status; 1403 return task->tk_status;
1405 case -NFS4ERR_RESET_TO_MDS: 1404 case -NFS4ERR_RESET_TO_MDS:
1406 pnfs_clear_retry_layoutget(hdr->lseg->pls_layout);
1407 ff_layout_reset_write(hdr, false); 1405 ff_layout_reset_write(hdr, false);
1408 return task->tk_status; 1406 return task->tk_status;
1409 case -EAGAIN: 1407 case -EAGAIN:
@@ -1438,11 +1436,9 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
1438 1436
1439 switch (err) { 1437 switch (err) {
1440 case -NFS4ERR_RESET_TO_PNFS: 1438 case -NFS4ERR_RESET_TO_PNFS:
1441 pnfs_set_retry_layoutget(data->lseg->pls_layout);
1442 pnfs_generic_prepare_to_resend_writes(data); 1439 pnfs_generic_prepare_to_resend_writes(data);
1443 return -EAGAIN; 1440 return -EAGAIN;
1444 case -NFS4ERR_RESET_TO_MDS: 1441 case -NFS4ERR_RESET_TO_MDS:
1445 pnfs_clear_retry_layoutget(data->lseg->pls_layout);
1446 pnfs_generic_prepare_to_resend_writes(data); 1442 pnfs_generic_prepare_to_resend_writes(data);
1447 return -EAGAIN; 1443 return -EAGAIN;
1448 case -EAGAIN: 1444 case -EAGAIN:
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index e125e55de86d..bd0327541366 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -429,22 +429,14 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
429 mirror, lseg->pls_range.offset, 429 mirror, lseg->pls_range.offset,
430 lseg->pls_range.length, NFS4ERR_NXIO, 430 lseg->pls_range.length, NFS4ERR_NXIO,
431 OP_ILLEGAL, GFP_NOIO); 431 OP_ILLEGAL, GFP_NOIO);
432 if (fail_return) { 432 if (!fail_return) {
433 pnfs_error_mark_layout_for_return(ino, lseg);
434 if (ff_layout_has_available_ds(lseg))
435 pnfs_set_retry_layoutget(lseg->pls_layout);
436 else
437 pnfs_clear_retry_layoutget(lseg->pls_layout);
438
439 } else {
440 if (ff_layout_has_available_ds(lseg)) 433 if (ff_layout_has_available_ds(lseg))
441 set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE, 434 set_bit(NFS_LAYOUT_RETURN_BEFORE_CLOSE,
442 &lseg->pls_layout->plh_flags); 435 &lseg->pls_layout->plh_flags);
443 else { 436 else
444 pnfs_error_mark_layout_for_return(ino, lseg); 437 pnfs_error_mark_layout_for_return(ino, lseg);
445 pnfs_clear_retry_layoutget(lseg->pls_layout); 438 } else
446 } 439 pnfs_error_mark_layout_for_return(ino, lseg);
447 }
448 } 440 }
449out_update_creds: 441out_update_creds:
450 if (ff_layout_update_mirror_cred(mirror, ds)) 442 if (ff_layout_update_mirror_cred(mirror, ds))
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 580207bc52a5..6b42362cdbb0 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -618,7 +618,6 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)
618 pnfs_get_layout_hdr(lo); 618 pnfs_get_layout_hdr(lo);
619 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); 619 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
620 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); 620 pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
621 pnfs_clear_retry_layoutget(lo);
622 spin_unlock(&nfsi->vfs_inode.i_lock); 621 spin_unlock(&nfsi->vfs_inode.i_lock);
623 pnfs_free_lseg_list(&tmp_list); 622 pnfs_free_lseg_list(&tmp_list);
624 pnfs_put_layout_hdr(lo); 623 pnfs_put_layout_hdr(lo);
@@ -1094,7 +1093,6 @@ bool pnfs_roc(struct inode *ino)
1094 &lo->plh_flags)) 1093 &lo->plh_flags))
1095 layoutreturn = pnfs_prepare_layoutreturn(lo); 1094 layoutreturn = pnfs_prepare_layoutreturn(lo);
1096 1095
1097 pnfs_clear_retry_layoutget(lo);
1098 list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list) 1096 list_for_each_entry_safe(lseg, tmp, &lo->plh_segs, pls_list)
1099 /* If we are sending layoutreturn, invalidate all valid lsegs */ 1097 /* If we are sending layoutreturn, invalidate all valid lsegs */
1100 if (layoutreturn || test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) { 1098 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 return ret; 1455 return ret;
1458} 1456}
1459 1457
1460/* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */
1461static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key, int mode)
1462{
1463 if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags))
1464 return 1;
1465 return nfs_wait_bit_killable(key, mode);
1466}
1467
1468static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo) 1458static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
1469{ 1459{
1470 if (!pnfs_should_retry_layoutget(lo))
1471 return false;
1472 /* 1460 /*
1473 * send layoutcommit as it can hold up layoutreturn due to lseg 1461 * send layoutcommit as it can hold up layoutreturn due to lseg
1474 * reference 1462 * reference
1475 */ 1463 */
1476 pnfs_layoutcommit_inode(lo->plh_inode, false); 1464 pnfs_layoutcommit_inode(lo->plh_inode, false);
1477 return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN, 1465 return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
1478 pnfs_layoutget_retry_bit_wait, 1466 nfs_wait_bit_killable,
1479 TASK_UNINTERRUPTIBLE); 1467 TASK_UNINTERRUPTIBLE);
1480} 1468}
1481 1469
@@ -1550,8 +1538,7 @@ lookup_again:
1550 } 1538 }
1551 1539
1552 /* if LAYOUTGET already failed once we don't try again */ 1540 /* if LAYOUTGET already failed once we don't try again */
1553 if (pnfs_layout_io_test_failed(lo, iomode) && 1541 if (pnfs_layout_io_test_failed(lo, iomode)) {
1554 !pnfs_should_retry_layoutget(lo)) {
1555 trace_pnfs_update_layout(ino, pos, count, iomode, lo, 1542 trace_pnfs_update_layout(ino, pos, count, iomode, lo,
1556 PNFS_UPDATE_LAYOUT_IO_TEST_FAIL); 1543 PNFS_UPDATE_LAYOUT_IO_TEST_FAIL);
1557 goto out_unlock; 1544 goto out_unlock;
@@ -1628,7 +1615,6 @@ lookup_again:
1628 arg.length = PAGE_CACHE_ALIGN(arg.length); 1615 arg.length = PAGE_CACHE_ALIGN(arg.length);
1629 1616
1630 lseg = send_layoutget(lo, ctx, &arg, gfp_flags); 1617 lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
1631 pnfs_clear_retry_layoutget(lo);
1632 atomic_dec(&lo->plh_outstanding); 1618 atomic_dec(&lo->plh_outstanding);
1633 trace_pnfs_update_layout(ino, pos, count, iomode, lo, 1619 trace_pnfs_update_layout(ino, pos, count, iomode, lo,
1634 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET); 1620 PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET);
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index d1990e90e7a0..6916ff4e86f9 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -98,7 +98,6 @@ enum {
98 NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */ 98 NFS_LAYOUT_RETURN_BEFORE_CLOSE, /* Return this layout before close */
99 NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */ 99 NFS_LAYOUT_INVALID_STID, /* layout stateid id is invalid */
100 NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ 100 NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */
101 NFS_LAYOUT_RETRY_LAYOUTGET, /* Retry layoutget */
102}; 101};
103 102
104enum layoutdriver_policy_flags { 103enum layoutdriver_policy_flags {
@@ -379,26 +378,6 @@ nfs4_get_deviceid(struct nfs4_deviceid_node *d)
379 return d; 378 return d;
380} 379}
381 380
382static inline void pnfs_set_retry_layoutget(struct pnfs_layout_hdr *lo)
383{
384 if (!test_and_set_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags))
385 atomic_inc(&lo->plh_refcount);
386}
387
388static inline void pnfs_clear_retry_layoutget(struct pnfs_layout_hdr *lo)
389{
390 if (test_and_clear_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags)) {
391 atomic_dec(&lo->plh_refcount);
392 /* wake up waiters for LAYOUTRETURN as that is not needed */
393 wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
394 }
395}
396
397static inline bool pnfs_should_retry_layoutget(struct pnfs_layout_hdr *lo)
398{
399 return test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, &lo->plh_flags);
400}
401
402static inline struct pnfs_layout_segment * 381static inline struct pnfs_layout_segment *
403pnfs_get_lseg(struct pnfs_layout_segment *lseg) 382pnfs_get_lseg(struct pnfs_layout_segment *lseg)
404{ 383{