Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NFSv4.1/flexfiles: RW layouts are valid only if all mirrors are valid

Unlike read layouts, the writeable layout cannot fall back to using only
one of the mirrors. It need to write to all of them.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

+28 -2
+28 -2
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 528 528 return 0; 529 529 } 530 530 531 - bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg) 531 + static bool ff_read_layout_has_available_ds(struct pnfs_layout_segment *lseg) 532 532 { 533 533 struct nfs4_ff_layout_mirror *mirror; 534 534 struct nfs4_deviceid_node *devid; 535 - int idx; 535 + u32 idx; 536 536 537 537 for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) { 538 538 mirror = FF_LAYOUT_COMP(lseg, idx); ··· 544 544 } 545 545 546 546 return false; 547 + } 548 + 549 + static bool ff_rw_layout_has_available_ds(struct pnfs_layout_segment *lseg) 550 + { 551 + struct nfs4_ff_layout_mirror *mirror; 552 + struct nfs4_deviceid_node *devid; 553 + u32 idx; 554 + 555 + for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) { 556 + mirror = FF_LAYOUT_COMP(lseg, idx); 557 + if (!mirror || !mirror->mirror_ds) 558 + return false; 559 + devid = &mirror->mirror_ds->id_node; 560 + if (ff_layout_test_devid_unavailable(devid)) 561 + return false; 562 + } 563 + 564 + return FF_LAYOUT_MIRROR_COUNT(lseg) != 0; 565 + } 566 + 567 + bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg) 568 + { 569 + if (lseg->pls_range.iomode == IOMODE_READ) 570 + return ff_read_layout_has_available_ds(lseg); 571 + /* Note: RW layout needs all mirrors available */ 572 + return ff_rw_layout_has_available_ds(lseg); 547 573 } 548 574 549 575 module_param(dataserver_retrans, uint, 0644);