Commit dab45f4d authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan Committed by Greg Kroah-Hartman

flexfiles: use per-mirror specified stateid for IO

[ Upstream commit bb21ce0a ]

rfc8435 says:

  For tight coupling, ffds_stateid provides the stateid to be used by
  the client to access the file.

However current implementation replaces per-mirror provided stateid with
by open or lock stateid.

Ensure that per-mirror stateid is used by ff_layout_write_prepare_v4 and
nfs4_ff_layout_prepare_ds.
Signed-off-by: default avatarTigran Mkrtchyan <tigran.mkrtchyan@desy.de>
Signed-off-by: default avatarRick Macklem <rmacklem@uoguelph.ca>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 84f49bb0
...@@ -1365,12 +1365,7 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data) ...@@ -1365,12 +1365,7 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
task)) task))
return; return;
if (ff_layout_read_prepare_common(task, hdr)) ff_layout_read_prepare_common(task, hdr);
return;
if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context,
hdr->args.lock_context, FMODE_READ) == -EIO)
rpc_exit(task, -EIO); /* lost lock, terminate I/O */
} }
static void ff_layout_read_call_done(struct rpc_task *task, void *data) static void ff_layout_read_call_done(struct rpc_task *task, void *data)
...@@ -1539,12 +1534,7 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data) ...@@ -1539,12 +1534,7 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data)
task)) task))
return; return;
if (ff_layout_write_prepare_common(task, hdr)) ff_layout_write_prepare_common(task, hdr);
return;
if (nfs4_set_rw_stateid(&hdr->args.stateid, hdr->args.context,
hdr->args.lock_context, FMODE_WRITE) == -EIO)
rpc_exit(task, -EIO); /* lost lock, terminate I/O */
} }
static void ff_layout_write_call_done(struct rpc_task *task, void *data) static void ff_layout_write_call_done(struct rpc_task *task, void *data)
...@@ -1734,6 +1724,10 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) ...@@ -1734,6 +1724,10 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
fh = nfs4_ff_layout_select_ds_fh(lseg, idx); fh = nfs4_ff_layout_select_ds_fh(lseg, idx);
if (fh) if (fh)
hdr->args.fh = fh; hdr->args.fh = fh;
if (!nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid))
goto out_failed;
/* /*
* Note that if we ever decide to split across DSes, * Note that if we ever decide to split across DSes,
* then we may need to handle dense-like offsets. * then we may need to handle dense-like offsets.
...@@ -1796,6 +1790,9 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) ...@@ -1796,6 +1790,9 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
if (fh) if (fh)
hdr->args.fh = fh; hdr->args.fh = fh;
if (!nfs4_ff_layout_select_ds_stateid(lseg, idx, &hdr->args.stateid))
goto out_failed;
/* /*
* Note that if we ever decide to split across DSes, * Note that if we ever decide to split across DSes,
* then we may need to handle dense-like offsets. * then we may need to handle dense-like offsets.
......
...@@ -214,6 +214,10 @@ unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo, ...@@ -214,6 +214,10 @@ unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo,
unsigned int maxnum); unsigned int maxnum);
struct nfs_fh * struct nfs_fh *
nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx); nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx);
int
nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
u32 mirror_idx,
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, u32 ds_idx,
......
...@@ -369,6 +369,25 @@ nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx) ...@@ -369,6 +369,25 @@ nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx)
return fh; return fh;
} }
int
nfs4_ff_layout_select_ds_stateid(struct pnfs_layout_segment *lseg,
u32 mirror_idx,
nfs4_stateid *stateid)
{
struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, mirror_idx);
if (!ff_layout_mirror_valid(lseg, mirror, false)) {
pr_err_ratelimited("NFS: %s: No data server for mirror offset index %d\n",
__func__, mirror_idx);
goto out;
}
nfs4_stateid_copy(stateid, &mirror->stateid);
return 1;
out:
return 0;
}
/** /**
* 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
......
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