diff options
author | Andy Adamson <andros@netapp.com> | 2011-02-28 20:34:19 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-03-11 15:38:43 -0500 |
commit | dc70d7b3189597f313df7bd2da849cfc39063b15 (patch) | |
tree | c739f2c3a2213b1bc028f1599ee0efcbeabd9b81 /fs/nfs/nfs4filelayout.c | |
parent | cfe7f4120f8b1b9465c333d1e42efd4669b1799f (diff) |
NFSv4.1: filelayout read
Attempt a pNFS file layout read by setting up the nfs_read_data struct and
calling nfs_initiate_read with the data server rpc client and the
filelayout rpc call ops.
Error handling is implemented in a subsequent patch.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
Signed-off-by: Fred Isaman <iisaman@citi.umich.edu>
Signed-off-by: Fred Isaman <iisaman@netapp.com>
Signed-off-by: Mingyang Guo <guomingyang@nrchpc.ac.cn>
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Signed-off-by: Ricardo Labiaga <Ricardo.Labiaga@netapp.com>
Tested-by: Guo Mingyang <guomingyang@nrchpc.ac.cn>
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/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index ed833705dcee..3608411653dc 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -101,6 +101,87 @@ filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * Call ops for the async read/write cases | ||
105 | * In the case of dense layouts, the offset needs to be reset to its | ||
106 | * original value. | ||
107 | */ | ||
108 | static void filelayout_read_prepare(struct rpc_task *task, void *data) | ||
109 | { | ||
110 | struct nfs_read_data *rdata = (struct nfs_read_data *)data; | ||
111 | |||
112 | if (nfs41_setup_sequence(rdata->ds_clp->cl_session, | ||
113 | &rdata->args.seq_args, &rdata->res.seq_res, | ||
114 | 0, task)) | ||
115 | return; | ||
116 | |||
117 | rpc_call_start(task); | ||
118 | } | ||
119 | |||
120 | static void filelayout_read_call_done(struct rpc_task *task, void *data) | ||
121 | { | ||
122 | struct nfs_read_data *rdata = (struct nfs_read_data *)data; | ||
123 | |||
124 | dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); | ||
125 | |||
126 | /* Note this may cause RPC to be resent */ | ||
127 | rdata->mds_ops->rpc_call_done(task, data); | ||
128 | } | ||
129 | |||
130 | static void filelayout_read_release(void *data) | ||
131 | { | ||
132 | struct nfs_read_data *rdata = (struct nfs_read_data *)data; | ||
133 | |||
134 | rdata->mds_ops->rpc_release(data); | ||
135 | } | ||
136 | |||
137 | struct rpc_call_ops filelayout_read_call_ops = { | ||
138 | .rpc_call_prepare = filelayout_read_prepare, | ||
139 | .rpc_call_done = filelayout_read_call_done, | ||
140 | .rpc_release = filelayout_read_release, | ||
141 | }; | ||
142 | |||
143 | static enum pnfs_try_status | ||
144 | filelayout_read_pagelist(struct nfs_read_data *data) | ||
145 | { | ||
146 | struct pnfs_layout_segment *lseg = data->lseg; | ||
147 | struct nfs4_pnfs_ds *ds; | ||
148 | loff_t offset = data->args.offset; | ||
149 | u32 j, idx; | ||
150 | struct nfs_fh *fh; | ||
151 | int status; | ||
152 | |||
153 | dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n", | ||
154 | __func__, data->inode->i_ino, | ||
155 | data->args.pgbase, (size_t)data->args.count, offset); | ||
156 | |||
157 | /* Retrieve the correct rpc_client for the byte range */ | ||
158 | j = nfs4_fl_calc_j_index(lseg, offset); | ||
159 | idx = nfs4_fl_calc_ds_index(lseg, j); | ||
160 | ds = nfs4_fl_prepare_ds(lseg, idx); | ||
161 | if (!ds) { | ||
162 | printk(KERN_ERR "%s: prepare_ds failed, use MDS\n", __func__); | ||
163 | return PNFS_NOT_ATTEMPTED; | ||
164 | } | ||
165 | dprintk("%s USE DS:ip %x %hu\n", __func__, | ||
166 | ntohl(ds->ds_ip_addr), ntohs(ds->ds_port)); | ||
167 | |||
168 | /* No multipath support. Use first DS */ | ||
169 | data->ds_clp = ds->ds_clp; | ||
170 | fh = nfs4_fl_select_ds_fh(lseg, j); | ||
171 | if (fh) | ||
172 | data->args.fh = fh; | ||
173 | |||
174 | data->args.offset = filelayout_get_dserver_offset(lseg, offset); | ||
175 | data->mds_offset = offset; | ||
176 | |||
177 | /* Perform an asynchronous read to ds */ | ||
178 | status = nfs_initiate_read(data, ds->ds_clp->cl_rpcclient, | ||
179 | &filelayout_read_call_ops); | ||
180 | BUG_ON(status != 0); | ||
181 | return PNFS_ATTEMPTED; | ||
182 | } | ||
183 | |||
184 | /* | ||
104 | * filelayout_check_layout() | 185 | * filelayout_check_layout() |
105 | * | 186 | * |
106 | * Make sure layout segment parameters are sane WRT the device. | 187 | * Make sure layout segment parameters are sane WRT the device. |
@@ -320,6 +401,7 @@ static struct pnfs_layoutdriver_type filelayout_type = { | |||
320 | .alloc_lseg = filelayout_alloc_lseg, | 401 | .alloc_lseg = filelayout_alloc_lseg, |
321 | .free_lseg = filelayout_free_lseg, | 402 | .free_lseg = filelayout_free_lseg, |
322 | .pg_test = filelayout_pg_test, | 403 | .pg_test = filelayout_pg_test, |
404 | .read_pagelist = filelayout_read_pagelist, | ||
323 | }; | 405 | }; |
324 | 406 | ||
325 | static int __init nfs4filelayout_init(void) | 407 | static int __init nfs4filelayout_init(void) |