aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorPeng Tao <tao.peng@primarydata.com>2014-09-05 12:53:24 -0400
committerTom Haynes <loghyr@primarydata.com>2015-02-03 14:06:41 -0500
commitce6ab4f238cb76d356229e97e1fefb7192388e13 (patch)
tree928a0be822e46a712597d8ef6b5731f84c5320ce /fs/nfs
parent016256df3a7e9eeb3f4dea5ccd0e21a0b63841eb (diff)
nfs41: don't use a layout if it is marked for returning
And if we are to return the same type of layouts, don't bother sending more layoutgets. Signed-off-by: Peng Tao <tao.peng@primarydata.com> Signed-off-by: Tom Haynes <Thomas.Haynes@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c1
-rw-r--r--fs/nfs/pnfs.c23
-rw-r--r--fs/nfs/pnfs.h1
3 files changed, 20 insertions, 5 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f358262a95f9..19432842b2dc 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -7540,6 +7540,7 @@ nfs4_layoutget_prepare(struct rpc_task *task, void *calldata)
7540 return; 7540 return;
7541 if (pnfs_choose_layoutget_stateid(&lgp->args.stateid, 7541 if (pnfs_choose_layoutget_stateid(&lgp->args.stateid,
7542 NFS_I(lgp->args.inode)->layout, 7542 NFS_I(lgp->args.inode)->layout,
7543 &lgp->args.range,
7543 lgp->args.ctx->state)) { 7544 lgp->args.ctx->state)) {
7544 rpc_exit(task, NFS4_OK); 7545 rpc_exit(task, NFS4_OK);
7545 } 7546 }
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 0bd149baca71..853b544f2efc 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -740,25 +740,37 @@ pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
740 return !pnfs_seqid_is_newer(seqid, lo->plh_barrier); 740 return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
741} 741}
742 742
743static bool
744pnfs_layout_returning(const struct pnfs_layout_hdr *lo,
745 struct pnfs_layout_range *range)
746{
747 return test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) &&
748 (lo->plh_return_iomode == IOMODE_ANY ||
749 lo->plh_return_iomode == range->iomode);
750}
751
743/* lget is set to 1 if called from inside send_layoutget call chain */ 752/* lget is set to 1 if called from inside send_layoutget call chain */
744static bool 753static bool
745pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget) 754pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo,
755 struct pnfs_layout_range *range, int lget)
746{ 756{
747 return lo->plh_block_lgets || 757 return lo->plh_block_lgets ||
748 test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || 758 test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
749 (list_empty(&lo->plh_segs) && 759 (list_empty(&lo->plh_segs) &&
750 (atomic_read(&lo->plh_outstanding) > lget)); 760 (atomic_read(&lo->plh_outstanding) > lget)) ||
761 pnfs_layout_returning(lo, range);
751} 762}
752 763
753int 764int
754pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, 765pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
766 struct pnfs_layout_range *range,
755 struct nfs4_state *open_state) 767 struct nfs4_state *open_state)
756{ 768{
757 int status = 0; 769 int status = 0;
758 770
759 dprintk("--> %s\n", __func__); 771 dprintk("--> %s\n", __func__);
760 spin_lock(&lo->plh_inode->i_lock); 772 spin_lock(&lo->plh_inode->i_lock);
761 if (pnfs_layoutgets_blocked(lo, 1)) { 773 if (pnfs_layoutgets_blocked(lo, range, 1)) {
762 status = -EAGAIN; 774 status = -EAGAIN;
763 } else if (!nfs4_valid_open_stateid(open_state)) { 775 } else if (!nfs4_valid_open_stateid(open_state)) {
764 status = -EBADF; 776 status = -EBADF;
@@ -1192,6 +1204,7 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo,
1192 1204
1193 list_for_each_entry(lseg, &lo->plh_segs, pls_list) { 1205 list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
1194 if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) && 1206 if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
1207 !test_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags) &&
1195 pnfs_lseg_range_match(&lseg->pls_range, range)) { 1208 pnfs_lseg_range_match(&lseg->pls_range, range)) {
1196 ret = pnfs_get_lseg(lseg); 1209 ret = pnfs_get_lseg(lseg);
1197 break; 1210 break;
@@ -1351,7 +1364,7 @@ lookup_again:
1351 goto out_unlock; 1364 goto out_unlock;
1352 } 1365 }
1353 1366
1354 if (pnfs_layoutgets_blocked(lo, 0)) 1367 if (pnfs_layoutgets_blocked(lo, &arg, 0))
1355 goto out_unlock; 1368 goto out_unlock;
1356 atomic_inc(&lo->plh_outstanding); 1369 atomic_inc(&lo->plh_outstanding);
1357 spin_unlock(&ino->i_lock); 1370 spin_unlock(&ino->i_lock);
@@ -1432,7 +1445,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
1432 goto out_forget_reply; 1445 goto out_forget_reply;
1433 } 1446 }
1434 1447
1435 if (pnfs_layoutgets_blocked(lo, 1)) { 1448 if (pnfs_layoutgets_blocked(lo, &lgp->args.range, 1)) {
1436 dprintk("%s forget reply due to state\n", __func__); 1449 dprintk("%s forget reply due to state\n", __func__);
1437 goto out_forget_reply; 1450 goto out_forget_reply;
1438 } 1451 }
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index bea2030eec74..9e6edd1ebbc6 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -249,6 +249,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
249 bool update_barrier); 249 bool update_barrier);
250int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, 250int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
251 struct pnfs_layout_hdr *lo, 251 struct pnfs_layout_hdr *lo,
252 struct pnfs_layout_range *range,
252 struct nfs4_state *open_state); 253 struct nfs4_state *open_state);
253int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, 254int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
254 struct list_head *tmp_list, 255 struct list_head *tmp_list,