aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r--fs/nfs/nfs4filelayout.c101
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 */
81static void
82filelayout_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
93static int filelayout_async_handle_error(struct rpc_task *task, 80static 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 */
662bool 666static bool
663filelayout_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 667filelayout_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
687void
688filelayout_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
704void
705filelayout_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
721static 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
727static 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
685static bool filelayout_mark_pnfs_commit(struct pnfs_layout_segment *lseg) 733static 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
954MODULE_ALIAS("nfs-layouttype4-1");
955
905module_init(nfs4filelayout_init); 956module_init(nfs4filelayout_init);
906module_exit(nfs4filelayout_exit); 957module_exit(nfs4filelayout_exit);