.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Module for pnfs flexfile layout driver. |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | */ |
---|
8 | 9 | |
---|
9 | 10 | #include <linux/nfs_fs.h> |
---|
| 11 | +#include <linux/nfs_mount.h> |
---|
10 | 12 | #include <linux/nfs_page.h> |
---|
11 | 13 | #include <linux/module.h> |
---|
| 14 | +#include <linux/sched/mm.h> |
---|
12 | 15 | |
---|
13 | 16 | #include <linux/sunrpc/metrics.h> |
---|
14 | 17 | |
---|
.. | .. |
---|
27 | 30 | #define FF_LAYOUT_POLL_RETRY_MAX (15*HZ) |
---|
28 | 31 | #define FF_LAYOUTRETURN_MAXERR 20 |
---|
29 | 32 | |
---|
| 33 | +static unsigned short io_maxretrans; |
---|
30 | 34 | |
---|
31 | | -static struct group_info *ff_zero_group; |
---|
32 | | - |
---|
| 35 | +static const struct pnfs_commit_ops ff_layout_commit_ops; |
---|
33 | 36 | static void ff_layout_read_record_layoutstats_done(struct rpc_task *task, |
---|
34 | 37 | struct nfs_pgio_header *hdr); |
---|
35 | 38 | static int ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo, |
---|
.. | .. |
---|
46 | 49 | |
---|
47 | 50 | ffl = kzalloc(sizeof(*ffl), gfp_flags); |
---|
48 | 51 | if (ffl) { |
---|
| 52 | + pnfs_init_ds_commit_info(&ffl->commit_info); |
---|
49 | 53 | INIT_LIST_HEAD(&ffl->error_list); |
---|
50 | 54 | INIT_LIST_HEAD(&ffl->mirrors); |
---|
51 | 55 | ffl->last_report_time = ktime_get(); |
---|
| 56 | + ffl->commit_info.ops = &ff_layout_commit_ops; |
---|
52 | 57 | return &ffl->generic_hdr; |
---|
53 | 58 | } else |
---|
54 | 59 | return NULL; |
---|
.. | .. |
---|
57 | 62 | static void |
---|
58 | 63 | ff_layout_free_layout_hdr(struct pnfs_layout_hdr *lo) |
---|
59 | 64 | { |
---|
| 65 | + struct nfs4_flexfile_layout *ffl = FF_LAYOUT_FROM_HDR(lo); |
---|
60 | 66 | struct nfs4_ff_layout_ds_err *err, *n; |
---|
61 | 67 | |
---|
62 | | - list_for_each_entry_safe(err, n, &FF_LAYOUT_FROM_HDR(lo)->error_list, |
---|
63 | | - list) { |
---|
| 68 | + list_for_each_entry_safe(err, n, &ffl->error_list, list) { |
---|
64 | 69 | list_del(&err->list); |
---|
65 | 70 | kfree(err); |
---|
66 | 71 | } |
---|
67 | | - kfree(FF_LAYOUT_FROM_HDR(lo)); |
---|
| 72 | + kfree_rcu(ffl, generic_hdr.plh_rcu); |
---|
68 | 73 | } |
---|
69 | 74 | |
---|
70 | 75 | static int decode_pnfs_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) |
---|
.. | .. |
---|
226 | 231 | |
---|
227 | 232 | static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror) |
---|
228 | 233 | { |
---|
229 | | - struct rpc_cred *cred; |
---|
| 234 | + const struct cred *cred; |
---|
230 | 235 | |
---|
231 | 236 | ff_layout_remove_mirror(mirror); |
---|
232 | 237 | kfree(mirror->fh_versions); |
---|
233 | 238 | cred = rcu_access_pointer(mirror->ro_cred); |
---|
234 | | - if (cred) |
---|
235 | | - put_rpccred(cred); |
---|
| 239 | + put_cred(cred); |
---|
236 | 240 | cred = rcu_access_pointer(mirror->rw_cred); |
---|
237 | | - if (cred) |
---|
238 | | - put_rpccred(cred); |
---|
| 241 | + put_cred(cred); |
---|
239 | 242 | nfs4_ff_layout_put_deviceid(mirror->mirror_ds); |
---|
240 | 243 | kfree(mirror); |
---|
241 | 244 | } |
---|
.. | .. |
---|
248 | 251 | |
---|
249 | 252 | static void ff_layout_free_mirror_array(struct nfs4_ff_layout_segment *fls) |
---|
250 | 253 | { |
---|
251 | | - int i; |
---|
| 254 | + u32 i; |
---|
252 | 255 | |
---|
253 | | - if (fls->mirror_array) { |
---|
254 | | - for (i = 0; i < fls->mirror_array_cnt; i++) { |
---|
255 | | - /* normally mirror_ds is freed in |
---|
256 | | - * .free_deviceid_node but we still do it here |
---|
257 | | - * for .alloc_lseg error path */ |
---|
258 | | - ff_layout_put_mirror(fls->mirror_array[i]); |
---|
259 | | - } |
---|
260 | | - kfree(fls->mirror_array); |
---|
261 | | - fls->mirror_array = NULL; |
---|
262 | | - } |
---|
263 | | -} |
---|
264 | | - |
---|
265 | | -static int ff_layout_check_layout(struct nfs4_layoutget_res *lgr) |
---|
266 | | -{ |
---|
267 | | - int ret = 0; |
---|
268 | | - |
---|
269 | | - dprintk("--> %s\n", __func__); |
---|
270 | | - |
---|
271 | | - /* FIXME: remove this check when layout segment support is added */ |
---|
272 | | - if (lgr->range.offset != 0 || |
---|
273 | | - lgr->range.length != NFS4_MAX_UINT64) { |
---|
274 | | - dprintk("%s Only whole file layouts supported. Use MDS i/o\n", |
---|
275 | | - __func__); |
---|
276 | | - ret = -EINVAL; |
---|
277 | | - } |
---|
278 | | - |
---|
279 | | - dprintk("--> %s returns %d\n", __func__, ret); |
---|
280 | | - return ret; |
---|
| 256 | + for (i = 0; i < fls->mirror_array_cnt; i++) |
---|
| 257 | + ff_layout_put_mirror(fls->mirror_array[i]); |
---|
281 | 258 | } |
---|
282 | 259 | |
---|
283 | 260 | static void _ff_layout_free_lseg(struct nfs4_ff_layout_segment *fls) |
---|
.. | .. |
---|
286 | 263 | ff_layout_free_mirror_array(fls); |
---|
287 | 264 | kfree(fls); |
---|
288 | 265 | } |
---|
| 266 | +} |
---|
| 267 | + |
---|
| 268 | +static bool |
---|
| 269 | +ff_lseg_match_mirrors(struct pnfs_layout_segment *l1, |
---|
| 270 | + struct pnfs_layout_segment *l2) |
---|
| 271 | +{ |
---|
| 272 | + const struct nfs4_ff_layout_segment *fl1 = FF_LAYOUT_LSEG(l1); |
---|
| 273 | + const struct nfs4_ff_layout_segment *fl2 = FF_LAYOUT_LSEG(l1); |
---|
| 274 | + u32 i; |
---|
| 275 | + |
---|
| 276 | + if (fl1->mirror_array_cnt != fl2->mirror_array_cnt) |
---|
| 277 | + return false; |
---|
| 278 | + for (i = 0; i < fl1->mirror_array_cnt; i++) { |
---|
| 279 | + if (fl1->mirror_array[i] != fl2->mirror_array[i]) |
---|
| 280 | + return false; |
---|
| 281 | + } |
---|
| 282 | + return true; |
---|
289 | 283 | } |
---|
290 | 284 | |
---|
291 | 285 | static bool |
---|
.. | .. |
---|
322 | 316 | new_end = pnfs_calc_offset_end(new->pls_range.offset, |
---|
323 | 317 | new->pls_range.length); |
---|
324 | 318 | if (new_end < old->pls_range.offset) |
---|
| 319 | + return false; |
---|
| 320 | + if (!ff_lseg_match_mirrors(new, old)) |
---|
325 | 321 | return false; |
---|
326 | 322 | |
---|
327 | 323 | /* Mergeable: copy info from 'old' to 'new' */ |
---|
.. | .. |
---|
400 | 396 | goto out_err_free; |
---|
401 | 397 | |
---|
402 | 398 | rc = -ENOMEM; |
---|
403 | | - fls = kzalloc(sizeof(*fls), gfp_flags); |
---|
| 399 | + fls = kzalloc(struct_size(fls, mirror_array, mirror_array_cnt), |
---|
| 400 | + gfp_flags); |
---|
404 | 401 | if (!fls) |
---|
405 | 402 | goto out_err_free; |
---|
406 | 403 | |
---|
407 | 404 | fls->mirror_array_cnt = mirror_array_cnt; |
---|
408 | 405 | fls->stripe_unit = stripe_unit; |
---|
409 | | - fls->mirror_array = kcalloc(fls->mirror_array_cnt, |
---|
410 | | - sizeof(fls->mirror_array[0]), gfp_flags); |
---|
411 | | - if (fls->mirror_array == NULL) |
---|
412 | | - goto out_err_free; |
---|
413 | 406 | |
---|
414 | 407 | for (i = 0; i < fls->mirror_array_cnt; i++) { |
---|
415 | 408 | struct nfs4_ff_layout_mirror *mirror; |
---|
416 | | - struct auth_cred acred = { .group_info = ff_zero_group }; |
---|
417 | | - struct rpc_cred __rcu *cred; |
---|
| 409 | + struct cred *kcred; |
---|
| 410 | + const struct cred __rcu *cred; |
---|
| 411 | + kuid_t uid; |
---|
| 412 | + kgid_t gid; |
---|
418 | 413 | u32 ds_count, fh_count, id; |
---|
419 | 414 | int j; |
---|
420 | 415 | |
---|
.. | .. |
---|
482 | 477 | if (rc) |
---|
483 | 478 | goto out_err_free; |
---|
484 | 479 | |
---|
485 | | - acred.uid = make_kuid(&init_user_ns, id); |
---|
| 480 | + uid = make_kuid(&init_user_ns, id); |
---|
486 | 481 | |
---|
487 | 482 | /* group */ |
---|
488 | 483 | rc = decode_name(&stream, &id); |
---|
489 | 484 | if (rc) |
---|
490 | 485 | goto out_err_free; |
---|
491 | 486 | |
---|
492 | | - acred.gid = make_kgid(&init_user_ns, id); |
---|
| 487 | + gid = make_kgid(&init_user_ns, id); |
---|
493 | 488 | |
---|
494 | | - /* find the cred for it */ |
---|
495 | | - rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags)); |
---|
496 | | - if (IS_ERR(cred)) { |
---|
497 | | - rc = PTR_ERR(cred); |
---|
498 | | - goto out_err_free; |
---|
| 489 | + if (gfp_flags & __GFP_FS) |
---|
| 490 | + kcred = prepare_kernel_cred(NULL); |
---|
| 491 | + else { |
---|
| 492 | + unsigned int nofs_flags = memalloc_nofs_save(); |
---|
| 493 | + kcred = prepare_kernel_cred(NULL); |
---|
| 494 | + memalloc_nofs_restore(nofs_flags); |
---|
499 | 495 | } |
---|
| 496 | + rc = -ENOMEM; |
---|
| 497 | + if (!kcred) |
---|
| 498 | + goto out_err_free; |
---|
| 499 | + kcred->fsuid = uid; |
---|
| 500 | + kcred->fsgid = gid; |
---|
| 501 | + cred = RCU_INITIALIZER(kcred); |
---|
500 | 502 | |
---|
501 | 503 | if (lgr->range.iomode == IOMODE_READ) |
---|
502 | 504 | rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred); |
---|
.. | .. |
---|
519 | 521 | |
---|
520 | 522 | dprintk("%s: iomode %s uid %u gid %u\n", __func__, |
---|
521 | 523 | lgr->range.iomode == IOMODE_READ ? "READ" : "RW", |
---|
522 | | - from_kuid(&init_user_ns, acred.uid), |
---|
523 | | - from_kgid(&init_user_ns, acred.gid)); |
---|
| 524 | + from_kuid(&init_user_ns, uid), |
---|
| 525 | + from_kgid(&init_user_ns, gid)); |
---|
524 | 526 | } |
---|
525 | 527 | |
---|
526 | 528 | p = xdr_inline_decode(&stream, 4); |
---|
.. | .. |
---|
536 | 538 | |
---|
537 | 539 | out_sort_mirrors: |
---|
538 | 540 | ff_layout_sort_mirrors(fls); |
---|
539 | | - rc = ff_layout_check_layout(lgr); |
---|
540 | | - if (rc) |
---|
541 | | - goto out_err_free; |
---|
542 | 541 | ret = &fls->generic_hdr; |
---|
543 | 542 | dprintk("<-- %s (success)\n", __func__); |
---|
544 | 543 | out_free_page: |
---|
.. | .. |
---|
549 | 548 | ret = ERR_PTR(rc); |
---|
550 | 549 | dprintk("<-- %s (%d)\n", __func__, rc); |
---|
551 | 550 | goto out_free_page; |
---|
552 | | -} |
---|
553 | | - |
---|
554 | | -static bool ff_layout_has_rw_segments(struct pnfs_layout_hdr *layout) |
---|
555 | | -{ |
---|
556 | | - struct pnfs_layout_segment *lseg; |
---|
557 | | - |
---|
558 | | - list_for_each_entry(lseg, &layout->plh_segs, pls_list) |
---|
559 | | - if (lseg->pls_range.iomode == IOMODE_RW) |
---|
560 | | - return true; |
---|
561 | | - |
---|
562 | | - return false; |
---|
563 | 551 | } |
---|
564 | 552 | |
---|
565 | 553 | static void |
---|
.. | .. |
---|
576 | 564 | ffl = FF_LAYOUT_FROM_HDR(lseg->pls_layout); |
---|
577 | 565 | inode = ffl->generic_hdr.plh_inode; |
---|
578 | 566 | spin_lock(&inode->i_lock); |
---|
579 | | - if (!ff_layout_has_rw_segments(lseg->pls_layout)) { |
---|
580 | | - ffl->commit_info.nbuckets = 0; |
---|
581 | | - kfree(ffl->commit_info.buckets); |
---|
582 | | - ffl->commit_info.buckets = NULL; |
---|
583 | | - } |
---|
| 567 | + pnfs_generic_ds_cinfo_release_lseg(&ffl->commit_info, lseg); |
---|
584 | 568 | spin_unlock(&inode->i_lock); |
---|
585 | 569 | } |
---|
586 | 570 | _ff_layout_free_lseg(fls); |
---|
587 | | -} |
---|
588 | | - |
---|
589 | | -/* Return 1 until we have multiple lsegs support */ |
---|
590 | | -static int |
---|
591 | | -ff_layout_get_lseg_count(struct nfs4_ff_layout_segment *fls) |
---|
592 | | -{ |
---|
593 | | - return 1; |
---|
594 | 571 | } |
---|
595 | 572 | |
---|
596 | 573 | static void |
---|
.. | .. |
---|
737 | 714 | spin_unlock(&mirror->lock); |
---|
738 | 715 | } |
---|
739 | 716 | |
---|
740 | | -static int |
---|
741 | | -ff_layout_alloc_commit_info(struct pnfs_layout_segment *lseg, |
---|
742 | | - struct nfs_commit_info *cinfo, |
---|
743 | | - gfp_t gfp_flags) |
---|
| 717 | +static void |
---|
| 718 | +ff_layout_mark_ds_unreachable(struct pnfs_layout_segment *lseg, u32 idx) |
---|
| 719 | +{ |
---|
| 720 | + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); |
---|
| 721 | + |
---|
| 722 | + if (devid) |
---|
| 723 | + nfs4_mark_deviceid_unavailable(devid); |
---|
| 724 | +} |
---|
| 725 | + |
---|
| 726 | +static void |
---|
| 727 | +ff_layout_mark_ds_reachable(struct pnfs_layout_segment *lseg, u32 idx) |
---|
| 728 | +{ |
---|
| 729 | + struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); |
---|
| 730 | + |
---|
| 731 | + if (devid) |
---|
| 732 | + nfs4_mark_deviceid_available(devid); |
---|
| 733 | +} |
---|
| 734 | + |
---|
| 735 | +static struct nfs4_pnfs_ds * |
---|
| 736 | +ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg, |
---|
| 737 | + u32 start_idx, u32 *best_idx, |
---|
| 738 | + bool check_device) |
---|
744 | 739 | { |
---|
745 | 740 | struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg); |
---|
746 | | - struct pnfs_commit_bucket *buckets; |
---|
747 | | - int size; |
---|
| 741 | + struct nfs4_ff_layout_mirror *mirror; |
---|
| 742 | + struct nfs4_pnfs_ds *ds; |
---|
| 743 | + bool fail_return = false; |
---|
| 744 | + u32 idx; |
---|
748 | 745 | |
---|
749 | | - if (cinfo->ds->nbuckets != 0) { |
---|
750 | | - /* This assumes there is only one RW lseg per file. |
---|
751 | | - * To support multiple lseg per file, we need to |
---|
752 | | - * change struct pnfs_commit_bucket to allow dynamic |
---|
753 | | - * increasing nbuckets. |
---|
754 | | - */ |
---|
755 | | - return 0; |
---|
| 746 | + /* mirrors are initially sorted by efficiency */ |
---|
| 747 | + for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { |
---|
| 748 | + if (idx+1 == fls->mirror_array_cnt) |
---|
| 749 | + fail_return = !check_device; |
---|
| 750 | + |
---|
| 751 | + mirror = FF_LAYOUT_COMP(lseg, idx); |
---|
| 752 | + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, fail_return); |
---|
| 753 | + if (!ds) |
---|
| 754 | + continue; |
---|
| 755 | + |
---|
| 756 | + if (check_device && |
---|
| 757 | + nfs4_test_deviceid_unavailable(&mirror->mirror_ds->id_node)) |
---|
| 758 | + continue; |
---|
| 759 | + |
---|
| 760 | + *best_idx = idx; |
---|
| 761 | + return ds; |
---|
756 | 762 | } |
---|
757 | 763 | |
---|
758 | | - size = ff_layout_get_lseg_count(fls) * FF_LAYOUT_MIRROR_COUNT(lseg); |
---|
| 764 | + return NULL; |
---|
| 765 | +} |
---|
759 | 766 | |
---|
760 | | - buckets = kcalloc(size, sizeof(struct pnfs_commit_bucket), |
---|
761 | | - gfp_flags); |
---|
762 | | - if (!buckets) |
---|
763 | | - return -ENOMEM; |
---|
764 | | - else { |
---|
765 | | - int i; |
---|
| 767 | +static struct nfs4_pnfs_ds * |
---|
| 768 | +ff_layout_choose_any_ds_for_read(struct pnfs_layout_segment *lseg, |
---|
| 769 | + u32 start_idx, u32 *best_idx) |
---|
| 770 | +{ |
---|
| 771 | + return ff_layout_choose_ds_for_read(lseg, start_idx, best_idx, false); |
---|
| 772 | +} |
---|
766 | 773 | |
---|
767 | | - spin_lock(&cinfo->inode->i_lock); |
---|
768 | | - if (cinfo->ds->nbuckets != 0) |
---|
769 | | - kfree(buckets); |
---|
770 | | - else { |
---|
771 | | - cinfo->ds->buckets = buckets; |
---|
772 | | - cinfo->ds->nbuckets = size; |
---|
773 | | - for (i = 0; i < size; i++) { |
---|
774 | | - INIT_LIST_HEAD(&buckets[i].written); |
---|
775 | | - INIT_LIST_HEAD(&buckets[i].committing); |
---|
776 | | - /* mark direct verifier as unset */ |
---|
777 | | - buckets[i].direct_verf.committed = |
---|
778 | | - NFS_INVALID_STABLE_HOW; |
---|
779 | | - } |
---|
780 | | - } |
---|
781 | | - spin_unlock(&cinfo->inode->i_lock); |
---|
782 | | - return 0; |
---|
783 | | - } |
---|
| 774 | +static struct nfs4_pnfs_ds * |
---|
| 775 | +ff_layout_choose_valid_ds_for_read(struct pnfs_layout_segment *lseg, |
---|
| 776 | + u32 start_idx, u32 *best_idx) |
---|
| 777 | +{ |
---|
| 778 | + return ff_layout_choose_ds_for_read(lseg, start_idx, best_idx, true); |
---|
784 | 779 | } |
---|
785 | 780 | |
---|
786 | 781 | static struct nfs4_pnfs_ds * |
---|
787 | 782 | ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg, |
---|
788 | | - int start_idx, |
---|
789 | | - int *best_idx) |
---|
| 783 | + u32 start_idx, u32 *best_idx) |
---|
790 | 784 | { |
---|
791 | | - struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg); |
---|
792 | 785 | struct nfs4_pnfs_ds *ds; |
---|
793 | | - bool fail_return = false; |
---|
794 | | - int idx; |
---|
795 | 786 | |
---|
796 | | - /* mirrors are sorted by efficiency */ |
---|
797 | | - for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { |
---|
798 | | - if (idx+1 == fls->mirror_array_cnt) |
---|
799 | | - fail_return = true; |
---|
800 | | - ds = nfs4_ff_layout_prepare_ds(lseg, idx, fail_return); |
---|
801 | | - if (ds) { |
---|
802 | | - *best_idx = idx; |
---|
803 | | - return ds; |
---|
804 | | - } |
---|
805 | | - } |
---|
| 787 | + ds = ff_layout_choose_valid_ds_for_read(lseg, start_idx, best_idx); |
---|
| 788 | + if (ds) |
---|
| 789 | + return ds; |
---|
| 790 | + return ff_layout_choose_any_ds_for_read(lseg, start_idx, best_idx); |
---|
| 791 | +} |
---|
806 | 792 | |
---|
807 | | - return NULL; |
---|
| 793 | +static struct nfs4_pnfs_ds * |
---|
| 794 | +ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio, |
---|
| 795 | + u32 *best_idx) |
---|
| 796 | +{ |
---|
| 797 | + struct pnfs_layout_segment *lseg = pgio->pg_lseg; |
---|
| 798 | + struct nfs4_pnfs_ds *ds; |
---|
| 799 | + |
---|
| 800 | + ds = ff_layout_choose_best_ds_for_read(lseg, pgio->pg_mirror_idx, |
---|
| 801 | + best_idx); |
---|
| 802 | + if (ds || !pgio->pg_mirror_idx) |
---|
| 803 | + return ds; |
---|
| 804 | + return ff_layout_choose_best_ds_for_read(lseg, 0, best_idx); |
---|
808 | 805 | } |
---|
809 | 806 | |
---|
810 | 807 | static void |
---|
.. | .. |
---|
814 | 811 | { |
---|
815 | 812 | pnfs_put_lseg(pgio->pg_lseg); |
---|
816 | 813 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
---|
817 | | - req->wb_context, |
---|
818 | | - 0, |
---|
819 | | - NFS4_MAX_UINT64, |
---|
| 814 | + nfs_req_openctx(req), |
---|
| 815 | + req_offset(req), |
---|
| 816 | + req->wb_bytes, |
---|
820 | 817 | IOMODE_READ, |
---|
821 | 818 | strict_iomode, |
---|
822 | 819 | GFP_KERNEL); |
---|
.. | .. |
---|
827 | 824 | } |
---|
828 | 825 | |
---|
829 | 826 | static void |
---|
| 827 | +ff_layout_pg_check_layout(struct nfs_pageio_descriptor *pgio, |
---|
| 828 | + struct nfs_page *req) |
---|
| 829 | +{ |
---|
| 830 | + pnfs_generic_pg_check_layout(pgio); |
---|
| 831 | + pnfs_generic_pg_check_range(pgio, req); |
---|
| 832 | +} |
---|
| 833 | + |
---|
| 834 | +static void |
---|
830 | 835 | ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio, |
---|
831 | 836 | struct nfs_page *req) |
---|
832 | 837 | { |
---|
833 | 838 | struct nfs_pgio_mirror *pgm; |
---|
834 | 839 | struct nfs4_ff_layout_mirror *mirror; |
---|
835 | 840 | struct nfs4_pnfs_ds *ds; |
---|
836 | | - int ds_idx; |
---|
| 841 | + u32 ds_idx; |
---|
837 | 842 | |
---|
838 | 843 | retry: |
---|
839 | | - pnfs_generic_pg_check_layout(pgio); |
---|
| 844 | + ff_layout_pg_check_layout(pgio, req); |
---|
840 | 845 | /* Use full layout for now */ |
---|
841 | 846 | if (!pgio->pg_lseg) { |
---|
842 | 847 | ff_layout_pg_get_read(pgio, req, false); |
---|
.. | .. |
---|
849 | 854 | goto out_nolseg; |
---|
850 | 855 | } |
---|
851 | 856 | |
---|
852 | | - ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx); |
---|
| 857 | + ds = ff_layout_get_ds_for_read(pgio, &ds_idx); |
---|
853 | 858 | if (!ds) { |
---|
854 | 859 | if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) |
---|
855 | 860 | goto out_mds; |
---|
856 | | - pnfs_put_lseg(pgio->pg_lseg); |
---|
857 | | - pgio->pg_lseg = NULL; |
---|
| 861 | + pnfs_generic_pg_cleanup(pgio); |
---|
858 | 862 | /* Sleep for 1 second before retrying */ |
---|
859 | 863 | ssleep(1); |
---|
860 | 864 | goto retry; |
---|
861 | 865 | } |
---|
862 | 866 | |
---|
863 | 867 | mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx); |
---|
864 | | - |
---|
865 | | - pgio->pg_mirror_idx = ds_idx; |
---|
866 | | - |
---|
867 | | - /* read always uses only one mirror - idx 0 for pgio layer */ |
---|
868 | 868 | pgm = &pgio->pg_mirrors[0]; |
---|
869 | 869 | pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize; |
---|
870 | 870 | |
---|
| 871 | + pgio->pg_mirror_idx = ds_idx; |
---|
| 872 | + |
---|
| 873 | + if (NFS_SERVER(pgio->pg_inode)->flags & |
---|
| 874 | + (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) |
---|
| 875 | + pgio->pg_maxretrans = io_maxretrans; |
---|
871 | 876 | return; |
---|
872 | 877 | out_nolseg: |
---|
873 | 878 | if (pgio->pg_error < 0) |
---|
874 | 879 | return; |
---|
875 | 880 | out_mds: |
---|
876 | | - pnfs_put_lseg(pgio->pg_lseg); |
---|
877 | | - pgio->pg_lseg = NULL; |
---|
| 881 | + trace_pnfs_mds_fallback_pg_init_read(pgio->pg_inode, |
---|
| 882 | + 0, NFS4_MAX_UINT64, IOMODE_READ, |
---|
| 883 | + NFS_I(pgio->pg_inode)->layout, |
---|
| 884 | + pgio->pg_lseg); |
---|
| 885 | + pgio->pg_maxretrans = 0; |
---|
878 | 886 | nfs_pageio_reset_read_mds(pgio); |
---|
879 | 887 | } |
---|
880 | 888 | |
---|
.. | .. |
---|
884 | 892 | { |
---|
885 | 893 | struct nfs4_ff_layout_mirror *mirror; |
---|
886 | 894 | struct nfs_pgio_mirror *pgm; |
---|
887 | | - struct nfs_commit_info cinfo; |
---|
888 | 895 | struct nfs4_pnfs_ds *ds; |
---|
889 | | - int i; |
---|
890 | | - int status; |
---|
| 896 | + u32 i; |
---|
891 | 897 | |
---|
892 | 898 | retry: |
---|
893 | | - pnfs_generic_pg_check_layout(pgio); |
---|
| 899 | + ff_layout_pg_check_layout(pgio, req); |
---|
894 | 900 | if (!pgio->pg_lseg) { |
---|
895 | 901 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
---|
896 | | - req->wb_context, |
---|
897 | | - 0, |
---|
898 | | - NFS4_MAX_UINT64, |
---|
| 902 | + nfs_req_openctx(req), |
---|
| 903 | + req_offset(req), |
---|
| 904 | + req->wb_bytes, |
---|
899 | 905 | IOMODE_RW, |
---|
900 | 906 | false, |
---|
901 | 907 | GFP_NOFS); |
---|
.. | .. |
---|
909 | 915 | if (pgio->pg_lseg == NULL) |
---|
910 | 916 | goto out_mds; |
---|
911 | 917 | |
---|
912 | | - nfs_init_cinfo(&cinfo, pgio->pg_inode, pgio->pg_dreq); |
---|
913 | | - status = ff_layout_alloc_commit_info(pgio->pg_lseg, &cinfo, GFP_NOFS); |
---|
914 | | - if (status < 0) |
---|
915 | | - goto out_mds; |
---|
916 | | - |
---|
917 | 918 | /* Use a direct mapping of ds_idx to pgio mirror_idx */ |
---|
918 | 919 | if (pgio->pg_mirror_count != FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg)) |
---|
919 | 920 | goto out_eagain; |
---|
920 | 921 | |
---|
921 | 922 | for (i = 0; i < pgio->pg_mirror_count; i++) { |
---|
922 | | - ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, i, true); |
---|
| 923 | + mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); |
---|
| 924 | + ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, mirror, true); |
---|
923 | 925 | if (!ds) { |
---|
924 | 926 | if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) |
---|
925 | 927 | goto out_mds; |
---|
926 | | - pnfs_put_lseg(pgio->pg_lseg); |
---|
927 | | - pgio->pg_lseg = NULL; |
---|
| 928 | + pnfs_generic_pg_cleanup(pgio); |
---|
928 | 929 | /* Sleep for 1 second before retrying */ |
---|
929 | 930 | ssleep(1); |
---|
930 | 931 | goto retry; |
---|
931 | 932 | } |
---|
932 | 933 | pgm = &pgio->pg_mirrors[i]; |
---|
933 | | - mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); |
---|
934 | 934 | pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize; |
---|
935 | 935 | } |
---|
936 | 936 | |
---|
| 937 | + if (NFS_SERVER(pgio->pg_inode)->flags & |
---|
| 938 | + (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)) |
---|
| 939 | + pgio->pg_maxretrans = io_maxretrans; |
---|
937 | 940 | return; |
---|
938 | 941 | out_eagain: |
---|
939 | 942 | pnfs_generic_pg_cleanup(pgio); |
---|
940 | 943 | pgio->pg_error = -EAGAIN; |
---|
941 | 944 | return; |
---|
942 | 945 | out_mds: |
---|
943 | | - pnfs_put_lseg(pgio->pg_lseg); |
---|
944 | | - pgio->pg_lseg = NULL; |
---|
| 946 | + trace_pnfs_mds_fallback_pg_init_write(pgio->pg_inode, |
---|
| 947 | + 0, NFS4_MAX_UINT64, IOMODE_RW, |
---|
| 948 | + NFS_I(pgio->pg_inode)->layout, |
---|
| 949 | + pgio->pg_lseg); |
---|
| 950 | + pgio->pg_maxretrans = 0; |
---|
945 | 951 | nfs_pageio_reset_write_mds(pgio); |
---|
946 | 952 | pgio->pg_error = -EAGAIN; |
---|
947 | 953 | } |
---|
.. | .. |
---|
952 | 958 | { |
---|
953 | 959 | if (!pgio->pg_lseg) { |
---|
954 | 960 | pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, |
---|
955 | | - req->wb_context, |
---|
956 | | - 0, |
---|
957 | | - NFS4_MAX_UINT64, |
---|
| 961 | + nfs_req_openctx(req), |
---|
| 962 | + req_offset(req), |
---|
| 963 | + req->wb_bytes, |
---|
958 | 964 | IOMODE_RW, |
---|
959 | 965 | false, |
---|
960 | 966 | GFP_NOFS); |
---|
.. | .. |
---|
967 | 973 | if (pgio->pg_lseg) |
---|
968 | 974 | return FF_LAYOUT_MIRROR_COUNT(pgio->pg_lseg); |
---|
969 | 975 | |
---|
| 976 | + trace_pnfs_mds_fallback_pg_get_mirror_count(pgio->pg_inode, |
---|
| 977 | + 0, NFS4_MAX_UINT64, IOMODE_RW, |
---|
| 978 | + NFS_I(pgio->pg_inode)->layout, |
---|
| 979 | + pgio->pg_lseg); |
---|
970 | 980 | /* no lseg means that pnfs is not in use, so no mirroring here */ |
---|
971 | 981 | nfs_pageio_reset_write_mds(pgio); |
---|
972 | 982 | out: |
---|
973 | 983 | return 1; |
---|
| 984 | +} |
---|
| 985 | + |
---|
| 986 | +static u32 |
---|
| 987 | +ff_layout_pg_set_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx) |
---|
| 988 | +{ |
---|
| 989 | + u32 old = desc->pg_mirror_idx; |
---|
| 990 | + |
---|
| 991 | + desc->pg_mirror_idx = idx; |
---|
| 992 | + return old; |
---|
| 993 | +} |
---|
| 994 | + |
---|
| 995 | +static struct nfs_pgio_mirror * |
---|
| 996 | +ff_layout_pg_get_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx) |
---|
| 997 | +{ |
---|
| 998 | + return &desc->pg_mirrors[idx]; |
---|
974 | 999 | } |
---|
975 | 1000 | |
---|
976 | 1001 | static const struct nfs_pageio_ops ff_layout_pg_read_ops = { |
---|
.. | .. |
---|
986 | 1011 | .pg_doio = pnfs_generic_pg_writepages, |
---|
987 | 1012 | .pg_get_mirror_count = ff_layout_pg_get_mirror_count_write, |
---|
988 | 1013 | .pg_cleanup = pnfs_generic_pg_cleanup, |
---|
| 1014 | + .pg_get_mirror = ff_layout_pg_get_mirror_write, |
---|
| 1015 | + .pg_set_mirror = ff_layout_pg_set_mirror_write, |
---|
989 | 1016 | }; |
---|
990 | 1017 | |
---|
991 | 1018 | static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs) |
---|
.. | .. |
---|
1016 | 1043 | hdr->args.count, |
---|
1017 | 1044 | (unsigned long long)hdr->args.offset); |
---|
1018 | 1045 | |
---|
| 1046 | + trace_pnfs_mds_fallback_write_done(hdr->inode, |
---|
| 1047 | + hdr->args.offset, hdr->args.count, |
---|
| 1048 | + IOMODE_RW, NFS_I(hdr->inode)->layout, |
---|
| 1049 | + hdr->lseg); |
---|
1019 | 1050 | task->tk_status = pnfs_write_done_resend_to_mds(hdr); |
---|
1020 | 1051 | } |
---|
| 1052 | +} |
---|
| 1053 | + |
---|
| 1054 | +static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr) |
---|
| 1055 | +{ |
---|
| 1056 | + u32 idx = hdr->pgio_mirror_idx + 1; |
---|
| 1057 | + u32 new_idx = 0; |
---|
| 1058 | + |
---|
| 1059 | + if (ff_layout_choose_any_ds_for_read(hdr->lseg, idx, &new_idx)) |
---|
| 1060 | + ff_layout_send_layouterror(hdr->lseg); |
---|
| 1061 | + else |
---|
| 1062 | + pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg); |
---|
| 1063 | + pnfs_read_resend_pnfs(hdr, new_idx); |
---|
1021 | 1064 | } |
---|
1022 | 1065 | |
---|
1023 | 1066 | static void ff_layout_reset_read(struct nfs_pgio_header *hdr) |
---|
.. | .. |
---|
1025 | 1068 | struct rpc_task *task = &hdr->task; |
---|
1026 | 1069 | |
---|
1027 | 1070 | pnfs_layoutcommit_inode(hdr->inode, false); |
---|
| 1071 | + pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg); |
---|
1028 | 1072 | |
---|
1029 | 1073 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { |
---|
1030 | 1074 | dprintk("%s Reset task %5u for i/o through MDS " |
---|
.. | .. |
---|
1035 | 1079 | hdr->args.count, |
---|
1036 | 1080 | (unsigned long long)hdr->args.offset); |
---|
1037 | 1081 | |
---|
| 1082 | + trace_pnfs_mds_fallback_read_done(hdr->inode, |
---|
| 1083 | + hdr->args.offset, hdr->args.count, |
---|
| 1084 | + IOMODE_READ, NFS_I(hdr->inode)->layout, |
---|
| 1085 | + hdr->lseg); |
---|
1038 | 1086 | task->tk_status = pnfs_read_done_resend_to_mds(hdr); |
---|
1039 | 1087 | } |
---|
1040 | 1088 | } |
---|
.. | .. |
---|
1043 | 1091 | struct nfs4_state *state, |
---|
1044 | 1092 | struct nfs_client *clp, |
---|
1045 | 1093 | struct pnfs_layout_segment *lseg, |
---|
1046 | | - int idx) |
---|
| 1094 | + u32 idx) |
---|
1047 | 1095 | { |
---|
1048 | 1096 | struct pnfs_layout_hdr *lo = lseg->pls_layout; |
---|
1049 | 1097 | struct inode *inode = lo->plh_inode; |
---|
.. | .. |
---|
1101 | 1149 | nfs4_delete_deviceid(devid->ld, devid->nfs_client, |
---|
1102 | 1150 | &devid->deviceid); |
---|
1103 | 1151 | rpc_wake_up(&tbl->slot_tbl_waitq); |
---|
1104 | | - /* fall through */ |
---|
| 1152 | + fallthrough; |
---|
1105 | 1153 | default: |
---|
1106 | 1154 | if (ff_layout_avoid_mds_available_ds(lseg)) |
---|
1107 | 1155 | return -NFS4ERR_RESET_TO_PNFS; |
---|
.. | .. |
---|
1117 | 1165 | /* Retry all errors through either pNFS or MDS except for -EJUKEBOX */ |
---|
1118 | 1166 | static int ff_layout_async_handle_error_v3(struct rpc_task *task, |
---|
1119 | 1167 | struct pnfs_layout_segment *lseg, |
---|
1120 | | - int idx) |
---|
| 1168 | + u32 idx) |
---|
1121 | 1169 | { |
---|
1122 | 1170 | struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx); |
---|
1123 | 1171 | |
---|
.. | .. |
---|
1152 | 1200 | struct nfs4_state *state, |
---|
1153 | 1201 | struct nfs_client *clp, |
---|
1154 | 1202 | struct pnfs_layout_segment *lseg, |
---|
1155 | | - int idx) |
---|
| 1203 | + u32 idx) |
---|
1156 | 1204 | { |
---|
1157 | 1205 | int vers = clp->cl_nfs_mod->rpc_vers->number; |
---|
1158 | 1206 | |
---|
1159 | | - if (task->tk_status >= 0) |
---|
| 1207 | + if (task->tk_status >= 0) { |
---|
| 1208 | + ff_layout_mark_ds_reachable(lseg, idx); |
---|
1160 | 1209 | return 0; |
---|
| 1210 | + } |
---|
1161 | 1211 | |
---|
1162 | 1212 | /* Handle the case of an invalid layout segment */ |
---|
1163 | 1213 | if (!pnfs_is_valid_lseg(lseg)) |
---|
.. | .. |
---|
1177 | 1227 | } |
---|
1178 | 1228 | |
---|
1179 | 1229 | static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg, |
---|
1180 | | - int idx, u64 offset, u64 length, |
---|
1181 | | - u32 status, int opnum, int error) |
---|
| 1230 | + u32 idx, u64 offset, u64 length, |
---|
| 1231 | + u32 *op_status, int opnum, int error) |
---|
1182 | 1232 | { |
---|
1183 | 1233 | struct nfs4_ff_layout_mirror *mirror; |
---|
| 1234 | + u32 status = *op_status; |
---|
1184 | 1235 | int err; |
---|
1185 | 1236 | |
---|
1186 | 1237 | if (status == 0) { |
---|
.. | .. |
---|
1198 | 1249 | case -ENOBUFS: |
---|
1199 | 1250 | case -EPIPE: |
---|
1200 | 1251 | case -EPERM: |
---|
1201 | | - status = NFS4ERR_NXIO; |
---|
| 1252 | + *op_status = status = NFS4ERR_NXIO; |
---|
1202 | 1253 | break; |
---|
1203 | 1254 | case -EACCES: |
---|
1204 | | - status = NFS4ERR_ACCESS; |
---|
| 1255 | + *op_status = status = NFS4ERR_ACCESS; |
---|
1205 | 1256 | break; |
---|
1206 | 1257 | default: |
---|
1207 | 1258 | return; |
---|
1208 | 1259 | } |
---|
1209 | 1260 | } |
---|
1210 | 1261 | |
---|
1211 | | - switch (status) { |
---|
1212 | | - case NFS4ERR_DELAY: |
---|
1213 | | - case NFS4ERR_GRACE: |
---|
1214 | | - return; |
---|
1215 | | - default: |
---|
1216 | | - break; |
---|
1217 | | - } |
---|
1218 | | - |
---|
1219 | 1262 | mirror = FF_LAYOUT_COMP(lseg, idx); |
---|
1220 | 1263 | err = ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), |
---|
1221 | 1264 | mirror, offset, length, status, opnum, |
---|
1222 | 1265 | GFP_NOIO); |
---|
1223 | | - pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode, lseg); |
---|
| 1266 | + |
---|
| 1267 | + switch (status) { |
---|
| 1268 | + case NFS4ERR_DELAY: |
---|
| 1269 | + case NFS4ERR_GRACE: |
---|
| 1270 | + break; |
---|
| 1271 | + case NFS4ERR_NXIO: |
---|
| 1272 | + ff_layout_mark_ds_unreachable(lseg, idx); |
---|
| 1273 | + /* |
---|
| 1274 | + * Don't return the layout if this is a read and we still |
---|
| 1275 | + * have layouts to try |
---|
| 1276 | + */ |
---|
| 1277 | + if (opnum == OP_READ) |
---|
| 1278 | + break; |
---|
| 1279 | + fallthrough; |
---|
| 1280 | + default: |
---|
| 1281 | + pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode, |
---|
| 1282 | + lseg); |
---|
| 1283 | + } |
---|
| 1284 | + |
---|
1224 | 1285 | dprintk("%s: err %d op %d status %u\n", __func__, err, opnum, status); |
---|
1225 | 1286 | } |
---|
1226 | 1287 | |
---|
.. | .. |
---|
1230 | 1291 | { |
---|
1231 | 1292 | int err; |
---|
1232 | 1293 | |
---|
1233 | | - trace_nfs4_pnfs_read(hdr, task->tk_status); |
---|
1234 | | - if (task->tk_status < 0) |
---|
| 1294 | + if (task->tk_status < 0) { |
---|
1235 | 1295 | ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx, |
---|
1236 | 1296 | hdr->args.offset, hdr->args.count, |
---|
1237 | | - hdr->res.op_status, OP_READ, |
---|
| 1297 | + &hdr->res.op_status, OP_READ, |
---|
1238 | 1298 | task->tk_status); |
---|
| 1299 | + trace_ff_layout_read_error(hdr); |
---|
| 1300 | + } |
---|
| 1301 | + |
---|
1239 | 1302 | err = ff_layout_async_handle_error(task, hdr->args.context->state, |
---|
1240 | 1303 | hdr->ds_clp, hdr->lseg, |
---|
1241 | 1304 | hdr->pgio_mirror_idx); |
---|
1242 | 1305 | |
---|
| 1306 | + trace_nfs4_pnfs_read(hdr, err); |
---|
1243 | 1307 | clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); |
---|
1244 | 1308 | clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); |
---|
1245 | 1309 | switch (err) { |
---|
1246 | 1310 | case -NFS4ERR_RESET_TO_PNFS: |
---|
1247 | | - if (ff_layout_choose_best_ds_for_read(hdr->lseg, |
---|
1248 | | - hdr->pgio_mirror_idx + 1, |
---|
1249 | | - &hdr->pgio_mirror_idx)) |
---|
1250 | | - goto out_eagain; |
---|
1251 | 1311 | set_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); |
---|
1252 | 1312 | return task->tk_status; |
---|
1253 | 1313 | case -NFS4ERR_RESET_TO_MDS: |
---|
.. | .. |
---|
1291 | 1351 | (unsigned long long) NFS_I(inode)->layout->plh_lwb); |
---|
1292 | 1352 | } |
---|
1293 | 1353 | |
---|
1294 | | -static bool |
---|
1295 | | -ff_layout_device_unavailable(struct pnfs_layout_segment *lseg, int idx) |
---|
1296 | | -{ |
---|
1297 | | - /* No mirroring for now */ |
---|
1298 | | - struct nfs4_deviceid_node *node = FF_LAYOUT_DEVID_NODE(lseg, idx); |
---|
1299 | | - |
---|
1300 | | - return ff_layout_test_devid_unavailable(node); |
---|
1301 | | -} |
---|
1302 | | - |
---|
1303 | 1354 | static void ff_layout_read_record_layoutstats_start(struct rpc_task *task, |
---|
1304 | 1355 | struct nfs_pgio_header *hdr) |
---|
1305 | 1356 | { |
---|
.. | .. |
---|
1329 | 1380 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) { |
---|
1330 | 1381 | rpc_exit(task, -EIO); |
---|
1331 | 1382 | return -EIO; |
---|
1332 | | - } |
---|
1333 | | - if (ff_layout_device_unavailable(hdr->lseg, hdr->pgio_mirror_idx)) { |
---|
1334 | | - rpc_exit(task, -EHOSTDOWN); |
---|
1335 | | - return -EAGAIN; |
---|
1336 | 1383 | } |
---|
1337 | 1384 | |
---|
1338 | 1385 | ff_layout_read_record_layoutstats_start(task, hdr); |
---|
.. | .. |
---|
1398 | 1445 | |
---|
1399 | 1446 | ff_layout_read_record_layoutstats_done(&hdr->task, hdr); |
---|
1400 | 1447 | if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) |
---|
1401 | | - pnfs_read_resend_pnfs(hdr); |
---|
| 1448 | + ff_layout_resend_pnfs_read(hdr); |
---|
1402 | 1449 | else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags)) |
---|
1403 | 1450 | ff_layout_reset_read(hdr); |
---|
1404 | 1451 | pnfs_generic_rw_release(data); |
---|
.. | .. |
---|
1411 | 1458 | loff_t end_offs = 0; |
---|
1412 | 1459 | int err; |
---|
1413 | 1460 | |
---|
1414 | | - trace_nfs4_pnfs_write(hdr, task->tk_status); |
---|
1415 | | - if (task->tk_status < 0) |
---|
| 1461 | + if (task->tk_status < 0) { |
---|
1416 | 1462 | ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx, |
---|
1417 | 1463 | hdr->args.offset, hdr->args.count, |
---|
1418 | | - hdr->res.op_status, OP_WRITE, |
---|
| 1464 | + &hdr->res.op_status, OP_WRITE, |
---|
1419 | 1465 | task->tk_status); |
---|
| 1466 | + trace_ff_layout_write_error(hdr); |
---|
| 1467 | + } |
---|
| 1468 | + |
---|
1420 | 1469 | err = ff_layout_async_handle_error(task, hdr->args.context->state, |
---|
1421 | 1470 | hdr->ds_clp, hdr->lseg, |
---|
1422 | 1471 | hdr->pgio_mirror_idx); |
---|
1423 | 1472 | |
---|
| 1473 | + trace_nfs4_pnfs_write(hdr, err); |
---|
1424 | 1474 | clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags); |
---|
1425 | 1475 | clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags); |
---|
1426 | 1476 | switch (err) { |
---|
.. | .. |
---|
1454 | 1504 | { |
---|
1455 | 1505 | int err; |
---|
1456 | 1506 | |
---|
1457 | | - trace_nfs4_pnfs_commit_ds(data, task->tk_status); |
---|
1458 | | - if (task->tk_status < 0) |
---|
| 1507 | + if (task->tk_status < 0) { |
---|
1459 | 1508 | ff_layout_io_track_ds_error(data->lseg, data->ds_commit_index, |
---|
1460 | 1509 | data->args.offset, data->args.count, |
---|
1461 | | - data->res.op_status, OP_COMMIT, |
---|
| 1510 | + &data->res.op_status, OP_COMMIT, |
---|
1462 | 1511 | task->tk_status); |
---|
| 1512 | + trace_ff_layout_commit_error(data); |
---|
| 1513 | + } |
---|
| 1514 | + |
---|
1463 | 1515 | err = ff_layout_async_handle_error(task, NULL, data->ds_clp, |
---|
1464 | 1516 | data->lseg, data->ds_commit_index); |
---|
1465 | 1517 | |
---|
| 1518 | + trace_nfs4_pnfs_commit_ds(data, err); |
---|
1466 | 1519 | switch (err) { |
---|
1467 | 1520 | case -NFS4ERR_RESET_TO_PNFS: |
---|
1468 | 1521 | pnfs_generic_prepare_to_resend_writes(data); |
---|
.. | .. |
---|
1509 | 1562 | if (unlikely(test_bit(NFS_CONTEXT_BAD, &hdr->args.context->flags))) { |
---|
1510 | 1563 | rpc_exit(task, -EIO); |
---|
1511 | 1564 | return -EIO; |
---|
1512 | | - } |
---|
1513 | | - |
---|
1514 | | - if (ff_layout_device_unavailable(hdr->lseg, hdr->pgio_mirror_idx)) { |
---|
1515 | | - rpc_exit(task, -EHOSTDOWN); |
---|
1516 | | - return -EAGAIN; |
---|
1517 | 1565 | } |
---|
1518 | 1566 | |
---|
1519 | 1567 | ff_layout_write_record_layoutstats_start(task, hdr); |
---|
.. | .. |
---|
1571 | 1619 | struct nfs_pgio_header *hdr = data; |
---|
1572 | 1620 | |
---|
1573 | 1621 | ff_layout_write_record_layoutstats_done(&hdr->task, hdr); |
---|
1574 | | - if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) |
---|
| 1622 | + if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) { |
---|
| 1623 | + ff_layout_send_layouterror(hdr->lseg); |
---|
1575 | 1624 | ff_layout_reset_write(hdr, true); |
---|
1576 | | - else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags)) |
---|
| 1625 | + } else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags)) |
---|
1577 | 1626 | ff_layout_reset_write(hdr, false); |
---|
1578 | 1627 | pnfs_generic_rw_release(data); |
---|
1579 | 1628 | } |
---|
.. | .. |
---|
1701 | 1750 | struct pnfs_layout_segment *lseg = hdr->lseg; |
---|
1702 | 1751 | struct nfs4_pnfs_ds *ds; |
---|
1703 | 1752 | struct rpc_clnt *ds_clnt; |
---|
1704 | | - struct rpc_cred *ds_cred; |
---|
| 1753 | + struct nfs4_ff_layout_mirror *mirror; |
---|
| 1754 | + const struct cred *ds_cred; |
---|
1705 | 1755 | loff_t offset = hdr->args.offset; |
---|
1706 | 1756 | u32 idx = hdr->pgio_mirror_idx; |
---|
1707 | 1757 | int vers; |
---|
.. | .. |
---|
1711 | 1761 | __func__, hdr->inode->i_ino, |
---|
1712 | 1762 | hdr->args.pgbase, (size_t)hdr->args.count, offset); |
---|
1713 | 1763 | |
---|
1714 | | - ds = nfs4_ff_layout_prepare_ds(lseg, idx, false); |
---|
| 1764 | + mirror = FF_LAYOUT_COMP(lseg, idx); |
---|
| 1765 | + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, false); |
---|
1715 | 1766 | if (!ds) |
---|
1716 | 1767 | goto out_failed; |
---|
1717 | 1768 | |
---|
1718 | | - ds_clnt = nfs4_ff_find_or_create_ds_client(lseg, idx, ds->ds_clp, |
---|
| 1769 | + ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, |
---|
1719 | 1770 | hdr->inode); |
---|
1720 | 1771 | if (IS_ERR(ds_clnt)) |
---|
1721 | 1772 | goto out_failed; |
---|
1722 | 1773 | |
---|
1723 | | - ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); |
---|
| 1774 | + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred); |
---|
1724 | 1775 | if (!ds_cred) |
---|
1725 | 1776 | goto out_failed; |
---|
1726 | 1777 | |
---|
1727 | | - vers = nfs4_ff_layout_ds_version(lseg, idx); |
---|
| 1778 | + vers = nfs4_ff_layout_ds_version(mirror); |
---|
1728 | 1779 | |
---|
1729 | 1780 | dprintk("%s USE DS: %s cl_count %d vers %d\n", __func__, |
---|
1730 | 1781 | ds->ds_remotestr, refcount_read(&ds->ds_clp->cl_count), vers); |
---|
.. | .. |
---|
1732 | 1783 | hdr->pgio_done_cb = ff_layout_read_done_cb; |
---|
1733 | 1784 | refcount_inc(&ds->ds_clp->cl_count); |
---|
1734 | 1785 | hdr->ds_clp = ds->ds_clp; |
---|
1735 | | - fh = nfs4_ff_layout_select_ds_fh(lseg, idx); |
---|
| 1786 | + fh = nfs4_ff_layout_select_ds_fh(mirror); |
---|
1736 | 1787 | if (fh) |
---|
1737 | 1788 | hdr->args.fh = fh; |
---|
1738 | 1789 | |
---|
1739 | | - if (vers == 4 && |
---|
1740 | | - !nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid)) |
---|
1741 | | - goto out_failed; |
---|
| 1790 | + nfs4_ff_layout_select_ds_stateid(mirror, &hdr->args.stateid); |
---|
1742 | 1791 | |
---|
1743 | 1792 | /* |
---|
1744 | 1793 | * Note that if we ever decide to split across DSes, |
---|
.. | .. |
---|
1752 | 1801 | vers == 3 ? &ff_layout_read_call_ops_v3 : |
---|
1753 | 1802 | &ff_layout_read_call_ops_v4, |
---|
1754 | 1803 | 0, RPC_TASK_SOFTCONN); |
---|
1755 | | - put_rpccred(ds_cred); |
---|
| 1804 | + put_cred(ds_cred); |
---|
1756 | 1805 | return PNFS_ATTEMPTED; |
---|
1757 | 1806 | |
---|
1758 | 1807 | out_failed: |
---|
1759 | 1808 | if (ff_layout_avoid_mds_available_ds(lseg)) |
---|
1760 | 1809 | return PNFS_TRY_AGAIN; |
---|
| 1810 | + trace_pnfs_mds_fallback_read_pagelist(hdr->inode, |
---|
| 1811 | + hdr->args.offset, hdr->args.count, |
---|
| 1812 | + IOMODE_READ, NFS_I(hdr->inode)->layout, lseg); |
---|
1761 | 1813 | return PNFS_NOT_ATTEMPTED; |
---|
1762 | 1814 | } |
---|
1763 | 1815 | |
---|
.. | .. |
---|
1768 | 1820 | struct pnfs_layout_segment *lseg = hdr->lseg; |
---|
1769 | 1821 | struct nfs4_pnfs_ds *ds; |
---|
1770 | 1822 | struct rpc_clnt *ds_clnt; |
---|
1771 | | - struct rpc_cred *ds_cred; |
---|
| 1823 | + struct nfs4_ff_layout_mirror *mirror; |
---|
| 1824 | + const struct cred *ds_cred; |
---|
1772 | 1825 | loff_t offset = hdr->args.offset; |
---|
1773 | 1826 | int vers; |
---|
1774 | 1827 | struct nfs_fh *fh; |
---|
1775 | | - int idx = hdr->pgio_mirror_idx; |
---|
| 1828 | + u32 idx = hdr->pgio_mirror_idx; |
---|
1776 | 1829 | |
---|
1777 | | - ds = nfs4_ff_layout_prepare_ds(lseg, idx, true); |
---|
| 1830 | + mirror = FF_LAYOUT_COMP(lseg, idx); |
---|
| 1831 | + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true); |
---|
1778 | 1832 | if (!ds) |
---|
1779 | 1833 | goto out_failed; |
---|
1780 | 1834 | |
---|
1781 | | - ds_clnt = nfs4_ff_find_or_create_ds_client(lseg, idx, ds->ds_clp, |
---|
| 1835 | + ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, |
---|
1782 | 1836 | hdr->inode); |
---|
1783 | 1837 | if (IS_ERR(ds_clnt)) |
---|
1784 | 1838 | goto out_failed; |
---|
1785 | 1839 | |
---|
1786 | | - ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); |
---|
| 1840 | + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, hdr->cred); |
---|
1787 | 1841 | if (!ds_cred) |
---|
1788 | 1842 | goto out_failed; |
---|
1789 | 1843 | |
---|
1790 | | - vers = nfs4_ff_layout_ds_version(lseg, idx); |
---|
| 1844 | + vers = nfs4_ff_layout_ds_version(mirror); |
---|
1791 | 1845 | |
---|
1792 | 1846 | dprintk("%s ino %lu sync %d req %zu@%llu DS: %s cl_count %d vers %d\n", |
---|
1793 | 1847 | __func__, hdr->inode->i_ino, sync, (size_t) hdr->args.count, |
---|
.. | .. |
---|
1798 | 1852 | refcount_inc(&ds->ds_clp->cl_count); |
---|
1799 | 1853 | hdr->ds_clp = ds->ds_clp; |
---|
1800 | 1854 | hdr->ds_commit_idx = idx; |
---|
1801 | | - fh = nfs4_ff_layout_select_ds_fh(lseg, idx); |
---|
| 1855 | + fh = nfs4_ff_layout_select_ds_fh(mirror); |
---|
1802 | 1856 | if (fh) |
---|
1803 | 1857 | hdr->args.fh = fh; |
---|
1804 | 1858 | |
---|
1805 | | - if (vers == 4 && |
---|
1806 | | - !nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid)) |
---|
1807 | | - goto out_failed; |
---|
| 1859 | + nfs4_ff_layout_select_ds_stateid(mirror, &hdr->args.stateid); |
---|
1808 | 1860 | |
---|
1809 | 1861 | /* |
---|
1810 | 1862 | * Note that if we ever decide to split across DSes, |
---|
.. | .. |
---|
1817 | 1869 | vers == 3 ? &ff_layout_write_call_ops_v3 : |
---|
1818 | 1870 | &ff_layout_write_call_ops_v4, |
---|
1819 | 1871 | sync, RPC_TASK_SOFTCONN); |
---|
1820 | | - put_rpccred(ds_cred); |
---|
| 1872 | + put_cred(ds_cred); |
---|
1821 | 1873 | return PNFS_ATTEMPTED; |
---|
1822 | 1874 | |
---|
1823 | 1875 | out_failed: |
---|
1824 | 1876 | if (ff_layout_avoid_mds_available_ds(lseg)) |
---|
1825 | 1877 | return PNFS_TRY_AGAIN; |
---|
| 1878 | + trace_pnfs_mds_fallback_write_pagelist(hdr->inode, |
---|
| 1879 | + hdr->args.offset, hdr->args.count, |
---|
| 1880 | + IOMODE_RW, NFS_I(hdr->inode)->layout, lseg); |
---|
1826 | 1881 | return PNFS_NOT_ATTEMPTED; |
---|
1827 | 1882 | } |
---|
1828 | 1883 | |
---|
.. | .. |
---|
1847 | 1902 | struct pnfs_layout_segment *lseg = data->lseg; |
---|
1848 | 1903 | struct nfs4_pnfs_ds *ds; |
---|
1849 | 1904 | struct rpc_clnt *ds_clnt; |
---|
1850 | | - struct rpc_cred *ds_cred; |
---|
| 1905 | + struct nfs4_ff_layout_mirror *mirror; |
---|
| 1906 | + const struct cred *ds_cred; |
---|
1851 | 1907 | u32 idx; |
---|
1852 | 1908 | int vers, ret; |
---|
1853 | 1909 | struct nfs_fh *fh; |
---|
.. | .. |
---|
1857 | 1913 | goto out_err; |
---|
1858 | 1914 | |
---|
1859 | 1915 | idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); |
---|
1860 | | - ds = nfs4_ff_layout_prepare_ds(lseg, idx, true); |
---|
| 1916 | + mirror = FF_LAYOUT_COMP(lseg, idx); |
---|
| 1917 | + ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true); |
---|
1861 | 1918 | if (!ds) |
---|
1862 | 1919 | goto out_err; |
---|
1863 | 1920 | |
---|
1864 | | - ds_clnt = nfs4_ff_find_or_create_ds_client(lseg, idx, ds->ds_clp, |
---|
| 1921 | + ds_clnt = nfs4_ff_find_or_create_ds_client(mirror, ds->ds_clp, |
---|
1865 | 1922 | data->inode); |
---|
1866 | 1923 | if (IS_ERR(ds_clnt)) |
---|
1867 | 1924 | goto out_err; |
---|
1868 | 1925 | |
---|
1869 | | - ds_cred = ff_layout_get_ds_cred(lseg, idx, data->cred); |
---|
| 1926 | + ds_cred = ff_layout_get_ds_cred(mirror, &lseg->pls_range, data->cred); |
---|
1870 | 1927 | if (!ds_cred) |
---|
1871 | 1928 | goto out_err; |
---|
1872 | 1929 | |
---|
1873 | | - vers = nfs4_ff_layout_ds_version(lseg, idx); |
---|
| 1930 | + vers = nfs4_ff_layout_ds_version(mirror); |
---|
1874 | 1931 | |
---|
1875 | 1932 | dprintk("%s ino %lu, how %d cl_count %d vers %d\n", __func__, |
---|
1876 | 1933 | data->inode->i_ino, how, refcount_read(&ds->ds_clp->cl_count), |
---|
.. | .. |
---|
1887 | 1944 | vers == 3 ? &ff_layout_commit_call_ops_v3 : |
---|
1888 | 1945 | &ff_layout_commit_call_ops_v4, |
---|
1889 | 1946 | how, RPC_TASK_SOFTCONN); |
---|
1890 | | - put_rpccred(ds_cred); |
---|
| 1947 | + put_cred(ds_cred); |
---|
1891 | 1948 | return ret; |
---|
1892 | 1949 | out_err: |
---|
1893 | 1950 | pnfs_generic_prepare_to_resend_writes(data); |
---|
.. | .. |
---|
1912 | 1969 | return NULL; |
---|
1913 | 1970 | |
---|
1914 | 1971 | return &FF_LAYOUT_FROM_HDR(layout)->commit_info; |
---|
| 1972 | +} |
---|
| 1973 | + |
---|
| 1974 | +static void |
---|
| 1975 | +ff_layout_setup_ds_info(struct pnfs_ds_commit_info *fl_cinfo, |
---|
| 1976 | + struct pnfs_layout_segment *lseg) |
---|
| 1977 | +{ |
---|
| 1978 | + struct nfs4_ff_layout_segment *flseg = FF_LAYOUT_LSEG(lseg); |
---|
| 1979 | + struct inode *inode = lseg->pls_layout->plh_inode; |
---|
| 1980 | + struct pnfs_commit_array *array, *new; |
---|
| 1981 | + |
---|
| 1982 | + new = pnfs_alloc_commit_array(flseg->mirror_array_cnt, GFP_NOIO); |
---|
| 1983 | + if (new) { |
---|
| 1984 | + spin_lock(&inode->i_lock); |
---|
| 1985 | + array = pnfs_add_commit_array(fl_cinfo, new, lseg); |
---|
| 1986 | + spin_unlock(&inode->i_lock); |
---|
| 1987 | + if (array != new) |
---|
| 1988 | + pnfs_free_commit_array(new); |
---|
| 1989 | + } |
---|
| 1990 | +} |
---|
| 1991 | + |
---|
| 1992 | +static void |
---|
| 1993 | +ff_layout_release_ds_info(struct pnfs_ds_commit_info *fl_cinfo, |
---|
| 1994 | + struct inode *inode) |
---|
| 1995 | +{ |
---|
| 1996 | + spin_lock(&inode->i_lock); |
---|
| 1997 | + pnfs_generic_ds_cinfo_destroy(fl_cinfo); |
---|
| 1998 | + spin_unlock(&inode->i_lock); |
---|
1915 | 1999 | } |
---|
1916 | 2000 | |
---|
1917 | 2001 | static void |
---|
.. | .. |
---|
2034 | 2118 | |
---|
2035 | 2119 | dprintk("%s: Begin\n", __func__); |
---|
2036 | 2120 | |
---|
2037 | | - xdr_init_encode(&tmp_xdr, &tmp_buf, NULL); |
---|
| 2121 | + xdr_init_encode(&tmp_xdr, &tmp_buf, NULL, NULL); |
---|
2038 | 2122 | |
---|
2039 | 2123 | ff_layout_encode_ioerr(&tmp_xdr, args, ff_args); |
---|
2040 | 2124 | ff_layout_encode_iostats_array(&tmp_xdr, args, ff_args); |
---|
.. | .. |
---|
2099 | 2183 | out_nomem: |
---|
2100 | 2184 | return -ENOMEM; |
---|
2101 | 2185 | } |
---|
| 2186 | + |
---|
| 2187 | +#ifdef CONFIG_NFS_V4_2 |
---|
| 2188 | +void |
---|
| 2189 | +ff_layout_send_layouterror(struct pnfs_layout_segment *lseg) |
---|
| 2190 | +{ |
---|
| 2191 | + struct pnfs_layout_hdr *lo = lseg->pls_layout; |
---|
| 2192 | + struct nfs42_layout_error *errors; |
---|
| 2193 | + LIST_HEAD(head); |
---|
| 2194 | + |
---|
| 2195 | + if (!nfs_server_capable(lo->plh_inode, NFS_CAP_LAYOUTERROR)) |
---|
| 2196 | + return; |
---|
| 2197 | + ff_layout_fetch_ds_ioerr(lo, &lseg->pls_range, &head, -1); |
---|
| 2198 | + if (list_empty(&head)) |
---|
| 2199 | + return; |
---|
| 2200 | + |
---|
| 2201 | + errors = kmalloc_array(NFS42_LAYOUTERROR_MAX, |
---|
| 2202 | + sizeof(*errors), GFP_NOFS); |
---|
| 2203 | + if (errors != NULL) { |
---|
| 2204 | + const struct nfs4_ff_layout_ds_err *pos; |
---|
| 2205 | + size_t n = 0; |
---|
| 2206 | + |
---|
| 2207 | + list_for_each_entry(pos, &head, list) { |
---|
| 2208 | + errors[n].offset = pos->offset; |
---|
| 2209 | + errors[n].length = pos->length; |
---|
| 2210 | + nfs4_stateid_copy(&errors[n].stateid, &pos->stateid); |
---|
| 2211 | + errors[n].errors[0].dev_id = pos->deviceid; |
---|
| 2212 | + errors[n].errors[0].status = pos->status; |
---|
| 2213 | + errors[n].errors[0].opnum = pos->opnum; |
---|
| 2214 | + n++; |
---|
| 2215 | + if (!list_is_last(&pos->list, &head) && |
---|
| 2216 | + n < NFS42_LAYOUTERROR_MAX) |
---|
| 2217 | + continue; |
---|
| 2218 | + if (nfs42_proc_layouterror(lseg, errors, n) < 0) |
---|
| 2219 | + break; |
---|
| 2220 | + n = 0; |
---|
| 2221 | + } |
---|
| 2222 | + kfree(errors); |
---|
| 2223 | + } |
---|
| 2224 | + ff_layout_free_ds_ioerr(&head); |
---|
| 2225 | +} |
---|
| 2226 | +#else |
---|
| 2227 | +void |
---|
| 2228 | +ff_layout_send_layouterror(struct pnfs_layout_segment *lseg) |
---|
| 2229 | +{ |
---|
| 2230 | +} |
---|
| 2231 | +#endif |
---|
2102 | 2232 | |
---|
2103 | 2233 | static int |
---|
2104 | 2234 | ff_layout_ntop4(const struct sockaddr *sap, char *buf, const size_t buflen) |
---|
.. | .. |
---|
2353 | 2483 | return 0; |
---|
2354 | 2484 | } |
---|
2355 | 2485 | |
---|
| 2486 | +static const struct pnfs_commit_ops ff_layout_commit_ops = { |
---|
| 2487 | + .setup_ds_info = ff_layout_setup_ds_info, |
---|
| 2488 | + .release_ds_info = ff_layout_release_ds_info, |
---|
| 2489 | + .mark_request_commit = pnfs_layout_mark_request_commit, |
---|
| 2490 | + .clear_request_commit = pnfs_generic_clear_request_commit, |
---|
| 2491 | + .scan_commit_lists = pnfs_generic_scan_commit_lists, |
---|
| 2492 | + .recover_commit_reqs = pnfs_generic_recover_commit_reqs, |
---|
| 2493 | + .commit_pagelist = ff_layout_commit_pagelist, |
---|
| 2494 | +}; |
---|
| 2495 | + |
---|
2356 | 2496 | static struct pnfs_layoutdriver_type flexfilelayout_type = { |
---|
2357 | 2497 | .id = LAYOUT_FLEX_FILES, |
---|
2358 | 2498 | .name = "LAYOUT_FLEX_FILES", |
---|
2359 | 2499 | .owner = THIS_MODULE, |
---|
2360 | 2500 | .flags = PNFS_LAYOUTGET_ON_OPEN, |
---|
| 2501 | + .max_layoutget_response = 4096, /* 1 page or so... */ |
---|
2361 | 2502 | .set_layoutdriver = ff_layout_set_layoutdriver, |
---|
2362 | 2503 | .alloc_layout_hdr = ff_layout_alloc_layout_hdr, |
---|
2363 | 2504 | .free_layout_hdr = ff_layout_free_layout_hdr, |
---|
.. | .. |
---|
2368 | 2509 | .pg_write_ops = &ff_layout_pg_write_ops, |
---|
2369 | 2510 | .get_ds_info = ff_layout_get_ds_info, |
---|
2370 | 2511 | .free_deviceid_node = ff_layout_free_deviceid_node, |
---|
2371 | | - .mark_request_commit = pnfs_layout_mark_request_commit, |
---|
2372 | | - .clear_request_commit = pnfs_generic_clear_request_commit, |
---|
2373 | | - .scan_commit_lists = pnfs_generic_scan_commit_lists, |
---|
2374 | | - .recover_commit_reqs = pnfs_generic_recover_commit_reqs, |
---|
2375 | | - .commit_pagelist = ff_layout_commit_pagelist, |
---|
2376 | 2512 | .read_pagelist = ff_layout_read_pagelist, |
---|
2377 | 2513 | .write_pagelist = ff_layout_write_pagelist, |
---|
2378 | 2514 | .alloc_deviceid_node = ff_layout_alloc_deviceid_node, |
---|
.. | .. |
---|
2385 | 2521 | { |
---|
2386 | 2522 | printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Registering...\n", |
---|
2387 | 2523 | __func__); |
---|
2388 | | - if (!ff_zero_group) { |
---|
2389 | | - ff_zero_group = groups_alloc(0); |
---|
2390 | | - if (!ff_zero_group) |
---|
2391 | | - return -ENOMEM; |
---|
2392 | | - } |
---|
2393 | 2524 | return pnfs_register_layoutdriver(&flexfilelayout_type); |
---|
2394 | 2525 | } |
---|
2395 | 2526 | |
---|
.. | .. |
---|
2398 | 2529 | printk(KERN_INFO "%s: NFSv4 Flexfile Layout Driver Unregistering...\n", |
---|
2399 | 2530 | __func__); |
---|
2400 | 2531 | pnfs_unregister_layoutdriver(&flexfilelayout_type); |
---|
2401 | | - if (ff_zero_group) { |
---|
2402 | | - put_group_info(ff_zero_group); |
---|
2403 | | - ff_zero_group = NULL; |
---|
2404 | | - } |
---|
2405 | 2532 | } |
---|
2406 | 2533 | |
---|
2407 | 2534 | MODULE_ALIAS("nfs-layouttype4-4"); |
---|
.. | .. |
---|
2411 | 2538 | |
---|
2412 | 2539 | module_init(nfs4flexfilelayout_init); |
---|
2413 | 2540 | module_exit(nfs4flexfilelayout_exit); |
---|
| 2541 | + |
---|
| 2542 | +module_param(io_maxretrans, ushort, 0644); |
---|
| 2543 | +MODULE_PARM_DESC(io_maxretrans, "The number of times the NFSv4.1 client " |
---|
| 2544 | + "retries an I/O request before returning an error. "); |
---|