aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-11-30 19:22:23 -0500
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:51 -0500
commitaa8a45ee974dfe3ffe290daaf5db457afae56fde (patch)
tree10d2b6eb4a9530f2d1a3433627b401d907c3bdb7 /fs/nfs/pnfs.c
parent012fa16dca0da6c487dd066829ff0b0954925fe6 (diff)
nfs41: wait for LAYOUTRETURN before retrying LAYOUTGET
Also take care to stop waiting if someone clears retry bit. Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 893f6b5afe6a..c4c9fe606ae6 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1398,6 +1398,26 @@ static bool pnfs_within_mdsthreshold(struct nfs_open_context *ctx,
1398 return ret; 1398 return ret;
1399} 1399}
1400 1400
1401/* stop waiting if someone clears NFS_LAYOUT_RETRY_LAYOUTGET bit. */
1402static int pnfs_layoutget_retry_bit_wait(struct wait_bit_key *key)
1403{
1404 if (!test_bit(NFS_LAYOUT_RETRY_LAYOUTGET, key->flags))
1405 return 1;
1406 return nfs_wait_bit_killable(key);
1407}
1408
1409static bool pnfs_prepare_to_retry_layoutget(struct pnfs_layout_hdr *lo)
1410{
1411 /*
1412 * send layoutcommit as it can hold up layoutreturn due to lseg
1413 * reference
1414 */
1415 pnfs_layoutcommit_inode(lo->plh_inode, false);
1416 return !wait_on_bit_action(&lo->plh_flags, NFS_LAYOUT_RETURN,
1417 pnfs_layoutget_retry_bit_wait,
1418 TASK_UNINTERRUPTIBLE);
1419}
1420
1401/* 1421/*
1402 * Layout segment is retreived from the server if not cached. 1422 * Layout segment is retreived from the server if not cached.
1403 * The appropriate layout segment is referenced and returned to the caller. 1423 * The appropriate layout segment is referenced and returned to the caller.
@@ -1444,7 +1464,8 @@ lookup_again:
1444 } 1464 }
1445 1465
1446 /* if LAYOUTGET already failed once we don't try again */ 1466 /* if LAYOUTGET already failed once we don't try again */
1447 if (pnfs_layout_io_test_failed(lo, iomode)) 1467 if (pnfs_layout_io_test_failed(lo, iomode) &&
1468 !pnfs_should_retry_layoutget(lo))
1448 goto out_unlock; 1469 goto out_unlock;
1449 1470
1450 first = list_empty(&lo->plh_segs); 1471 first = list_empty(&lo->plh_segs);
@@ -1469,6 +1490,22 @@ lookup_again:
1469 goto out_unlock; 1490 goto out_unlock;
1470 } 1491 }
1471 1492
1493 /*
1494 * Because we free lsegs before sending LAYOUTRETURN, we need to wait
1495 * for LAYOUTRETURN even if first is true.
1496 */
1497 if (!lseg && pnfs_should_retry_layoutget(lo) &&
1498 test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
1499 spin_unlock(&ino->i_lock);
1500 dprintk("%s wait for layoutreturn\n", __func__);
1501 if (pnfs_prepare_to_retry_layoutget(lo)) {
1502 pnfs_put_layout_hdr(lo);
1503 dprintk("%s retrying\n", __func__);
1504 goto lookup_again;
1505 }
1506 goto out_put_layout_hdr;
1507 }
1508
1472 if (pnfs_layoutgets_blocked(lo, &arg, 0)) 1509 if (pnfs_layoutgets_blocked(lo, &arg, 0))
1473 goto out_unlock; 1510 goto out_unlock;
1474 atomic_inc(&lo->plh_outstanding); 1511 atomic_inc(&lo->plh_outstanding);