diff options
author | Fred Isaman <iisaman@netapp.com> | 2011-02-28 20:34:18 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-11 15:38:42 -0500 |
commit | cfe7f4120f8b1b9465c333d1e42efd4669b1799f (patch) | |
tree | a55e5fc7dbafdf43588a480a0348da0ad8e1eb9e /fs/nfs | |
parent | d83217c13531fd59730d77b5c2284e90e56c0a50 (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.c | 34 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayout.h | 7 | ||||
-rw-r--r-- | fs/nfs/nfs4filelayoutdev.c | 67 |
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 | ||
69 | static loff_t | ||
70 | filelayout_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 | */ | ||
87 | static loff_t | ||
88 | filelayout_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 | ||
86 | extern struct nfs_fh * | ||
87 | nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j); | ||
88 | |||
86 | extern void nfs4_fl_free_deviceid_callback(struct pnfs_deviceid_node *); | 89 | extern void nfs4_fl_free_deviceid_callback(struct pnfs_deviceid_node *); |
87 | extern void print_ds(struct nfs4_pnfs_ds *ds); | 90 | extern void print_ds(struct nfs4_pnfs_ds *ds); |
88 | extern void print_deviceid(struct nfs4_deviceid *dev_id); | 91 | extern void print_deviceid(struct nfs4_deviceid *dev_id); |
92 | u32 nfs4_fl_calc_j_index(struct pnfs_layout_segment *lseg, loff_t offset); | ||
93 | u32 nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j); | ||
94 | struct nfs4_pnfs_ds *nfs4_fl_prepare_ds(struct pnfs_layout_segment *lseg, | ||
95 | u32 ds_idx); | ||
89 | extern struct nfs4_file_layout_dsaddr * | 96 | extern struct nfs4_file_layout_dsaddr * |
90 | nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id); | 97 | nfs4_fl_find_get_deviceid(struct nfs_client *, struct nfs4_deviceid *dev_id); |
91 | struct nfs4_file_layout_dsaddr * | 98 | struct 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 | */ | ||
524 | u32 | ||
525 | nfs4_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 | |||
536 | u32 | ||
537 | nfs4_fl_calc_ds_index(struct pnfs_layout_segment *lseg, u32 j) | ||
538 | { | ||
539 | return FILELAYOUT_LSEG(lseg)->dsaddr->stripe_indices[j]; | ||
540 | } | ||
541 | |||
542 | struct nfs_fh * | ||
543 | nfs4_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 | |||
561 | struct nfs4_pnfs_ds * | ||
562 | nfs4_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 | } | ||