Skip to contentSkip to conversation

pnfs-submit use latest layout stateid

PATCH New [email protected] 1 participant 5 messages Jul 15, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover pnfs-submit use latest layout stateid

Set the layout stateid from an open stateid in layoutget iff the layout stateid is zero.

Get the layout stateid from the layout in the xdr layer for layoutget and layoutreturn so that the latest stateid is used. Fixes a bug where a retry due to NFS4ERR_OLD_STATEID (and any retry) will use the old stateid.

0001-SQUASHME-pnfs-submit-get-layoutget-stateid-from-layo.patch 0002-SQUASHME-pnfs-submit-get-layoutreturn-stateid-from-l.patch

Remove unnecessary fields.

0003-SQUASHME-pnfs-submit-remove-unnecessary-layoutreturn.patch 0004-SQUASHME-pnfs-submit-remove-unnecessary-layoutget-fi.patch

Tested

CONFIG_NFS_V4_1 set

Connectathon passes

-->Andy

#1 lore raw

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

From: Andy Adamson <[email protected]>

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.

---
 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(-)
fs/nfs/nfs4xdr.c +4 -2
index 9a52050..d542bc2 100644
@@ -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",
fs/nfs/pnfs.c +14 -11
index b9ada8e..9b72c00 100644
@@ -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);
fs/nfs/pnfs.h +1 -0
index d5dc2e2..87b6303 100644
@@ -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 &&	\
include/linux/pnfs_xdr.h +0 -1
index d3d0d78..5b8f4c3 100644
@@ -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;
 };
Signature · 1 line
1.6.6
#2 lore raw

PATCH 2/4 SQUASHME pnfs-submit get layoutreturn stateid from layout in xdr layer

From: Andy Adamson <[email protected]>

So as to use the latest stateid, and to fix the bug where a replay on NFS4ERR_OLD_STATEID (and all replays) would use the old stateid.

---
 fs/nfs/nfs4xdr.c         |    4 +++-
 fs/nfs/pnfs.c            |    1 -
 include/linux/pnfs_xdr.h |    1 -
 3 files changed, 3 insertions(+), 3 deletions(-)
