struct nfs_pgio_mirror *pgm;
        struct nfs4_ff_layout_mirror *mirror;
        struct nfs4_pnfs_ds *ds;
-       u32 ds_idx, i;
+       u32 ds_idx;
 
 retry:
        ff_layout_pg_check_layout(pgio, req);
                goto retry;
        }
 
-       for (i = 0; i < pgio->pg_mirror_count; i++) {
-               mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i);
-               pgm = &pgio->pg_mirrors[i];
-               pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
-       }
+       mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx);
+       pgm = &pgio->pg_mirrors[0];
+       pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
 
        pgio->pg_mirror_idx = ds_idx;
 
        return 1;
 }
 
+static u32
+ff_layout_pg_set_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx)
+{
+       u32 old = desc->pg_mirror_idx;
+
+       desc->pg_mirror_idx = idx;
+       return old;
+}
+
+static struct nfs_pgio_mirror *
+ff_layout_pg_get_mirror_write(struct nfs_pageio_descriptor *desc, u32 idx)
+{
+       return &desc->pg_mirrors[idx];
+}
+
 static const struct nfs_pageio_ops ff_layout_pg_read_ops = {
        .pg_init = ff_layout_pg_init_read,
        .pg_test = pnfs_generic_pg_test,
        .pg_doio = pnfs_generic_pg_writepages,
        .pg_get_mirror_count = ff_layout_pg_get_mirror_count_write,
        .pg_cleanup = pnfs_generic_pg_cleanup,
+       .pg_get_mirror = ff_layout_pg_get_mirror_write,
+       .pg_set_mirror = ff_layout_pg_set_mirror_write,
 };
 
 static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs)
 
 static struct kmem_cache *nfs_page_cachep;
 static const struct rpc_call_ops nfs_pgio_common_ops;
 
+static struct nfs_pgio_mirror *
+nfs_pgio_get_mirror(struct nfs_pageio_descriptor *desc, u32 idx)
+{
+       if (desc->pg_ops->pg_get_mirror)
+               return desc->pg_ops->pg_get_mirror(desc, idx);
+       return &desc->pg_mirrors[0];
+}
+
 struct nfs_pgio_mirror *
 nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc)
 {
-       return &desc->pg_mirrors[desc->pg_mirror_idx];
+       return nfs_pgio_get_mirror(desc, desc->pg_mirror_idx);
 }
 EXPORT_SYMBOL_GPL(nfs_pgio_current_mirror);
 
+static u32
+nfs_pgio_set_current_mirror(struct nfs_pageio_descriptor *desc, u32 idx)
+{
+       if (desc->pg_ops->pg_set_mirror)
+               return desc->pg_ops->pg_set_mirror(desc, idx);
+       return desc->pg_mirror_idx;
+}
+
 void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
                       struct nfs_pgio_header *hdr,
                       void (*release)(struct nfs_pgio_header *hdr))
                return;
 
        for (midx = 0; midx < desc->pg_mirror_count; midx++) {
-               mirror = &desc->pg_mirrors[midx];
+               mirror = nfs_pgio_get_mirror(desc, midx);
                desc->pg_completion_ops->error_cleanup(&mirror->pg_list,
                                desc->pg_error);
        }
                        goto out_failed;
                }
 
-               desc->pg_mirror_idx = midx;
+               nfs_pgio_set_current_mirror(desc, midx);
                if (!nfs_pageio_add_request_mirror(desc, dupreq))
                        goto out_cleanup_subreq;
        }
 
-       desc->pg_mirror_idx = 0;
+       nfs_pgio_set_current_mirror(desc, 0);
        if (!nfs_pageio_add_request_mirror(desc, req))
                goto out_failed;
 
 static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc,
                                       u32 mirror_idx)
 {
-       struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[mirror_idx];
-       u32 restore_idx = desc->pg_mirror_idx;
+       struct nfs_pgio_mirror *mirror;
+       u32 restore_idx;
+
+       restore_idx = nfs_pgio_set_current_mirror(desc, mirror_idx);
+       mirror = nfs_pgio_current_mirror(desc);
 
-       desc->pg_mirror_idx = mirror_idx;
        for (;;) {
                nfs_pageio_doio(desc);
                if (desc->pg_error < 0 || !mirror->pg_recoalesce)
                if (!nfs_do_recoalesce(desc))
                        break;
        }
-       desc->pg_mirror_idx = restore_idx;
+       nfs_pgio_set_current_mirror(desc, restore_idx);
 }
 
 /*
        u32 midx;
 
        for (midx = 0; midx < desc->pg_mirror_count; midx++) {
-               mirror = &desc->pg_mirrors[midx];
+               mirror = nfs_pgio_get_mirror(desc, midx);
                if (!list_empty(&mirror->pg_list)) {
                        prev = nfs_list_entry(mirror->pg_list.prev);
                        if (index != prev->wb_index + 1) {
 
        unsigned short          wb_nio;         /* Number of I/O attempts */
 };
 
+struct nfs_pgio_mirror;
 struct nfs_pageio_descriptor;
 struct nfs_pageio_ops {
        void    (*pg_init)(struct nfs_pageio_descriptor *, struct nfs_page *);
        unsigned int    (*pg_get_mirror_count)(struct nfs_pageio_descriptor *,
                                       struct nfs_page *);
        void    (*pg_cleanup)(struct nfs_pageio_descriptor *);
+       struct nfs_pgio_mirror *
+               (*pg_get_mirror)(struct nfs_pageio_descriptor *, u32);
+       u32     (*pg_set_mirror)(struct nfs_pageio_descriptor *, u32);
 };
 
 struct nfs_rw_ops {