aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@primarydata.com>2014-05-15 11:56:56 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2014-05-29 11:11:50 -0400
commitc6194271f94b81042bbc45034d31f9b0920f3905 (patch)
tree6194a5964bc781121688f2a1480aee4609c522cd /fs/nfs
parent19b54848fee419f0bb35479e4ea98d9f2b985657 (diff)
pnfs: filelayout: support non page aligned layouts
Use the new pg_test interface to adjust requests to fit in the current stripe / segment. Signed-off-by: Weston Andros Adamson <dros@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4filelayout.c52
1 files changed, 20 insertions, 32 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 0ebc521ea6fc..63a16375660a 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -639,7 +639,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
639 struct nfs4_deviceid_node *d; 639 struct nfs4_deviceid_node *d;
640 struct nfs4_file_layout_dsaddr *dsaddr; 640 struct nfs4_file_layout_dsaddr *dsaddr;
641 int status = -EINVAL; 641 int status = -EINVAL;
642 struct nfs_server *nfss = NFS_SERVER(lo->plh_inode);
643 642
644 dprintk("--> %s\n", __func__); 643 dprintk("--> %s\n", __func__);
645 644
@@ -657,7 +656,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
657 goto out; 656 goto out;
658 } 657 }
659 658
660 if (!fl->stripe_unit || fl->stripe_unit % PAGE_SIZE) { 659 if (!fl->stripe_unit) {
661 dprintk("%s Invalid stripe unit (%u)\n", 660 dprintk("%s Invalid stripe unit (%u)\n",
662 __func__, fl->stripe_unit); 661 __func__, fl->stripe_unit);
663 goto out; 662 goto out;
@@ -694,12 +693,6 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo,
694 goto out_put; 693 goto out_put;
695 } 694 }
696 695
697 if (fl->stripe_unit % nfss->rsize || fl->stripe_unit % nfss->wsize) {
698 dprintk("%s Stripe unit (%u) not aligned with rsize %u "
699 "wsize %u\n", __func__, fl->stripe_unit, nfss->rsize,
700 nfss->wsize);
701 }
702
703 status = 0; 696 status = 0;
704out: 697out:
705 dprintk("--> %s returns %d\n", __func__, status); 698 dprintk("--> %s returns %d\n", __func__, status);
@@ -936,44 +929,42 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
936{ 929{
937 unsigned int size; 930 unsigned int size;
938 u64 p_stripe, r_stripe; 931 u64 p_stripe, r_stripe;
939 u32 stripe_unit; 932 u32 stripe_offset;
933 u64 segment_offset = pgio->pg_lseg->pls_range.offset;
934 u32 stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit;
940 935
941 /* calls nfs_generic_pg_test */ 936 /* calls nfs_generic_pg_test */
942 size = pnfs_generic_pg_test(pgio, prev, req); 937 size = pnfs_generic_pg_test(pgio, prev, req);
943 if (!size) 938 if (!size)
944 return 0; 939 return 0;
945 940
941 /* see if req and prev are in the same stripe */
946 if (prev) { 942 if (prev) {
947 p_stripe = (u64)req_offset(prev); 943 p_stripe = (u64)req_offset(prev) - segment_offset;
948 r_stripe = (u64)req_offset(req); 944 r_stripe = (u64)req_offset(req) - segment_offset;
949 stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit;
950
951 do_div(p_stripe, stripe_unit); 945 do_div(p_stripe, stripe_unit);
952 do_div(r_stripe, stripe_unit); 946 do_div(r_stripe, stripe_unit);
953 947
954 if (p_stripe != r_stripe) 948 if (p_stripe != r_stripe)
955 return 0; 949 return 0;
956 } 950 }
957 return min(size, req->wb_bytes); 951
952 /* calculate remaining bytes in the current stripe */
953 div_u64_rem((u64)req_offset(req) - segment_offset,
954 stripe_unit,
955 &stripe_offset);
956 WARN_ON_ONCE(stripe_offset > stripe_unit);
957 if (stripe_offset >= stripe_unit)
958 return 0;
959 return min(stripe_unit - (unsigned int)stripe_offset, size);
958} 960}
959 961
960static void 962static void
961filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, 963filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
962 struct nfs_page *req) 964 struct nfs_page *req)
963{ 965{
964 WARN_ON_ONCE(pgio->pg_lseg != NULL); 966 if (!pgio->pg_lseg)
965 967 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
966 if (req->wb_offset != req->wb_pgbase) {
967 /*
968 * Handling unaligned pages is difficult, because have to
969 * somehow split a req in two in certain cases in the
970 * pg.test code. Avoid this by just not using pnfs
971 * in this case.
972 */
973 nfs_pageio_reset_read_mds(pgio);
974 return;
975 }
976 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
977 req->wb_context, 968 req->wb_context,
978 0, 969 0,
979 NFS4_MAX_UINT64, 970 NFS4_MAX_UINT64,
@@ -991,11 +982,8 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
991 struct nfs_commit_info cinfo; 982 struct nfs_commit_info cinfo;
992 int status; 983 int status;
993 984
994 WARN_ON_ONCE(pgio->pg_lseg != NULL); 985 if (!pgio->pg_lseg)
995 986 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
996 if (req->wb_offset != req->wb_pgbase)
997 goto out_mds;
998 pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
999 req->wb_context, 987 req->wb_context,
1000 0, 988 0,
1001 NFS4_MAX_UINT64, 989 NFS4_MAX_UINT64,