diff options
author | Peng Tao <tao.peng@primarydata.com> | 2014-09-05 12:53:24 -0400 |
---|---|---|
committer | Tom Haynes <loghyr@primarydata.com> | 2015-02-03 14:06:41 -0500 |
commit | ce6ab4f238cb76d356229e97e1fefb7192388e13 (patch) | |
tree | 928a0be822e46a712597d8ef6b5731f84c5320ce /fs/nfs | |
parent | 016256df3a7e9eeb3f4dea5ccd0e21a0b63841eb (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.c | 1 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 23 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 1 |
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 | ||
743 | static bool | ||
744 | pnfs_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 */ |
744 | static bool | 753 | static bool |
745 | pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget) | 754 | pnfs_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 | ||
753 | int | 764 | int |
754 | pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, | 765 | pnfs_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); |
250 | int pnfs_choose_layoutget_stateid(nfs4_stateid *dst, | 250 | int 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); |
253 | int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, | 254 | int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo, |
254 | struct list_head *tmp_list, | 255 | struct list_head *tmp_list, |