NFS/flexfiles: refactor calls to fs4_ff_layout_prepare_ds()
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 14 Feb 2019 18:45:45 +0000 (13:45 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 2 Mar 2019 03:37:37 +0000 (22:37 -0500)
While we may want to skip attempting to connect to a downed mirror
when we're deciding which mirror to select for a read, we do not
want to do so once we've committed to attempting the I/O in
ff_layout_read/write_pagelist(), or ff_layout_initiate_commit()

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/flexfilelayout/flexfilelayout.h
fs/nfs/flexfilelayout/flexfilelayoutdev.c

index eb86da30d4b922d6104479f188f0c6f8d056a67a..0134bcac46a7e1818f76f482ff30811645e66000 100644 (file)
@@ -794,6 +794,7 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
                                  int *best_idx)
 {
        struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
+       struct nfs4_ff_layout_mirror *mirror;
        struct nfs4_pnfs_ds *ds;
        bool fail_return = false;
        int idx;
@@ -802,7 +803,12 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
        for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) {
                if (idx+1 == fls->mirror_array_cnt)
                        fail_return = true;
-               ds = nfs4_ff_layout_prepare_ds(lseg, idx, fail_return);
+
+               mirror = FF_LAYOUT_COMP(lseg, idx);
+               if (ff_layout_test_devid_unavailable(&mirror->mirror_ds->id_node))
+                       continue;
+
+               ds = nfs4_ff_layout_prepare_ds(lseg, mirror, fail_return);
                if (ds) {
                        *best_idx = idx;
                        return ds;
@@ -925,7 +931,10 @@ retry:
                goto out_mds;
 
        for (i = 0; i < pgio->pg_mirror_count; i++) {
-               ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, i, true);
+               mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i);
+               if (ff_layout_test_devid_unavailable(&mirror->mirror_ds->id_node))
+                       continue;
+               ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, mirror, true);
                if (!ds) {
                        if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
                                goto out_mds;
@@ -936,7 +945,6 @@ retry:
                        goto retry;
                }
                pgm = &pgio->pg_mirrors[i];
-               mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i);
                pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize;
        }
 
@@ -1724,6 +1732,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
        struct pnfs_layout_segment *lseg = hdr->lseg;
        struct nfs4_pnfs_ds *ds;
        struct rpc_clnt *ds_clnt;
+       struct nfs4_ff_layout_mirror *mirror;
        const struct cred *ds_cred;
        loff_t offset = hdr->args.offset;
        u32 idx = hdr->pgio_mirror_idx;
@@ -1734,7 +1743,8 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
                __func__, hdr->inode->i_ino,
                hdr->args.pgbase, (size_t)hdr->args.count, offset);
 
-       ds = nfs4_ff_layout_prepare_ds(lseg, idx, false);
+       mirror = FF_LAYOUT_COMP(lseg, idx);
+       ds = nfs4_ff_layout_prepare_ds(lseg, mirror, false);
        if (!ds)
                goto out_failed;
 
@@ -1791,13 +1801,15 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
        struct pnfs_layout_segment *lseg = hdr->lseg;
        struct nfs4_pnfs_ds *ds;
        struct rpc_clnt *ds_clnt;
+       struct nfs4_ff_layout_mirror *mirror;
        const struct cred *ds_cred;
        loff_t offset = hdr->args.offset;
        int vers;
        struct nfs_fh *fh;
        int idx = hdr->pgio_mirror_idx;
 
-       ds = nfs4_ff_layout_prepare_ds(lseg, idx, true);
+       mirror = FF_LAYOUT_COMP(lseg, idx);
+       ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true);
        if (!ds)
                goto out_failed;
 
@@ -1870,6 +1882,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
        struct pnfs_layout_segment *lseg = data->lseg;
        struct nfs4_pnfs_ds *ds;
        struct rpc_clnt *ds_clnt;
+       struct nfs4_ff_layout_mirror *mirror;
        const struct cred *ds_cred;
        u32 idx;
        int vers, ret;
@@ -1880,7 +1893,8 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
                goto out_err;
 
        idx = calc_ds_index_from_commit(lseg, data->ds_commit_index);
-       ds = nfs4_ff_layout_prepare_ds(lseg, idx, true);
+       mirror = FF_LAYOUT_COMP(lseg, idx);
+       ds = nfs4_ff_layout_prepare_ds(lseg, mirror, true);
        if (!ds)
                goto out_err;
 
index 31a62820a5c66c3a983443c5dd75316b656884cb..93508112486a7b80e7fc31e8e41e9db3993973cc 100644 (file)
@@ -228,7 +228,8 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
                                nfs4_stateid *stateid);
 
 struct nfs4_pnfs_ds *
-nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
+nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
+                         struct nfs4_ff_layout_mirror *mirror,
                          bool fail_return);
 
 struct rpc_clnt *
index c174f23afc6d440b517302ad0ca5c06ef420d029..f9a13e1fb1a8f50cc9bb3d71be4f626976e1e1e7 100644 (file)
@@ -391,7 +391,7 @@ out:
 /**
  * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call
  * @lseg: the layout segment we're operating on
- * @ds_idx: index of the DS to use
+ * @mirror: layout mirror describing the DS to use
  * @fail_return: return layout on connect failure?
  *
  * Try to prepare a DS connection to accept an RPC call. This involves
@@ -406,26 +406,18 @@ out:
  * Returns a pointer to a connected DS object on success or NULL on failure.
  */
 struct nfs4_pnfs_ds *
-nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
+nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg,
+                         struct nfs4_ff_layout_mirror *mirror,
                          bool fail_return)
 {
-       struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
        struct nfs4_pnfs_ds *ds = NULL;
-       struct nfs4_deviceid_node *devid;
        struct inode *ino = lseg->pls_layout->plh_inode;
        struct nfs_server *s = NFS_SERVER(ino);
        unsigned int max_payload;
        int status;
 
-       if (!ff_layout_mirror_valid(lseg, mirror, true)) {
-               pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
-                       __func__, ds_idx);
+       if (!ff_layout_mirror_valid(lseg, mirror, true))
                goto out;
-       }
-
-       devid = &mirror->mirror_ds->id_node;
-       if (ff_layout_test_devid_unavailable(devid))
-               goto out_fail;
 
        ds = mirror->mirror_ds->ds;
        /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
@@ -436,8 +428,8 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
        /* FIXME: For now we assume the server sent only one version of NFS
         * to use for the DS.
         */
-       status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo,
-                            dataserver_retrans,
+       status = nfs4_pnfs_ds_connect(s, ds, &mirror->mirror_ds->id_node,
+                            dataserver_timeo, dataserver_retrans,
                             mirror->mirror_ds->ds_versions[0].version,
                             mirror->mirror_ds->ds_versions[0].minor_version);
 
@@ -452,7 +444,6 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
                        mirror->mirror_ds->ds_versions[0].wsize = max_payload;
                goto out;
        }
-out_fail:
        ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
                                 mirror, lseg->pls_range.offset,
                                 lseg->pls_range.length, NFS4ERR_NXIO,