fs/nfs/nfs4xdr.c +3 -1
index d542bc2..f6e1d49 100644
@@ -1867,6 +1867,7 @@ encode_layoutreturn(struct xdr_stream *xdr,
 		    const struct nfs4_pnfs_layoutreturn_arg *args,
 		    struct compound_hdr *hdr)
 {
+	nfs4_stateid stateid;
 	__be32 *p;
 
 	p = reserve_space(xdr, 20);
@@ -1879,7 +1880,8 @@ encode_layoutreturn(struct xdr_stream *xdr,
 		p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE);
 		p = xdr_encode_hyper(p, args->lseg.offset);
 		p = xdr_encode_hyper(p, args->lseg.length);
-		p = xdr_encode_opaque_fixed(p, &args->stateid.u.data,
+		pnfs_get_layout_stateid(&stateid, NFS_I(args->inode)->layout);
+		p = xdr_encode_opaque_fixed(p, &stateid.u.data,
 					    NFS4_STATEID_SIZE);
 		p = reserve_space(xdr, 4);
 		*p = cpu_to_be32(0);
fs/nfs/pnfs.c +0 -1
index 9b72c00..ea508bf 100644
@@ -683,7 +683,6 @@ return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range,
 	lrp->args.lseg = *range;
 	lrp->args.inode = ino;
 	lrp->lo = lo;
-	pnfs_get_layout_stateid(&lrp->args.stateid, lo);
 
 	status = pnfs4_proc_layoutreturn(lrp, wait);
 out:
include/linux/pnfs_xdr.h +0 -1
index 5b8f4c3..185fade 100644
@@ -94,7 +94,6 @@ struct nfs4_pnfs_layoutreturn_arg {
 	__u32	layout_type;
 	__u32	return_type;
 	struct nfs4_pnfs_layout_segment lseg;
-	nfs4_stateid stateid;
 	struct inode *inode;
 	struct nfs4_sequence_args seq_args;
 };
Signature · 1 line
1.6.6
#3 lore raw

PATCH 3/4 SQUASHME pnfs-submit remove unnecessary layoutreturn field

From: Andy Adamson <[email protected]>

Don't need both an inode and a pnfs_layout_type field.

---
 fs/nfs/callback_proc.c   |    1 -
 fs/nfs/nfs4proc.c        |    9 +++++----
 fs/nfs/pnfs.c            |    1 -
 include/linux/pnfs_xdr.h |    1 -
 4 files changed, 5 insertions(+), 7 deletions(-)
fs/nfs/callback_proc.c +0 -1
index d999ea8..e2ea2be 100644
@@ -274,7 +274,6 @@ static int pnfs_recall_layout(void *data)
 	lrp->args.return_type = rl.cbl_recall_type;
 	lrp->args.lseg = rl.cbl_seg;
 	lrp->args.inode = inode;
-	lrp->lo = NULL;
 	pnfs4_proc_layoutreturn(lrp, true);
 
 out:
fs/nfs/nfs4proc.c +5 -4
index 288025e..ebe1b49 100644
@@ -5660,14 +5660,15 @@ static void nfs4_pnfs_layoutreturn_done(struct rpc_task *task, void *calldata)
 static void nfs4_pnfs_layoutreturn_release(void *calldata)
 {
 	struct nfs4_pnfs_layoutreturn *lrp = calldata;
+	struct pnfs_layout_type *lo = NFS_I(lrp->args.inode)->layout;
 
 	dprintk("--> %s return_type %d lo %p\n", __func__,
-		lrp->args.return_type, lrp->lo);
+		lrp->args.return_type, lo);
 
-	if (lrp->lo && (lrp->args.return_type == RETURN_FILE)) {
+	if (lrp->args.return_type == RETURN_FILE) {
 		if (!lrp->res.lrs_present)
-			pnfs_set_layout_stateid(lrp->lo, &zero_stateid);
-		pnfs_layout_release(lrp->lo, &lrp->args.lseg);
+			pnfs_set_layout_stateid(lo, &zero_stateid);
+		pnfs_layout_release(lo, &lrp->args.lseg);
 	}
 	kfree(calldata);
 	dprintk("<-- %s\n", __func__);
fs/nfs/pnfs.c +0 -1
index ea508bf..edcbe46 100644
@@ -682,7 +682,6 @@ return_layout(struct inode *ino, struct nfs4_pnfs_layout_segment *range,
 	lrp->args.return_type = type;
 	lrp->args.lseg = *range;
 	lrp->args.inode = ino;
-	lrp->lo = lo;
 
 	status = pnfs4_proc_layoutreturn(lrp, wait);
 out:
include/linux/pnfs_xdr.h +0 -1
index 185fade..f9c9950 100644
@@ -105,7 +105,6 @@ struct nfs4_pnfs_layoutreturn_res {
 };
 
 struct nfs4_pnfs_layoutreturn {
-	struct pnfs_layout_type *lo;
 	struct nfs4_pnfs_layoutreturn_arg args;
 	struct nfs4_pnfs_layoutreturn_res res;
 	struct rpc_cred *cred;
Signature · 1 line
1.6.6
#4 lore raw

PATCH 4/4 SQUASHME pnfs-submit remove unnecessary layoutget field

From: Andy Adamson <[email protected]>

Don't need both an inode and a pnfs_layout_type field.

---
 fs/nfs/nfs4proc.c        |    2 +-
 fs/nfs/pnfs.c            |    5 ++---
 include/linux/pnfs_xdr.h |    1 -
 3 files changed, 3 insertions(+), 5 deletions(-)
fs/nfs/nfs4proc.c +1 -1
index ebe1b49..4aa4fc1 100644
@@ -5448,7 +5448,7 @@ static void nfs4_pnfs_layoutget_release(void *calldata)
 	struct nfs4_pnfs_layoutget *lgp = calldata;
 
 	dprintk("--> %s\n", __func__);
-	pnfs_layout_release(lgp->lo, NULL);
+	pnfs_layout_release(NFS_I(lgp->args.inode)->layout, NULL);
 	if (lgp->res.layout.buf != NULL)
 		free_page((unsigned long) lgp->res.layout.buf);
 	kfree(calldata);
fs/nfs/pnfs.c +2 -3
index edcbe46..7a30eb0 100644
@@ -524,7 +524,6 @@ send_layoutget(struct inode *ino,
 		pnfs_layout_release(lo, NULL);
 		return -ENOMEM;
 	}
-	lgp->lo = lo;
 	lgp->args.minlength = NFS4_MAX_UINT64;
 	lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
 	lgp->args.lseg.iomode = range->iomode;
@@ -1003,7 +1002,7 @@ void
 pnfs_get_layout_done(struct nfs4_pnfs_layoutget *lgp, int rpc_status)
 {
 	struct pnfs_layout_segment *lseg = NULL;
-	struct nfs_inode *nfsi = PNFS_NFS_INODE(lgp->lo);
+	struct nfs_inode *nfsi = NFS_I(lgp->args.inode);
 	time_t suspend = 0;
 
 	dprintk("-->%s\n", __func__);
@@ -1106,7 +1105,7 @@ out:
 int
 pnfs_layout_process(struct nfs4_pnfs_layoutget *lgp)
 {
-	struct pnfs_layout_type *lo = lgp->lo;
+	struct pnfs_layout_type *lo = NFS_I(lgp->args.inode)->layout;
 	struct nfs4_pnfs_layoutget_res *res = &lgp->res;
 	struct pnfs_layout_segment *lseg;
 	struct inode *ino = PNFS_INODE(lo);
include/linux/pnfs_xdr.h +0 -1
index f9c9950..c9a01b3 100644
@@ -49,7 +49,6 @@ struct nfs4_pnfs_layoutget_res {
 };
 
 struct nfs4_pnfs_layoutget {
-	struct pnfs_layout_type *lo;
 	struct nfs4_pnfs_layoutget_arg args;
 	struct nfs4_pnfs_layoutget_res res;
 	struct pnfs_layout_segment **lsegpp;
Signature · 1 line
1.6.6