diff options
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 101 |
1 files changed, 76 insertions, 25 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index f9d03abcd04..4c78c62639e 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -77,19 +77,6 @@ filelayout_get_dserver_offset(struct pnfs_layout_segment *lseg, loff_t offset) | |||
77 | BUG(); | 77 | BUG(); |
78 | } | 78 | } |
79 | 79 | ||
80 | /* For data server errors we don't recover from */ | ||
81 | static void | ||
82 | filelayout_set_lo_fail(struct pnfs_layout_segment *lseg) | ||
83 | { | ||
84 | if (lseg->pls_range.iomode == IOMODE_RW) { | ||
85 | dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__); | ||
86 | set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags); | ||
87 | } else { | ||
88 | dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__); | ||
89 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | static int filelayout_async_handle_error(struct rpc_task *task, | 80 | static int filelayout_async_handle_error(struct rpc_task *task, |
94 | struct nfs4_state *state, | 81 | struct nfs4_state *state, |
95 | struct nfs_client *clp, | 82 | struct nfs_client *clp, |
@@ -145,7 +132,7 @@ static int filelayout_read_done_cb(struct rpc_task *task, | |||
145 | dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", | 132 | dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", |
146 | __func__, data->ds_clp, data->ds_clp->cl_session); | 133 | __func__, data->ds_clp, data->ds_clp->cl_session); |
147 | if (reset) { | 134 | if (reset) { |
148 | filelayout_set_lo_fail(data->lseg); | 135 | pnfs_set_lo_fail(data->lseg); |
149 | nfs4_reset_read(task, data); | 136 | nfs4_reset_read(task, data); |
150 | clp = NFS_SERVER(data->inode)->nfs_client; | 137 | clp = NFS_SERVER(data->inode)->nfs_client; |
151 | } | 138 | } |
@@ -170,7 +157,7 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata) | |||
170 | 157 | ||
171 | pnfs_set_layoutcommit(wdata); | 158 | pnfs_set_layoutcommit(wdata); |
172 | dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino, | 159 | dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino, |
173 | (unsigned long) wdata->lseg->pls_end_pos); | 160 | (unsigned long) NFS_I(wdata->inode)->layout->plh_lwb); |
174 | } | 161 | } |
175 | 162 | ||
176 | /* | 163 | /* |
@@ -221,7 +208,7 @@ static int filelayout_write_done_cb(struct rpc_task *task, | |||
221 | dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", | 208 | dprintk("%s calling restart ds_clp %p ds_clp->cl_session %p\n", |
222 | __func__, data->ds_clp, data->ds_clp->cl_session); | 209 | __func__, data->ds_clp, data->ds_clp->cl_session); |
223 | if (reset) { | 210 | if (reset) { |
224 | filelayout_set_lo_fail(data->lseg); | 211 | pnfs_set_lo_fail(data->lseg); |
225 | nfs4_reset_write(task, data); | 212 | nfs4_reset_write(task, data); |
226 | clp = NFS_SERVER(data->inode)->nfs_client; | 213 | clp = NFS_SERVER(data->inode)->nfs_client; |
227 | } else | 214 | } else |
@@ -256,7 +243,7 @@ static int filelayout_commit_done_cb(struct rpc_task *task, | |||
256 | __func__, data->ds_clp, data->ds_clp->cl_session); | 243 | __func__, data->ds_clp, data->ds_clp->cl_session); |
257 | if (reset) { | 244 | if (reset) { |
258 | prepare_to_resend_writes(data); | 245 | prepare_to_resend_writes(data); |
259 | filelayout_set_lo_fail(data->lseg); | 246 | pnfs_set_lo_fail(data->lseg); |
260 | } else | 247 | } else |
261 | nfs_restart_rpc(task, data->ds_clp); | 248 | nfs_restart_rpc(task, data->ds_clp); |
262 | return -EAGAIN; | 249 | return -EAGAIN; |
@@ -334,6 +321,9 @@ filelayout_read_pagelist(struct nfs_read_data *data) | |||
334 | __func__, data->inode->i_ino, | 321 | __func__, data->inode->i_ino, |
335 | data->args.pgbase, (size_t)data->args.count, offset); | 322 | data->args.pgbase, (size_t)data->args.count, offset); |
336 | 323 | ||
324 | if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags)) | ||
325 | return PNFS_NOT_ATTEMPTED; | ||
326 | |||
337 | /* Retrieve the correct rpc_client for the byte range */ | 327 | /* Retrieve the correct rpc_client for the byte range */ |
338 | j = nfs4_fl_calc_j_index(lseg, offset); | 328 | j = nfs4_fl_calc_j_index(lseg, offset); |
339 | idx = nfs4_fl_calc_ds_index(lseg, j); | 329 | idx = nfs4_fl_calc_ds_index(lseg, j); |
@@ -344,8 +334,7 @@ filelayout_read_pagelist(struct nfs_read_data *data) | |||
344 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); | 334 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); |
345 | return PNFS_NOT_ATTEMPTED; | 335 | return PNFS_NOT_ATTEMPTED; |
346 | } | 336 | } |
347 | dprintk("%s USE DS:ip %x %hu\n", __func__, | 337 | dprintk("%s USE DS: %s\n", __func__, ds->ds_remotestr); |
348 | ntohl(ds->ds_ip_addr), ntohs(ds->ds_port)); | ||
349 | 338 | ||
350 | /* No multipath support. Use first DS */ | 339 | /* No multipath support. Use first DS */ |
351 | data->ds_clp = ds->ds_clp; | 340 | data->ds_clp = ds->ds_clp; |
@@ -374,6 +363,9 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync) | |||
374 | struct nfs_fh *fh; | 363 | struct nfs_fh *fh; |
375 | int status; | 364 | int status; |
376 | 365 | ||
366 | if (test_bit(NFS_DEVICEID_INVALID, &FILELAYOUT_DEVID_NODE(lseg)->flags)) | ||
367 | return PNFS_NOT_ATTEMPTED; | ||
368 | |||
377 | /* Retrieve the correct rpc_client for the byte range */ | 369 | /* Retrieve the correct rpc_client for the byte range */ |
378 | j = nfs4_fl_calc_j_index(lseg, offset); | 370 | j = nfs4_fl_calc_j_index(lseg, offset); |
379 | idx = nfs4_fl_calc_ds_index(lseg, j); | 371 | idx = nfs4_fl_calc_ds_index(lseg, j); |
@@ -384,9 +376,9 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync) | |||
384 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); | 376 | set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags); |
385 | return PNFS_NOT_ATTEMPTED; | 377 | return PNFS_NOT_ATTEMPTED; |
386 | } | 378 | } |
387 | dprintk("%s ino %lu sync %d req %Zu@%llu DS:%x:%hu\n", __func__, | 379 | dprintk("%s ino %lu sync %d req %Zu@%llu DS: %s\n", __func__, |
388 | data->inode->i_ino, sync, (size_t) data->args.count, offset, | 380 | data->inode->i_ino, sync, (size_t) data->args.count, offset, |
389 | ntohl(ds->ds_ip_addr), ntohs(ds->ds_port)); | 381 | ds->ds_remotestr); |
390 | 382 | ||
391 | data->write_done_cb = filelayout_write_done_cb; | 383 | data->write_done_cb = filelayout_write_done_cb; |
392 | data->ds_clp = ds->ds_clp; | 384 | data->ds_clp = ds->ds_clp; |
@@ -428,6 +420,14 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
428 | 420 | ||
429 | dprintk("--> %s\n", __func__); | 421 | dprintk("--> %s\n", __func__); |
430 | 422 | ||
423 | /* FIXME: remove this check when layout segment support is added */ | ||
424 | if (lgr->range.offset != 0 || | ||
425 | lgr->range.length != NFS4_MAX_UINT64) { | ||
426 | dprintk("%s Only whole file layouts supported. Use MDS i/o\n", | ||
427 | __func__); | ||
428 | goto out; | ||
429 | } | ||
430 | |||
431 | if (fl->pattern_offset > lgr->range.offset) { | 431 | if (fl->pattern_offset > lgr->range.offset) { |
432 | dprintk("%s pattern_offset %lld too large\n", | 432 | dprintk("%s pattern_offset %lld too large\n", |
433 | __func__, fl->pattern_offset); | 433 | __func__, fl->pattern_offset); |
@@ -449,6 +449,10 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, | |||
449 | goto out; | 449 | goto out; |
450 | } else | 450 | } else |
451 | dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); | 451 | dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node); |
452 | /* Found deviceid is being reaped */ | ||
453 | if (test_bit(NFS_DEVICEID_INVALID, &dsaddr->id_node.flags)) | ||
454 | goto out_put; | ||
455 | |||
452 | fl->dsaddr = dsaddr; | 456 | fl->dsaddr = dsaddr; |
453 | 457 | ||
454 | if (fl->first_stripe_index < 0 || | 458 | if (fl->first_stripe_index < 0 || |
@@ -659,7 +663,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, | |||
659 | * return true : coalesce page | 663 | * return true : coalesce page |
660 | * return false : don't coalesce page | 664 | * return false : don't coalesce page |
661 | */ | 665 | */ |
662 | bool | 666 | static bool |
663 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | 667 | filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, |
664 | struct nfs_page *req) | 668 | struct nfs_page *req) |
665 | { | 669 | { |
@@ -670,8 +674,6 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | |||
670 | !nfs_generic_pg_test(pgio, prev, req)) | 674 | !nfs_generic_pg_test(pgio, prev, req)) |
671 | return false; | 675 | return false; |
672 | 676 | ||
673 | if (!pgio->pg_lseg) | ||
674 | return 1; | ||
675 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; | 677 | p_stripe = (u64)prev->wb_index << PAGE_CACHE_SHIFT; |
676 | r_stripe = (u64)req->wb_index << PAGE_CACHE_SHIFT; | 678 | r_stripe = (u64)req->wb_index << PAGE_CACHE_SHIFT; |
677 | stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit; | 679 | stripe_unit = FILELAYOUT_LSEG(pgio->pg_lseg)->stripe_unit; |
@@ -682,6 +684,52 @@ filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | |||
682 | return (p_stripe == r_stripe); | 684 | return (p_stripe == r_stripe); |
683 | } | 685 | } |
684 | 686 | ||
687 | void | ||
688 | filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio, | ||
689 | struct nfs_page *req) | ||
690 | { | ||
691 | BUG_ON(pgio->pg_lseg != NULL); | ||
692 | |||
693 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | ||
694 | req->wb_context, | ||
695 | 0, | ||
696 | NFS4_MAX_UINT64, | ||
697 | IOMODE_READ, | ||
698 | GFP_KERNEL); | ||
699 | /* If no lseg, fall back to read through mds */ | ||
700 | if (pgio->pg_lseg == NULL) | ||
701 | nfs_pageio_reset_read_mds(pgio); | ||
702 | } | ||
703 | |||
704 | void | ||
705 | filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio, | ||
706 | struct nfs_page *req) | ||
707 | { | ||
708 | BUG_ON(pgio->pg_lseg != NULL); | ||
709 | |||
710 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, | ||
711 | req->wb_context, | ||
712 | 0, | ||
713 | NFS4_MAX_UINT64, | ||
714 | IOMODE_RW, | ||
715 | GFP_NOFS); | ||
716 | /* If no lseg, fall back to write through mds */ | ||
717 | if (pgio->pg_lseg == NULL) | ||
718 | nfs_pageio_reset_write_mds(pgio); | ||
719 | } | ||
720 | |||
721 | static const struct nfs_pageio_ops filelayout_pg_read_ops = { | ||
722 | .pg_init = filelayout_pg_init_read, | ||
723 | .pg_test = filelayout_pg_test, | ||
724 | .pg_doio = pnfs_generic_pg_readpages, | ||
725 | }; | ||
726 | |||
727 | static const struct nfs_pageio_ops filelayout_pg_write_ops = { | ||
728 | .pg_init = filelayout_pg_init_write, | ||
729 | .pg_test = filelayout_pg_test, | ||
730 | .pg_doio = pnfs_generic_pg_writepages, | ||
731 | }; | ||
732 | |||
685 | static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg) | 733 | static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg) |
686 | { | 734 | { |
687 | return !FILELAYOUT_LSEG(lseg)->commit_through_mds; | 735 | return !FILELAYOUT_LSEG(lseg)->commit_through_mds; |
@@ -879,7 +927,8 @@ static struct pnfs_layoutdriver_type filelayout_type = { | |||
879 | .owner = THIS_MODULE, | 927 | .owner = THIS_MODULE, |
880 | .alloc_lseg = filelayout_alloc_lseg, | 928 | .alloc_lseg = filelayout_alloc_lseg, |
881 | .free_lseg = filelayout_free_lseg, | 929 | .free_lseg = filelayout_free_lseg, |
882 | .pg_test = filelayout_pg_test, | 930 | .pg_read_ops = &filelayout_pg_read_ops, |
931 | .pg_write_ops = &filelayout_pg_write_ops, | ||
883 | .mark_pnfs_commit = filelayout_mark_pnfs_commit, | 932 | .mark_pnfs_commit = filelayout_mark_pnfs_commit, |
884 | .choose_commit_list = filelayout_choose_commit_list, | 933 | .choose_commit_list = filelayout_choose_commit_list, |
885 | .commit_pagelist = filelayout_commit_pagelist, | 934 | .commit_pagelist = filelayout_commit_pagelist, |
@@ -902,5 +951,7 @@ static void __exit nfs4filelayout_exit(void) | |||
902 | pnfs_unregister_layoutdriver(&filelayout_type); | 951 | pnfs_unregister_layoutdriver(&filelayout_type); |
903 | } | 952 | } |
904 | 953 | ||
954 | MODULE_ALIAS("nfs-layouttype4-1"); | ||
955 | |||
905 | module_init(nfs4filelayout_init); | 956 | module_init(nfs4filelayout_init); |
906 | module_exit(nfs4filelayout_exit); | 957 | module_exit(nfs4filelayout_exit); |