aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorFred Isaman <iisaman@netapp.com>2012-04-20 14:47:44 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-04-27 14:10:37 -0400
commitcd841605f7a721878d8a2d1362484723d8abf569 (patch)
treeb5c37db575cd545a183577249909e042fe38d646 /fs/nfs/nfs4filelayout.c
parentb5542849764aa56fd3f05c0041195b637b9d2ac2 (diff)
NFS: create common nfs_pgio_header for both read and write
In order to avoid duplicating all the data in nfs_read_data whenever we split it up into multiple RPC calls (either due to a short read result or due to rsize < PAGE_SIZE), we split out the bits that are the same per RPC call into a separate "header" structure. The goal this patch moves towards is to have a single header refcounted by several rpc_data structures. Thus, want to always refer from rpc_data to the header, and not the other way. This patch comes close to that ideal, but the directio code currently needs some special casing, isolated in the nfs_direct_[read_write]hdr_release() functions. This will be dealt with in a future patch. Signed-off-by: Fred Isaman <iisaman@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index c536328557cb..ad1d68013a5b 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -148,6 +148,7 @@ wait_on_recovery:
148static int filelayout_read_done_cb(struct rpc_task *task, 148static int filelayout_read_done_cb(struct rpc_task *task,
149 struct nfs_read_data *data) 149 struct nfs_read_data *data)
150{ 150{
151 struct nfs_pgio_header *hdr = data->header;
151 int reset = 0; 152 int reset = 0;
152 153
153 dprintk("%s DS read\n", __func__); 154 dprintk("%s DS read\n", __func__);
@@ -157,7 +158,7 @@ static int filelayout_read_done_cb(struct rpc_task *task,
157 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 158 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
158 __func__, data->ds_clp, data->ds_clp->cl_session); 159 __func__, data->ds_clp, data->ds_clp->cl_session);
159 if (reset) { 160 if (reset) {
160 pnfs_set_lo_fail(data->lseg); 161 pnfs_set_lo_fail(hdr->lseg);
161 nfs4_reset_read(task, data); 162 nfs4_reset_read(task, data);
162 } 163 }
163 rpc_restart_call_prepare(task); 164 rpc_restart_call_prepare(task);
@@ -175,13 +176,15 @@ static int filelayout_read_done_cb(struct rpc_task *task,
175static void 176static void
176filelayout_set_layoutcommit(struct nfs_write_data *wdata) 177filelayout_set_layoutcommit(struct nfs_write_data *wdata)
177{ 178{
178 if (FILELAYOUT_LSEG(wdata->lseg)->commit_through_mds || 179 struct nfs_pgio_header *hdr = wdata->header;
180
181 if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
179 wdata->res.verf->committed == NFS_FILE_SYNC) 182 wdata->res.verf->committed == NFS_FILE_SYNC)
180 return; 183 return;
181 184
182 pnfs_set_layoutcommit(wdata); 185 pnfs_set_layoutcommit(wdata);
183 dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino, 186 dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
184 (unsigned long) NFS_I(wdata->inode)->layout->plh_lwb); 187 (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
185} 188}
186 189
187/* 190/*
@@ -210,27 +213,28 @@ static void filelayout_read_call_done(struct rpc_task *task, void *data)
210 dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); 213 dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status);
211 214
212 /* Note this may cause RPC to be resent */ 215 /* Note this may cause RPC to be resent */
213 rdata->mds_ops->rpc_call_done(task, data); 216 rdata->header->mds_ops->rpc_call_done(task, data);
214} 217}
215 218
216static void filelayout_read_count_stats(struct rpc_task *task, void *data) 219static void filelayout_read_count_stats(struct rpc_task *task, void *data)
217{ 220{
218 struct nfs_read_data *rdata = data; 221 struct nfs_read_data *rdata = data;
219 222
220 rpc_count_iostats(task, NFS_SERVER(rdata->inode)->client->cl_metrics); 223 rpc_count_iostats(task, NFS_SERVER(rdata->header->inode)->client->cl_metrics);
221} 224}
222 225
223static void filelayout_read_release(void *data) 226static void filelayout_read_release(void *data)
224{ 227{
225 struct nfs_read_data *rdata = data; 228 struct nfs_read_data *rdata = data;
226 229
227 put_lseg(rdata->lseg); 230 put_lseg(rdata->header->lseg);
228 rdata->mds_ops->rpc_release(data); 231 rdata->header->mds_ops->rpc_release(data);
229} 232}
230 233
231static int filelayout_write_done_cb(struct rpc_task *task, 234static int filelayout_write_done_cb(struct rpc_task *task,
232 struct nfs_write_data *data) 235 struct nfs_write_data *data)
233{ 236{
237 struct nfs_pgio_header *hdr = data->header;
234 int reset = 0; 238 int reset = 0;
235 239
236 if (filelayout_async_handle_error(task, data->args.context->state, 240 if (filelayout_async_handle_error(task, data->args.context->state,
@@ -238,7 +242,7 @@ static int filelayout_write_done_cb(struct rpc_task *task,
238 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", 242 dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n",
239 __func__, data->ds_clp, data->ds_clp->cl_session); 243 __func__, data->ds_clp, data->ds_clp->cl_session);
240 if (reset) { 244 if (reset) {
241 pnfs_set_lo_fail(data->lseg); 245 pnfs_set_lo_fail(hdr->lseg);
242 nfs4_reset_write(task, data); 246 nfs4_reset_write(task, data);
243 } 247 }
244 rpc_restart_call_prepare(task); 248 rpc_restart_call_prepare(task);
@@ -297,22 +301,22 @@ static void filelayout_write_call_done(struct rpc_task *task, void *data)
297 struct nfs_write_data *wdata = data; 301 struct nfs_write_data *wdata = data;
298 302
299 /* Note this may cause RPC to be resent */ 303 /* Note this may cause RPC to be resent */
300 wdata->mds_ops->rpc_call_done(task, data); 304 wdata->header->mds_ops->rpc_call_done(task, data);
301} 305}
302 306
303static void filelayout_write_count_stats(struct rpc_task *task, void *data) 307static void filelayout_write_count_stats(struct rpc_task *task, void *data)
304{ 308{
305 struct nfs_write_data *wdata = data; 309 struct nfs_write_data *wdata = data;
306 310
307 rpc_count_iostats(task, NFS_SERVER(wdata->inode)->client->cl_metrics); 311 rpc_count_iostats(task, NFS_SERVER(wdata->header->inode)->client->cl_metrics);
308} 312}
309 313
310static void filelayout_write_release(void *data) 314static void filelayout_write_release(void *data)
311{ 315{
312 struct nfs_write_data *wdata = data; 316 struct nfs_write_data *wdata = data;
313 317
314 put_lseg(wdata->lseg); 318 put_lseg(wdata->header->lseg);
315 wdata->mds_ops->rpc_release(data); 319 wdata->header->mds_ops->rpc_release(data);
316} 320}
317 321
318static void filelayout_commit_prepare(struct rpc_task *task, void *data) 322static void filelayout_commit_prepare(struct rpc_task *task, void *data)
@@ -377,7 +381,8 @@ static const struct rpc_call_ops filelayout_commit_call_ops = {
377static enum pnfs_try_status 381static enum pnfs_try_status
378filelayout_read_pagelist(struct nfs_read_data *data) 382filelayout_read_pagelist(struct nfs_read_data *data)
379{ 383{
380 struct pnfs_layout_segment *lseg = data->lseg; 384 struct nfs_pgio_header *hdr = data->header;
385 struct pnfs_layout_segment *lseg = hdr->lseg;
381 struct nfs4_pnfs_ds *ds; 386 struct nfs4_pnfs_ds *ds;
382 loff_t offset = data->args.offset; 387 loff_t offset = data->args.offset;
383 u32 j, idx; 388 u32 j, idx;
@@ -385,7 +390,7 @@ filelayout_read_pagelist(struct nfs_read_data *data)
385 int status; 390 int status;
386 391
387 dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n", 392 dprintk("--> %s ino %lu pgbase %u req %Zu@%llu\n",
388 __func__, data->inode->i_ino, 393 __func__, hdr->inode->i_ino,
389 data->args.pgbase, (size_t)data->args.count, offset); 394 data->args.pgbase, (size_t)data->args.count, offset);
390 395
391 if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags)) 396 if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags))
@@ -423,7 +428,8 @@ filelayout_read_pagelist(struct nfs_read_data *data)
423static enum pnfs_try_status 428static enum pnfs_try_status
424filelayout_write_pagelist(struct nfs_write_data *data, int sync) 429filelayout_write_pagelist(struct nfs_write_data *data, int sync)
425{ 430{
426 struct pnfs_layout_segment *lseg = data->lseg; 431 struct nfs_pgio_header *hdr = data->header;
432 struct pnfs_layout_segment *lseg = hdr->lseg;
427 struct nfs4_pnfs_ds *ds; 433 struct nfs4_pnfs_ds *ds;
428 loff_t offset = data->args.offset; 434 loff_t offset = data->args.offset;
429 u32 j, idx; 435 u32 j, idx;
@@ -445,7 +451,7 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync)
445 return PNFS_NOT_ATTEMPTED; 451 return PNFS_NOT_ATTEMPTED;
446 } 452 }
447 dprintk("%s ino %lu sync %d req %Zu@%llu DS: %s\n", __func__, 453 dprintk("%s ino %lu sync %d req %Zu@%llu DS: %s\n", __func__,
448 data->inode->i_ino, sync, (size_t) data->args.count, offset, 454 hdr->inode->i_ino, sync, (size_t) data->args.count, offset,
449 ds->ds_remotestr); 455 ds->ds_remotestr);
450 456
451 data->write_done_cb = filelayout_write_done_cb; 457 data->write_done_cb = filelayout_write_done_cb;