Commit bb21ce0a authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan Committed by Trond Myklebust
Browse files

flexfiles: use per-mirror specified stateid for IO



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>
parent 99f2c555
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -1361,12 +1361,7 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
				task))
		return;

	if (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 */
	ff_layout_read_prepare_common(task, hdr);
}

static void ff_layout_read_call_done(struct rpc_task *task, void *data)
@@ -1542,12 +1537,7 @@ static void ff_layout_write_prepare_v4(struct rpc_task *task, void *data)
				task))
		return;

	if (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 */
	ff_layout_write_prepare_common(task, hdr);
}

static void ff_layout_write_call_done(struct rpc_task *task, void *data)
@@ -1742,6 +1732,10 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
	fh = nfs4_ff_layout_select_ds_fh(lseg, idx);
	if (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,
	 * then we may need to handle dense-like offsets.
@@ -1804,6 +1798,9 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
	if (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,
	 * then we may need to handle dense-like offsets.
+4 −0
Original line number Diff line number Diff line
@@ -215,6 +215,10 @@ unsigned int ff_layout_fetch_ds_ioerr(struct pnfs_layout_hdr *lo,
		unsigned int maxnum);
struct nfs_fh *
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 *
nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
+19 −0
Original line number Diff line number Diff line
@@ -370,6 +370,25 @@ out:
	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
 * @lseg: the layout segment we're operating on