Commit 2444ff27 authored by Trond Myklebust's avatar Trond Myklebust

NFS/flexfiles: refactor calls to fs4_ff_layout_prepare_ds()

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: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 18c0778a
...@@ -794,6 +794,7 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg, ...@@ -794,6 +794,7 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
int *best_idx) int *best_idx)
{ {
struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg); struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);
struct nfs4_ff_layout_mirror *mirror;
struct nfs4_pnfs_ds *ds; struct nfs4_pnfs_ds *ds;
bool fail_return = false; bool fail_return = false;
int idx; int idx;
...@@ -802,7 +803,12 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg, ...@@ -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++) { for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) {
if (idx+1 == fls->mirror_array_cnt) if (idx+1 == fls->mirror_array_cnt)
fail_return = true; 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) { if (ds) {
*best_idx = idx; *best_idx = idx;
return ds; return ds;
...@@ -925,7 +931,10 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio, ...@@ -925,7 +931,10 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
goto out_mds; goto out_mds;
for (i = 0; i < pgio->pg_mirror_count; i++) { 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 (!ds) {
if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg)) if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
goto out_mds; goto out_mds;
...@@ -936,7 +945,6 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio, ...@@ -936,7 +945,6 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
goto retry; goto retry;
} }
pgm = &pgio->pg_mirrors[i]; pgm = &pgio->pg_mirrors[i];
mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i);
pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize; pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize;
} }
...@@ -1724,6 +1732,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) ...@@ -1724,6 +1732,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
struct pnfs_layout_segment *lseg = hdr->lseg; struct pnfs_layout_segment *lseg = hdr->lseg;
struct nfs4_pnfs_ds *ds; struct nfs4_pnfs_ds *ds;
struct rpc_clnt *ds_clnt; struct rpc_clnt *ds_clnt;
struct nfs4_ff_layout_mirror *mirror;
const struct cred *ds_cred; const struct cred *ds_cred;
loff_t offset = hdr->args.offset; loff_t offset = hdr->args.offset;
u32 idx = hdr->pgio_mirror_idx; u32 idx = hdr->pgio_mirror_idx;
...@@ -1734,7 +1743,8 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) ...@@ -1734,7 +1743,8 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
__func__, hdr->inode->i_ino, __func__, hdr->inode->i_ino,
hdr->args.pgbase, (size_t)hdr->args.count, offset); 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) if (!ds)
goto out_failed; goto out_failed;
...@@ -1791,13 +1801,15 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) ...@@ -1791,13 +1801,15 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
struct pnfs_layout_segment *lseg = hdr->lseg; struct pnfs_layout_segment *lseg = hdr->lseg;
struct nfs4_pnfs_ds *ds; struct nfs4_pnfs_ds *ds;
struct rpc_clnt *ds_clnt; struct rpc_clnt *ds_clnt;
struct nfs4_ff_layout_mirror *mirror;
const struct cred *ds_cred; const struct cred *ds_cred;
loff_t offset = hdr->args.offset; loff_t offset = hdr->args.offset;
int vers; int vers;
struct nfs_fh *fh; struct nfs_fh *fh;
int idx = hdr->pgio_mirror_idx; 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) if (!ds)
goto out_failed; goto out_failed;
...@@ -1870,6 +1882,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) ...@@ -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 pnfs_layout_segment *lseg = data->lseg;
struct nfs4_pnfs_ds *ds; struct nfs4_pnfs_ds *ds;
struct rpc_clnt *ds_clnt; struct rpc_clnt *ds_clnt;
struct nfs4_ff_layout_mirror *mirror;
const struct cred *ds_cred; const struct cred *ds_cred;
u32 idx; u32 idx;
int vers, ret; int vers, ret;
...@@ -1880,7 +1893,8 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) ...@@ -1880,7 +1893,8 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
goto out_err; goto out_err;
idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); 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) if (!ds)
goto out_err; goto out_err;
......
...@@ -228,7 +228,8 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg, ...@@ -228,7 +228,8 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
nfs4_stateid *stateid); nfs4_stateid *stateid);
struct nfs4_pnfs_ds * 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); bool fail_return);
struct rpc_clnt * struct rpc_clnt *
......
...@@ -391,7 +391,7 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg, ...@@ -391,7 +391,7 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
/** /**
* nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call * nfs4_ff_layout_prepare_ds - prepare a DS connection for an RPC call
* @lseg: the layout segment we're operating on * @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? * @fail_return: return layout on connect failure?
* *
* Try to prepare a DS connection to accept an RPC call. This involves * Try to prepare a DS connection to accept an RPC call. This involves
...@@ -406,26 +406,18 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg, ...@@ -406,26 +406,18 @@ nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
* Returns a pointer to a connected DS object on success or NULL on failure. * Returns a pointer to a connected DS object on success or NULL on failure.
*/ */
struct nfs4_pnfs_ds * 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) bool fail_return)
{ {
struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
struct nfs4_pnfs_ds *ds = NULL; struct nfs4_pnfs_ds *ds = NULL;
struct nfs4_deviceid_node *devid;
struct inode *ino = lseg->pls_layout->plh_inode; struct inode *ino = lseg->pls_layout->plh_inode;
struct nfs_server *s = NFS_SERVER(ino); struct nfs_server *s = NFS_SERVER(ino);
unsigned int max_payload; unsigned int max_payload;
int status; int status;
if (!ff_layout_mirror_valid(lseg, mirror, true)) { if (!ff_layout_mirror_valid(lseg, mirror, true))
pr_err_ratelimited("NFS: %s: No data server for offset index %d\n",
__func__, ds_idx);
goto out; goto out;
}
devid = &mirror->mirror_ds->id_node;
if (ff_layout_test_devid_unavailable(devid))
goto out_fail;
ds = mirror->mirror_ds->ds; ds = mirror->mirror_ds->ds;
/* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */ /* 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, ...@@ -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 /* FIXME: For now we assume the server sent only one version of NFS
* to use for the DS. * to use for the DS.
*/ */
status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, status = nfs4_pnfs_ds_connect(s, ds, &mirror->mirror_ds->id_node,
dataserver_retrans, dataserver_timeo, dataserver_retrans,
mirror->mirror_ds->ds_versions[0].version, mirror->mirror_ds->ds_versions[0].version,
mirror->mirror_ds->ds_versions[0].minor_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, ...@@ -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; mirror->mirror_ds->ds_versions[0].wsize = max_payload;
goto out; goto out;
} }
out_fail:
ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout),
mirror, lseg->pls_range.offset, mirror, lseg->pls_range.offset,
lseg->pls_range.length, NFS4ERR_NXIO, lseg->pls_range.length, NFS4ERR_NXIO,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment