[PATCH 1/4] SQUASHME pnfs-submit get layoutget stateid from layout in xdr layer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andy Adamson <andros@xxxxxxxxxx>

Set the un-initialized layout stateid from an open stateid.

This pulls the latest stateid from the layout. Fixes bug where
retry on NFS4ERR_OLD_STATEID, (and any retry) would re-use the same stateid.

Signed-off-by: Andy Adamson <andros@xxxxxxxxxx>
---
 fs/nfs/nfs4xdr.c         |    6 ++++--
 fs/nfs/pnfs.c            |   25 ++++++++++++++-----------
 fs/nfs/pnfs.h            |    1 +
 include/linux/pnfs_xdr.h |    1 -
 4 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 9a52050..d542bc2 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -54,6 +54,7 @@
 #include <linux/pnfs_xdr.h>
 #include "nfs4_fs.h"
 #include "internal.h"
+#include "pnfs.h"
 
 #define NFSDBG_FACILITY		NFSDBG_XDR
 
@@ -1797,6 +1798,7 @@ encode_layoutget(struct xdr_stream *xdr,
 		      const struct nfs4_pnfs_layoutget_arg *args,
 		      struct compound_hdr *hdr)
 {
+	nfs4_stateid stateid;
 	__be32 *p;
 
 	p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
@@ -1807,8 +1809,8 @@ encode_layoutget(struct xdr_stream *xdr,
 	p = xdr_encode_hyper(p, args->lseg.offset);
 	p = xdr_encode_hyper(p, args->lseg.length);
 	p = xdr_encode_hyper(p, args->minlength);
-	p = xdr_encode_opaque_fixed(p, &args->stateid.u.data,
-				    NFS4_STATEID_SIZE);
+	pnfs_get_layout_stateid(&stateid, NFS_I(args->inode)->layout);
+	p = xdr_encode_opaque_fixed(p, &stateid.u.data, NFS4_STATEID_SIZE);
 	*p = cpu_to_be32(args->maxcount);
 
 	dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d\n",
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index b9ada8e..9b72c00 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -465,7 +465,7 @@ pnfs_set_layout_stateid(struct pnfs_layout_type *lo,
 	write_sequnlock(&lo->seqlock);
 }
 
-static void
+void
 pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_type *lo)
 {
 	int seq;
@@ -482,18 +482,21 @@ pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_type *lo)
 }
 
 static void
-pnfs_layout_from_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
+pnfs_layout_from_open_stateid(struct pnfs_layout_type *lo,
+			      struct nfs4_state *state)
 {
 	int seq;
 
 	dprintk("--> %s\n", __func__);
 
-	do {
-		seq = read_seqbegin(&state->seqlock);
-		memcpy(dst->u.data, state->stateid.u.data,
-				sizeof(state->stateid.u.data));
-	} while (read_seqretry(&state->seqlock, seq));
-
+	write_seqlock(&lo->seqlock);
+	if (!memcmp(lo->stateid.u.data, &zero_stateid, NFS4_STATEID_SIZE))
+		do {
+			seq = read_seqbegin(&state->seqlock);
+			memcpy(lo->stateid.u.data, state->stateid.u.data,
+					sizeof(state->stateid.u.data));
+		} while (read_seqretry(&state->seqlock, seq));
+	write_sequnlock(&lo->seqlock);
 	dprintk("<-- %s\n", __func__);
 }
 
@@ -540,11 +543,11 @@ send_layoutget(struct inode *ino,
 					FMODE_READ: FMODE_WRITE);
 			BUG_ON(!ctx);
 		}
-		pnfs_layout_from_open_stateid(&lgp->args.stateid, ctx->state);
+		/* Set the layout stateid from the open stateid */
+		pnfs_layout_from_open_stateid(NFS_I(ino)->layout, ctx->state);
 		if (!oldctx)
 			put_nfs_open_context(ctx);
-	} else
-		pnfs_get_layout_stateid(&lgp->args.stateid, lo);
+	}
 
 	/* Retrieve layout information from server */
 	status = pnfs4_proc_layoutget(lgp);
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index d5dc2e2..87b6303 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -65,6 +65,7 @@ void pnfs_set_layout_stateid(struct pnfs_layout_type *lo,
 			     const nfs4_stateid *stateid);
 void pnfs_destroy_layout(struct nfs_inode *);
 void put_layout(struct inode *inode);
+void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_type *lo);
 
 #define PNFS_EXISTS_LDIO_OP(srv, opname) ((srv)->pnfs_curr_ld &&	\
 				     (srv)->pnfs_curr_ld->ld_io_ops &&	\
diff --git a/include/linux/pnfs_xdr.h b/include/linux/pnfs_xdr.h
index d3d0d78..5b8f4c3 100644
--- a/include/linux/pnfs_xdr.h
+++ b/include/linux/pnfs_xdr.h
@@ -35,7 +35,6 @@ struct nfs4_pnfs_layoutget_arg {
 	struct nfs4_pnfs_layout_segment lseg;
 	__u64 minlength;
 	__u32 maxcount;
-	nfs4_stateid stateid;
 	struct inode *inode;
 	struct nfs4_sequence_args seq_args;
 };
-- 
1.6.6

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux