NFSv4.1/flexfiles: RW layouts are valid only if all mirrors are valid
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 1 Sep 2015 09:49:44 +0000 (02:49 -0700)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 1 Sep 2015 22:12:11 +0000 (15:12 -0700)
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>
fs/nfs/flexfilelayout/flexfilelayoutdev.c

index 883d35c867788af7c7accfe301a3499f5675e65c..b6c21e9fa0026d23b984962ec3f3b66b5cb993c5 100644 (file)
@@ -528,11 +528,11 @@ int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
        return 0;
 }
 
-bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg)
+static bool ff_read_layout_has_available_ds(struct pnfs_layout_segment *lseg)
 {
        struct nfs4_ff_layout_mirror *mirror;
        struct nfs4_deviceid_node *devid;
-       int idx;
+       u32 idx;
 
        for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) {
                mirror = FF_LAYOUT_COMP(lseg, idx);
@@ -546,6 +546,32 @@ bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg)
        return false;
 }
 
+static bool ff_rw_layout_has_available_ds(struct pnfs_layout_segment *lseg)
+{
+       struct nfs4_ff_layout_mirror *mirror;
+       struct nfs4_deviceid_node *devid;
+       u32 idx;
+
+       for (idx = 0; idx < FF_LAYOUT_MIRROR_COUNT(lseg); idx++) {
+               mirror = FF_LAYOUT_COMP(lseg, idx);
+               if (!mirror || !mirror->mirror_ds)
+                       return false;
+               devid = &mirror->mirror_ds->id_node;
+               if (ff_layout_test_devid_unavailable(devid))
+                       return false;
+       }
+
+       return FF_LAYOUT_MIRROR_COUNT(lseg) != 0;
+}
+
+bool ff_layout_has_available_ds(struct pnfs_layout_segment *lseg)
+{
+       if (lseg->pls_range.iomode == IOMODE_READ)
+               return  ff_read_layout_has_available_ds(lseg);
+       /* Note: RW layout needs all mirrors available */
+       return ff_rw_layout_has_available_ds(lseg);
+}
+
 module_param(dataserver_retrans, uint, 0644);
 MODULE_PARM_DESC(dataserver_retrans, "The  number of times the NFSv4.1 client "
                        "retries a request before it attempts further "