diff options
author | Fred Isaman <iisaman@netapp.com> | 2012-04-20 14:47:44 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-04-27 14:10:37 -0400 |
commit | cd841605f7a721878d8a2d1362484723d8abf569 (patch) | |
tree | b5c37db575cd545a183577249909e042fe38d646 /fs/nfs/nfs4filelayout.c | |
parent | b5542849764aa56fd3f05c0041195b637b9d2ac2 (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.c | 40 |
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: | |||
148 | static int filelayout_read_done_cb(struct rpc_task *task, | 148 | static 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, | |||
175 | static void | 176 | static void |
176 | filelayout_set_layoutcommit(struct nfs_write_data *wdata) | 177 | filelayout_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 | ||
216 | static void filelayout_read_count_stats(struct rpc_task *task, void *data) | 219 | static 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 | ||
223 | static void filelayout_read_release(void *data) | 226 | static 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 | ||
231 | static int filelayout_write_done_cb(struct rpc_task *task, | 234 | static 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 | ||
303 | static void filelayout_write_count_stats(struct rpc_task *task, void *data) | 307 | static 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 | ||
310 | static void filelayout_write_release(void *data) | 314 | static 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 | ||
318 | static void filelayout_commit_prepare(struct rpc_task *task, void *data) | 322 | static void filelayout_commit_prepare(struct rpc_task *task, void *data) |
@@ -377,7 +381,8 @@ static const struct rpc_call_ops filelayout_commit_call_ops = { | |||
377 | static enum pnfs_try_status | 381 | static enum pnfs_try_status |
378 | filelayout_read_pagelist(struct nfs_read_data *data) | 382 | filelayout_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) | |||
423 | static enum pnfs_try_status | 428 | static enum pnfs_try_status |
424 | filelayout_write_pagelist(struct nfs_write_data *data, int sync) | 429 | filelayout_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; |