aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2011-02-28 20:34:18 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-03-11 15:38:42 -0500
commitcfe7f4120f8b1b9465c333d1e42efd4669b1799f (patch)
treea55e5fc7dbafdf43588a480a0348da0ad8e1eb9e /fs/nfs
parentd83217c13531fd59730d77b5c2284e90e56c0a50 (diff)
NFSv4.1: filelayout i/o helpers
Prepare for filelayout_read_pagelist with helper functions that find the correct data server, filehandle, and offset. Signed-off-by: Andy Adamson <andros@citi.umich.edu> Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com> Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Marc Eshel <eshel@almaden.ibm.com> Signed-off-by: Mike Sager <sager@netapp.com> Signed-off-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Tao Guo <guotao@nrchpc.ac.cn> Signed-off-by: Tigran Mkrtchyan <tigran@anahit.desy.de> Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de> Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4filelayout.c34
-rw-r--r--fs/nfs/nfs4filelayout.h7
-rw-r--r--fs/nfs/nfs4filelayoutdev.c67
3 files changed, 108 insertions, 0 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 0efe8cbd9e3c..ed833705dcee 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -66,6 +66,40 @@ filelayout_clear_layoutdriver(struct nfs_server *nfss)
66 return 0; 66 return 0;
67} 67}
68 68
69static loff_t
70filelayout_get_dense_offset(struct nfs4_filelayout_segment *flseg,
71 loff_t offset)
72{
73 u32 stripe_width = flseg->stripe_unit * flseg->dsaddr->stripe_count;
74 u64 tmp;
75
76 offset -= flseg->pattern_offset;
77 tmp = offset;
78 do_div(tmp, stripe_width);
79
80 return tmp * flseg->stripe_unit + do_div(offset, flseg->stripe_unit);
81}
82
83/* This function is used by the layout driver to calculate the
84 * offset of the file on the dserver based on whether the
85 * layout type is STRIPE_DENSE or STRIPE_SPARSE
86 */
87static loff_t
88filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset)
89{
90 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
91
92 switch (flseg->stripe_type) {
93 case STRIPE_SPARSE:
94 return offset;
95
96 case STRIPE_DENSE:
97 return filelayout_get_dense_offset(flseg, offset);
98 }
99
100 BUG();
101}
102
69/* 103/*
70 * filelayout_check_layout() 104 * filelayout_check_layout()
71 * 105 *
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index bbf60dd2ab9d..9fef76e04936 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -83,9 +83,16 @@ FILELAYOUT_LSEG(struct pnfs_layout_segment *lseg)
83 generic_hdr); 83 generic_hdr);
84} 84}
85 85
86extern struct nfs_fh *
87nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
88
86extern void nfs4_fl_free_deviceid_callback(struct pnfs_deviceid_node *); 89extern void nfs4_fl_free_deviceid_callback(struct pnfs_deviceid_node *);
87extern void print_ds(struct nfs4_pnfs_ds *ds); 90extern void print_ds(struct nfs4_pnfs_ds *ds);
88extern void print_deviceid(struct nfs4_deviceid *dev_id); 91extern void print_deviceid(struct nfs4_deviceid *dev_id);
92u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset);
93u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j);
94struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg,
95 u32 ds_idx);
89extern struct nfs4_file_layout_dsaddr * 96extern struct nfs4_file_layout_dsaddr *
90nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id); 97nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id);
91struct nfs4_file_layout_dsaddr * 98struct nfs4_file_layout_dsaddr *
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index 8bc91fb8b6fa..f466fed2f466 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -516,3 +516,70 @@ nfs4_fl_find_get_deviceid(struct nfs_client *clp, struct nfs4_deviceid *id)
516 return (d == NULL) ? NULL : 516 return (d == NULL) ? NULL :
517 container_of(d, struct nfs4_file_layout_dsaddr, deviceid); 517 container_of(d, struct nfs4_file_layout_dsaddr, deviceid);
518} 518}
519
520/*
521 * Want res = (offset - layout->pattern_offset)/ layout->stripe_unit
522 * Then: ((res + fsi) % dsaddr->stripe_count)
523 */
524u32
525nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset)
526{
527 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
528 u64 tmp;
529
530 tmp = offset - flseg->pattern_offset;
531 do_div(tmp, flseg->stripe_unit);
532 tmp += flseg->first_stripe_index;
533 return do_div(tmp, flseg->dsaddr->stripe_count);
534}
535
536u32
537nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j)
538{
539 return FILELAYOUT_LSEG(lseg)->dsaddr->stripe_indices[j];
540}
541
542struct nfs_fh *
543nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j)
544{
545 struct nfs4_filelayout_segment *flseg = FILELAYOUT_LSEG(lseg);
546 u32 i;
547
548 if (flseg->stripe_type == STRIPE_SPARSE) {
549 if (flseg->num_fh == 1)
550 i = 0;
551 else if (flseg->num_fh == 0)
552 /* Use the MDS OPEN fh set in nfs_read_rpcsetup */
553 return NULL;
554 else
555 i = nfs4_fl_calc_ds_index(lseg, j);
556 } else
557 i = j;
558 return flseg->fh_array[i];
559}
560
561struct nfs4_pnfs_ds *
562nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx)
563{
564 struct nfs4_file_layout_dsaddr *dsaddr = FILELAYOUT_LSEG(lseg)->dsaddr;
565 struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
566
567 if (ds == NULL) {
568 printk(KERN_ERR "%s: No data server for offset index %d\n",
569 __func__, ds_idx);
570 return NULL;
571 }
572
573 if (!ds->ds_clp) {
574 int err;
575
576 err = nfs4_ds_connect(NFS_SERVER(lseg->pls_layout->plh_inode),
577 dsaddr->ds_list[ds_idx]);
578 if (err) {
579 printk(KERN_ERR "%s nfs4_ds_connect error %d\n",
580 __func__, err);
581 return NULL;
582 }
583 }
584 return ds;
585}