From: Tigran Mkrtchyan <tigran.mkrtch...@desy.de>

[ Upstream commit bb21ce0ad227b69ec0f83279297ee44232105d96 ]

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: Tigran Mkrtchyan <tigran.mkrtch...@desy.de>
Signed-off-by: Rick Macklem <rmack...@uoguelph.ca>
Signed-off-by: Trond Myklebust <trond.mykleb...@hammerspace.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 fs/nfs/flexfilelayout/flexfilelayout.c    | 21 +++++++++------------
 fs/nfs/flexfilelayout/flexfilelayout.h    |  4 ++++
 fs/nfs/flexfilelayout/flexfilelayoutdev.c | 19 +++++++++++++++++++
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c 
b/fs/nfs/flexfilelayout/flexfilelayout.c
index cae43333ef16..86ac2c5b93fe 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -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.
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h 
b/fs/nfs/flexfilelayout/flexfilelayout.h
index 411798346e48..de50a342d5a5 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -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,
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c 
b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 59aa04976331..a8df2f496898 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -370,6 +370,25 @@ nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment 
*lseg, u32 mirror_idx)
        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
-- 
2.17.1

Reply via email to