All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders
@ 2010-05-17  2:45 Chuck Lever
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:45 UTC (permalink / raw)
  To: linux-nfs

This series backports patches I did 3 years ago that update the NFS
client's NFSv2 XDR encoders and decoders to use xdr_stream style
marshalling, similar to NFSv4.  The immediate advantage is better
bounds checking during marshalling and unmarshalling.

I've already done the kernel's MNT client, lockd's NSM client, and
the kernel's rpcbind client.  Eventually, we should convert NFSv3 and
NLM to use this style of marshalling XDR so that we can streamline
call_encode() and call_decode().

---

Chuck Lever (24):
      NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones
      NFS: Decode NFSv2 statfs reply using an xdr_stream
      NFS: Decode NFSv2 readdir reply using an xdr_stream
      NFS: Decode NFSv2 write reply using an xdr_stream
      NFS: Decode NFSv2 read reply using an xdr_stream
      NFS: Decode NFSv2 readlink reply using an xdr_stream
      NFS: Decode NFSv2 dirop reply using an xdr_stream
      NFS: Decode NFSv2 attrstat reply using an xdr_stream
      NFS: Decode NFSv2 stat reply using an xdr_stream
      NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()
      NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones
      NFS: Encode NFSv2 readdir argument using an xdr_stream
      NFS: Encode NFSv2 symlink argument using an xdr_stream
      NFS: Encode NFSv2 link argument using an xdr_stream
      NFS: Encode NFSv2 rename argument using an xdr_stream
      NFS: Encode NFSv2 create argument using an xdr_stream
      NFS: Encode NFSv2 write argument using an xdr_stream
      NFS: Encode NFSv2 read argument using an xdr_stream
      NFS: Encode NFSv2 readlink argument using an xdr_stream
      NFS: Encode dirop argument using an xdr_stream
      NFS: Encode v2 setattr argument using an xdr_stream
      NFS: Encode NFSv2 fhandle argument using an xdr_stream
      NFS: Introduce XDR helpers for basic NFSv2 data types
      SUNRPC: Refactor logic to NUL-terminate strings in pages


 fs/nfs/internal.h          |    2 
 fs/nfs/nfs2xdr.c           | 1169 +++++++++++++++++++++++++++++---------------
 fs/nfs/nfs3xdr.c           |    6 
 fs/nfs/nfs4xdr.c           |    5 
 include/linux/sunrpc/xdr.h |    1 
 net/sunrpc/xdr.c           |   17 +
 6 files changed, 779 insertions(+), 421 deletions(-)

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/24] SUNRPC: Refactor logic to NUL-terminate strings in pages
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
@ 2010-05-17  2:45   ` Chuck Lever
  2010-05-17  2:45   ` [PATCH 02/24] NFS: Introduce XDR helpers for basic NFSv2 data types Chuck Lever
                     ` (23 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:45 UTC (permalink / raw)
  To: linux-nfs

Clean up: Introduce a helper to '\0'-terminate XDR strings
that are placed in a page in the page cache.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c           |    6 +-----
 fs/nfs/nfs3xdr.c           |    6 +-----
 fs/nfs/nfs4xdr.c           |    5 +----
 include/linux/sunrpc/xdr.h |    1 +
 net/sunrpc/xdr.c           |   17 +++++++++++++++++
 5 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 81cf142..279883c 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -597,7 +597,6 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
 	struct kvec *iov = rcvbuf->head;
 	size_t hdrlen;
 	u32 len, recvd;
-	char	*kaddr;
 	int	status;
 
 	if ((status = ntohl(*p++)))
@@ -624,10 +623,7 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
 		return -EIO;
 	}
 
-	/* NULL terminate the string we got */
-	kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
-	kaddr[len+rcvbuf->page_base] = '\0';
-	kunmap_atomic(kaddr, KM_USER0);
+	xdr_terminate_string(rcvbuf, len);
 	return 0;
 }
 
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 56a86f6..cb2eb1f 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -824,7 +824,6 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 	struct kvec *iov = rcvbuf->head;
 	size_t hdrlen;
 	u32 len, recvd;
-	char	*kaddr;
 	int	status;
 
 	status = ntohl(*p++);
@@ -857,10 +856,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 		return -EIO;
 	}
 
-	/* NULL terminate the string we got */
-	kaddr = (char*)kmap_atomic(rcvbuf->pages[0], KM_USER0);
-	kaddr[len+rcvbuf->page_base] = '\0';
-	kunmap_atomic(kaddr, KM_USER0);
+	xdr_terminate_string(rcvbuf, len);
 	return 0;
 }
 
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 38f3b58..ab18790 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4250,7 +4250,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
 	size_t hdrlen;
 	u32 len, recvd;
 	__be32 *p;
-	char *kaddr;
 	int status;
 
 	status = decode_op_hdr(xdr, OP_READLINK);
@@ -4281,9 +4280,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
 	 * and and null-terminate the text (the VFS expects
 	 * null-termination).
 	 */
-	kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
-	kaddr[len+rcvbuf->page_base] = '\0';
-	kunmap_atomic(kaddr, KM_USER0);
+	xdr_terminate_string(rcvbuf, len);
 	return 0;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 35cf2e8..8c1dcbb 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -108,6 +108,7 @@ void	xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
 			 unsigned int);
 void	xdr_inline_pages(struct xdr_buf *, unsigned int,
 			 struct page **, unsigned int, unsigned int);
+void	xdr_terminate_string(struct xdr_buf *, const u32);
 
 static inline __be32 *xdr_encode_array(__be32 *p, const void *s, unsigned int len)
 {
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 2763fde..a6ce4f4 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -111,6 +111,23 @@ xdr_decode_string_inplace(__be32 *p, char **sp,
 }
 EXPORT_SYMBOL_GPL(xdr_decode_string_inplace);
 
+/**
+ * xdr_terminate_string - '\0'-terminate a string residing in an xdr_buf
+ * @buf: XDR buffer where string resides
+ * @len: length of string, in bytes
+ *
+ */
+void
+xdr_terminate_string(struct xdr_buf *buf, const u32 len)
+{
+	char *kaddr;
+
+	kaddr = kmap_atomic(buf->pages[0], KM_USER0);
+	kaddr[buf->page_base + len] = '\0';
+	kunmap_atomic(kaddr, KM_USER0);
+}
+EXPORT_SYMBOL(xdr_terminate_string);
+
 void
 xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base,
 		 unsigned int len)


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/24] NFS: Introduce XDR helpers for basic NFSv2 data types
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
  2010-05-17  2:45   ` [PATCH 01/24] SUNRPC: Refactor logic to NUL-terminate strings in pages Chuck Lever
@ 2010-05-17  2:45   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 03/24] NFS: Encode NFSv2 fhandle argument using an xdr_stream Chuck Lever
                     ` (22 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:45 UTC (permalink / raw)
  To: linux-nfs

Introduce a new set of XDR encoding/decoding functions for NFSv2 basic
types that operate on xdr_streams.  Use coding style similar to what's
in fs/nfs/nfs4xdr.c.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |  342 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 342 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 279883c..9d5159f 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -3,6 +3,11 @@
  *
  * XDR functions to encode/decode NFS RPC arguments and results.
  *
+ * NFSv2 argument and result types are defined in section 2.2 of
+ * RFC 1094: "NFS: Network File System Protocol Specification".
+ * Basic data types are defined in section 2.3 of RFC 1094.
+ *
+ *
  * Copyright (C) 1992, 1993, 1994  Rick Sladkey
  * Copyright (C) 1996 Olaf Kirch
  * 04 Aug 1998  Ion Badulescu <ionut-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
@@ -61,6 +66,343 @@
 #define NFS_readdirres_sz	(1)
 #define NFS_statfsres_sz	(1+NFS_info_sz)
 
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+{
+	dprintk("NFS: %s: prematurely hit end of receive buffer. "
+		"Remaining buffer length is %tu workds.\n",
+		func, xdr->end - xdr->p);
+}
+
+/*
+ * Encode/decode NFSv2 basic data types
+ *
+ * Not all basic data types have their own encoding and decoding
+ * functions.  For run-time efficiency, some data types are encoded
+ * or decoded inline.
+ */
+
+/*
+ * 2.3.1.  stat
+ *
+ *	enum stat {
+ *		NFS_OK = 0,
+ *		...
+ *	}
+ */
+static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, 4);
+	if (unlikely(p == NULL)) {
+		print_overflow_msg(__func__, xdr);
+		return -EIO;
+	}
+	*status = be32_to_cpup(p);
+	return 0;
+}
+
+/*
+ * 2.3.3.  fhandle
+ *
+ *	typedef opaque fhandle[FHSIZE];
+ */
+static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
+{
+	__be32 *p;
+
+	BUG_ON(unlikely(fh->size != NFS2_FHSIZE));
+	p = xdr_reserve_space(xdr, NFS2_FHSIZE);
+	BUG_ON(unlikely(p == NULL));
+	xdr_encode_opaque_fixed(p, &fh->data, NFS2_FHSIZE);
+}
+
+static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
+{
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, NFS2_FHSIZE);
+	if (unlikely(p == NULL)) {
+		print_overflow_msg(__func__, xdr);
+		return -EIO;
+	}
+	memcpy(&fh->data, p, NFS2_FHSIZE);
+	fh->size = NFS2_FHSIZE;
+	return 0;
+}
+
+/*
+ * 2.3.4.  timeval
+ *
+ *	struct timeval {
+ *		unsigned int seconds;
+ *		unsigned int useconds;
+ *	};
+ */
+static void encode_timeval(struct xdr_stream *xdr, const struct timespec *timep)
+{
+	__be32 *p;
+	u32 usec;
+
+	p = xdr_reserve_space(xdr, 8);
+	BUG_ON(unlikely(p == NULL));
+	usec = timep->tv_nsec ? (timep->tv_nsec / NSEC_PER_USEC) : 0;
+	*p++ = cpu_to_be32(timep->tv_sec);
+	*p = cpu_to_be32(usec);
+}
+
+/*
+ * Passing the invalid value useconds=1000000 is a Sun convention
+ * for "set to current server time".  It's needed to make
+ * permissions checks for the "touch" program across v2 mounts to
+ * Solaris and Irix servers work correctly.  Note that this is not
+ * discussed in RFC 1094; see description of sattr in section 6.1
+ * of "NFS Illustrated" by Brent Callaghan, Addison-Wesley,
+ * ISBN 0-201-32750-5
+ */
+static void encode_current_server_timeval(struct xdr_stream *xdr,
+					  const struct timespec *timep)
+{
+	__be32 *p;
+
+	p = xdr_reserve_space(xdr, 8);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(timep->tv_sec);
+	*p = cpu_to_be32(1000000);
+}
+
+/*
+ * 2.3.5.  fattr
+ *
+ *	struct fattr {
+ *		ftype		type;
+ *		unsigned int	mode;
+ *		unsigned int	nlink;
+ *		unsigned int	uid;
+ *		unsigned int	gid;
+ *		unsigned int	size;
+ *		unsigned int	blocksize;
+ *		unsigned int	rdev;
+ *		unsigned int	blocks;
+ *		unsigned int	fsid;
+ *		unsigned int	fileid;
+ *		timeval		atime;
+ *		timeval		mtime;
+ *		timeval		ctime;
+ *	};
+ *
+ */
+static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
+{
+	u32 rdev, type;
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
+	if (unlikely(p == NULL)) {
+		print_overflow_msg(__func__, xdr);
+		return -EIO;
+	}
+
+	fattr->valid |= NFS_ATTR_FATTR;
+
+	type			= be32_to_cpup(p++);	/* 2.3.2. ftype */
+	if (unlikely(type > NF2FIFO))
+		type = NFBAD;
+
+	fattr->mode		= be32_to_cpup(p++);
+	fattr->nlink		= be32_to_cpup(p++);
+	fattr->uid		= be32_to_cpup(p++);
+	fattr->gid		= be32_to_cpup(p++);
+	fattr->size		= be32_to_cpup(p++);
+	fattr->du.nfs2.blocksize = be32_to_cpup(p++);
+	rdev			= be32_to_cpup(p++);
+	fattr->rdev		= new_decode_dev(rdev);
+	fattr->du.nfs2.blocks	= be32_to_cpup(p++);
+	fattr->fsid.major	= be32_to_cpup(p++);
+	fattr->fsid.minor	= 0;
+	fattr->fileid		= be32_to_cpup(p++);
+
+	/* 2.3.4. timeval */
+	fattr->atime.tv_sec	= be32_to_cpup(p++);
+	fattr->atime.tv_nsec	= be32_to_cpup(p++) * NSEC_PER_USEC;
+
+	/* 2.3.4. timeval */
+	fattr->mtime.tv_sec	= be32_to_cpup(p++);
+	fattr->mtime.tv_nsec	= be32_to_cpup(p++) * NSEC_PER_USEC;
+
+	/* 2.3.4. timeval */
+	fattr->ctime.tv_sec	= be32_to_cpup(p++);
+	fattr->ctime.tv_nsec	= be32_to_cpup(p++) * NSEC_PER_USEC;
+
+	/*
+	 * RFC 1094 section 2.3.2 suggests that NF2SOCK and NF2FIFO
+	 * are not supported by version 2 of the protocol.
+	 */
+	if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
+		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
+		fattr->rdev = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * 2.3.6.  sattr
+ *
+ *	struct sattr {
+ *		unsigned int	mode;
+ *		unsigned int	uid;
+ *		unsigned int	gid;
+ *		unsigned int	size;
+ *		timeval		atime;
+ *		timeval		mtime;
+ *	};
+ */
+
+#define NFS2_SATTR_NOT_SET	(0xffffffff)
+
+static void encode_time_not_set(struct xdr_stream *xdr)
+{
+	__be32 *p;
+
+	p = xdr_reserve_space(xdr, 8);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+	*p = cpu_to_be32(NFS2_SATTR_NOT_SET);
+}
+
+static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
+{
+	unsigned int valid = attr->ia_valid;
+	__be32 *p;
+
+	p = xdr_reserve_space(xdr, 16);
+	BUG_ON(unlikely(p == NULL));
+	if (valid & ATTR_MODE)
+		*p++ = cpu_to_be32(attr->ia_mode);
+	else
+		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+	if (valid & ATTR_UID)
+		*p++ = cpu_to_be32(attr->ia_uid);
+	else
+		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+	if (valid & ATTR_GID)
+		*p++ = cpu_to_be32(attr->ia_gid);
+	else
+		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+	if (valid & ATTR_SIZE)
+		*p++ = cpu_to_be32((u32)attr->ia_size);
+	else
+		*p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
+
+	if (valid & ATTR_ATIME_SET)
+		encode_timeval(xdr, &attr->ia_atime);
+	else if (valid & ATTR_ATIME)
+		encode_current_server_timeval(xdr, &attr->ia_atime);
+	else
+		encode_time_not_set(xdr);
+	if (valid & ATTR_MTIME_SET)
+		encode_timeval(xdr, &attr->ia_mtime);
+	else if (valid & ATTR_MTIME)
+		encode_current_server_timeval(xdr, &attr->ia_mtime);
+	else
+		encode_time_not_set(xdr);
+}
+
+/*
+ * 2.3.7.  filename
+ *
+ *	typedef string filename<MAXNAMLEN>;
+ */
+static void encode_filename(struct xdr_stream *xdr, const char *name, u32 count)
+{
+	__be32 *p;
+
+	BUG_ON(unlikely(count > NFS2_MAXNAMLEN));
+	p = xdr_reserve_space(xdr, 4 + count);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(count);
+	xdr_encode_opaque_fixed(p, name, count);
+}
+
+/*
+ * 2.3.8.  path
+ *
+ *	typedef string path<MAXPATHLEN>;
+ */
+static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 count)
+{
+	__be32 *p;
+
+	BUG_ON(count > NFS_MAXPATHLEN);
+	p = xdr_reserve_space(xdr, 4);
+	BUG_ON(unlikely(p == NULL));
+	*p = cpu_to_be32(count);
+	xdr_write_pages(xdr, pages, 0, count);
+}
+
+static int decode_path(struct xdr_stream *xdr)
+{
+	u32 recvd, count;
+	size_t hdrlen;
+	__be32 *p;
+
+	p = xdr_inline_decode(xdr, 4);
+	if (unlikely(p == NULL)) {
+		print_overflow_msg(__func__, xdr);
+		return -EIO;
+	}
+	count = be32_to_cpup(p);
+
+	if (count >= xdr->buf->page_len || count > NFS_MAXPATHLEN) {
+		dprintk("NFS: server returned giant pathname!\n");
+		return -ENAMETOOLONG;
+	}
+	hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+	recvd = xdr->buf->len - hdrlen;
+	if (count > recvd) {
+		dprintk("NFS: server cheating in pathname result: "
+			"count %u > recvd %u\n", count, recvd);
+		return -EIO;
+	}
+
+	xdr_read_pages(xdr, count);
+	xdr_terminate_string(xdr->buf, count);
+	return 0;
+}
+
+/*
+ * 2.3.10.  diropargs
+ *
+ *	struct diropargs {
+ *		fhandle  dir;
+ *		filename name;
+ *	};
+ */
+static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
+			     const char *name, u32 count)
+{
+	encode_fhandle(xdr, fh);
+	encode_filename(xdr, name, count);
+}
+
+/*
+ * 2.3.11.  diropok
+ *
+ *	struct {
+ *		fhandle file;
+ *		fattr   attributes;
+ *	} diropok;
+ */
+static int decode_diropok(struct xdr_stream *xdr, struct nfs_fh *fh,
+			  struct nfs_fattr *fattr)
+{
+	if (decode_fhandle(xdr, fh) != 0)
+		return -EIO;
+	return decode_fattr(xdr, fattr);
+}
+
+
 /*
  * Common NFS XDR functions as inlines
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/24] NFS: Encode NFSv2 fhandle argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
  2010-05-17  2:45   ` [PATCH 01/24] SUNRPC: Refactor logic to NUL-terminate strings in pages Chuck Lever
  2010-05-17  2:45   ` [PATCH 02/24] NFS: Introduce XDR helpers for basic NFSv2 data types Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 04/24] NFS: Encode v2 setattr " Chuck Lever
                     ` (21 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 9d5159f..12307e9 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -530,6 +530,16 @@ nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
 	return 0;
 }
 
+static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
+				struct nfs_fh *fh)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, fh);
+	return 0;
+}
+
 /*
  * Encode SETATTR arguments
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/24] NFS: Encode v2 setattr argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (2 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 03/24] NFS: Encode NFSv2 fhandle argument using an xdr_stream Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 05/24] NFS: Encode dirop " Chuck Lever
                     ` (20 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 12307e9..ab94ed2 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -553,6 +553,25 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
 }
 
 /*
+ * 2.2.3.  sattrargs
+ *
+ *	struct sattrargs {
+ *		fhandle file;
+ *		sattr attributes;
+ *	};
+ */
+static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
+				  struct nfs_sattrargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fh);
+	encode_sattr(&xdr, args->sattr);
+	return 0;
+}
+
+/*
  * Encode directory ops argument
  * LOOKUP, RMDIR
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/24] NFS: Encode dirop argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (3 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 04/24] NFS: Encode v2 setattr " Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 06/24] NFS: Encode NFSv2 readlink " Chuck Lever
                     ` (19 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index ab94ed2..2f9102a 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -584,6 +584,16 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
 	return 0;
 }
 
+static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
+				  struct nfs_diropargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_diropargs(&xdr, args->fh, args->name, args->len);
+	return 0;
+}
+
 /*
  * Encode REMOVE argument
  */
@@ -596,6 +606,16 @@ nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs
 	return 0;
 }
 
+static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
+				   struct nfs_removeargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_diropargs(&xdr, args->fh, args->name.name, args->name.len);
+	return 0;
+}
+
 /*
  * Arguments to a READ call. Since we read data directly into the page
  * cache, we also set up the reply iovec here so that iov[1] points


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/24] NFS: Encode NFSv2 readlink argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (4 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 05/24] NFS: Encode dirop " Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 07/24] NFS: Encode NFSv2 read " Chuck Lever
                     ` (18 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 2f9102a..06f5a54 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -616,6 +616,23 @@ static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
 	return 0;
 }
 
+static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
+				     struct nfs_readlinkargs *args)
+{
+	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+	struct xdr_stream xdr;
+	unsigned int replen;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fh);
+
+	/* Prepare reply buffer to receive readlink data */
+	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
+	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
+						args->pgbase, args->pglen);
+	return 0;
+}
+
 /*
  * Arguments to a READ call. Since we read data directly into the page
  * cache, we also set up the reply iovec here so that iov[1] points


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/24] NFS: Encode NFSv2 read argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (5 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 06/24] NFS: Encode NFSv2 readlink " Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 08/24] NFS: Encode NFSv2 write " Chuck Lever
                     ` (17 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 06f5a54..c763149 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -661,6 +661,41 @@ nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
 }
 
 /*
+ * 2.2.7.  readargs
+ *
+ *	struct readargs {
+ *		fhandle file;
+ *		unsigned offset;
+ *		unsigned count;
+ *		unsigned totalcount;
+ *	};
+ */
+static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
+				 struct nfs_readargs *args)
+{
+	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+	u32 offset = (u32)args->offset;
+	u32 count = args->count;
+	struct xdr_stream xdr;
+	unsigned int replen;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fh);
+	p = xdr_reserve_space(&xdr, 12);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(offset);
+	*p++ = cpu_to_be32(count);
+	*p++ = cpu_to_be32(count);
+
+	/* Prepare reply buffer to receive read data */
+	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
+	xdr_inline_pages(&req->rq_rcv_buf, replen,
+			 args->pages, args->pgbase, count);
+	req->rq_rcv_buf.flags |= XDRBUF_READ;
+	return 0;
+}
+
+/*
  * Decode READ reply
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/24] NFS: Encode NFSv2 write argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (6 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 07/24] NFS: Encode NFSv2 read " Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:46   ` [PATCH 09/24] NFS: Encode NFSv2 create " Chuck Lever
                     ` (16 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   35 +++++++++++++++++++++++++++++++++++
 1 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index c763149..13c9975 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -761,6 +761,41 @@ nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
 }
 
 /*
+ * 2.2.9.  writeargs
+ *
+ *	struct writeargs {
+ *		fhandle file;
+ *		unsigned beginoffset;
+ *		unsigned offset;
+ *		unsigned totalcount;
+ *		nfsdata data;
+ *	};
+ */
+static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
+				  struct nfs_writeargs *args)
+{
+	struct xdr_buf *sndbuf = &req->rq_snd_buf;
+	u32 offset = (u32)args->offset;
+	u32 count = args->count;
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fh);
+	p = xdr_reserve_space(&xdr, 16);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(offset);
+	*p++ = cpu_to_be32(offset);
+	*p++ = cpu_to_be32(count);
+
+	/* nfsdata */
+	*p = cpu_to_be32(count);
+	xdr_write_pages(&xdr, args->pages, args->pgbase, count);
+
+	sndbuf->flags |= XDRBUF_WRITE;
+	return 0;
+}
+
+/*
  * Encode create arguments
  * CREATE, MKDIR
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/24] NFS: Encode NFSv2 create argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (7 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 08/24] NFS: Encode NFSv2 write " Chuck Lever
@ 2010-05-17  2:46   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 10/24] NFS: Encode NFSv2 rename " Chuck Lever
                     ` (15 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:46 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 13c9975..75583e8 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -810,6 +810,25 @@ nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
 }
 
 /*
+ * 2.2.10.  createargs
+ *
+ *	struct createargs {
+ *		diropargs where;
+ *		sattr attributes;
+ *	};
+ */
+static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
+				   const struct nfs_createargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_diropargs(&xdr, args->fh, args->name, args->len);
+	encode_sattr(&xdr, args->sattr);
+	return 0;
+}
+
+/*
  * Encode RENAME arguments
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/24] NFS: Encode NFSv2 rename argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (8 preceding siblings ...)
  2010-05-17  2:46   ` [PATCH 09/24] NFS: Encode NFSv2 create " Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 11/24] NFS: Encode NFSv2 link " Chuck Lever
                     ` (14 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 75583e8..493c3a1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -843,6 +843,25 @@ nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
 }
 
 /*
+ * 2.2.12.  renameargs
+ *
+ *	struct renameargs {
+ *		diropargs from;
+ *		diropargs to;
+ *	};
+ */
+static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
+				   struct nfs_renameargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
+	encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
+	return 0;
+}
+
+/*
  * Encode LINK arguments
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/24] NFS: Encode NFSv2 link argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (9 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 10/24] NFS: Encode NFSv2 rename " Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 12/24] NFS: Encode NFSv2 symlink " Chuck Lever
                     ` (13 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 493c3a1..48c8e88 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -875,6 +875,25 @@ nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
 }
 
 /*
+ * 2.2.13.  linkargs
+ *
+ *	struct linkargs {
+ *		fhandle from;
+ *		diropargs to;
+ *	};
+ */
+static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
+				 struct nfs_linkargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fromfh);
+	encode_diropargs(&xdr, args->tofh, args->toname, args->tolen);
+	return 0;
+}
+
+/*
  * Encode SYMLINK arguments
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/24] NFS: Encode NFSv2 symlink argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (10 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 11/24] NFS: Encode NFSv2 link " Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 13/24] NFS: Encode NFSv2 readdir " Chuck Lever
                     ` (12 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 48c8e88..42f7461 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -923,6 +923,27 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *arg
 }
 
 /*
+ * 2.2.14.  symlinkargs
+ *
+ *	struct symlinkargs {
+ *		diropargs from;
+ *		path to;
+ *		sattr attributes;
+ *	};
+ */
+static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
+				    struct nfs_symlinkargs *args)
+{
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen);
+	encode_path(&xdr, args->pages, args->pathlen);
+	encode_sattr(&xdr, args->sattr);
+	return 0;
+}
+
+/*
  * Encode arguments to readdir call
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 13/24] NFS: Encode NFSv2 readdir argument using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (11 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 12/24] NFS: Encode NFSv2 symlink " Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 14/24] NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones Chuck Lever
                     ` (11 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 42f7461..47809ac 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -966,6 +966,36 @@ nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *arg
 }
 
 /*
+ * 2.2.17.  readdirargs
+ *
+ *	struct readdirargs {
+ *		fhandle dir;
+ *		nfscookie cookie;
+ *		unsigned count;
+ *	};
+ */
+static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
+				    struct nfs_readdirargs *args)
+{
+	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+	u32 count = args->count;
+	unsigned int replen;
+	struct xdr_stream xdr;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_fhandle(&xdr, args->fh);
+	p = xdr_reserve_space(&xdr, 8);
+	BUG_ON(unlikely(p == NULL));
+	*p++ = cpu_to_be32(args->cookie);
+	*p = cpu_to_be32(count);
+
+	/* Prepare reply buffer to receive readdir data */
+	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
+	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
+	return 0;
+}
+
+/*
  * Decode the result of a readdir call.
  * We're not really decoding anymore, we just leave the buffer untouched
  * and only check that it is syntactically correct.


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 14/24] NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (12 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 13/24] NFS: Encode NFSv2 readdir " Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 15/24] NFS: Use the "nfs_stat" enum for nfs_stat_to_errno() Chuck Lever
                     ` (10 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Clean up.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |  273 ------------------------------------------------------
 1 files changed, 1 insertions(+), 272 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 47809ac..eb86e55 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -407,13 +407,6 @@ static int decode_diropok(struct xdr_stream *xdr, struct nfs_fh *fh,
  * Common NFS XDR functions as inlines
  */
 static inline __be32 *
-xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle)
-{
-	memcpy(p, fhandle->data, NFS2_FHSIZE);
-	return p + XDR_QUADLEN(NFS2_FHSIZE);
-}
-
-static inline __be32 *
 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 {
 	/* NFSv2 handles have a fixed length */
@@ -423,32 +416,6 @@ xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
 }
 
 static inline __be32*
-xdr_encode_time(__be32 *p, struct timespec *timep)
-{
-	*p++ = htonl(timep->tv_sec);
-	/* Convert nanoseconds into microseconds */
-	*p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
-	return p;
-}
-
-static inline __be32*
-xdr_encode_current_server_time(__be32 *p, struct timespec *timep)
-{
-	/*
-	 * Passing the invalid value useconds=1000000 is a
-	 * Sun convention for "set to current server time".
-	 * It's needed to make permissions checks for the
-	 * "touch" program across v2 mounts to Solaris and
-	 * Irix boxes work correctly. See description of
-	 * sattr in section 6.1 of "NFS Illustrated" by
-	 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
-	 */
-	*p++ = htonl(timep->tv_sec);
-	*p++ = htonl(1000000);
-	return p;
-}
-
-static inline __be32*
 xdr_decode_time(__be32 *p, struct timespec *timep)
 {
 	timep->tv_sec = ntohl(*p++);
@@ -485,50 +452,9 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
 	return p;
 }
 
-static inline __be32 *
-xdr_encode_sattr(__be32 *p, struct iattr *attr)
-{
-	const __be32 not_set = __constant_htonl(0xFFFFFFFF);
-
-	*p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
-	*p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
-	*p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set;
-	*p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set;
-
-	if (attr->ia_valid & ATTR_ATIME_SET) {
-		p = xdr_encode_time(p, &attr->ia_atime);
-	} else if (attr->ia_valid & ATTR_ATIME) {
-		p = xdr_encode_current_server_time(p, &attr->ia_atime);
-	} else {
-		*p++ = not_set;
-		*p++ = not_set;
-	}
-
-	if (attr->ia_valid & ATTR_MTIME_SET) {
-		p = xdr_encode_time(p, &attr->ia_mtime);
-	} else if (attr->ia_valid & ATTR_MTIME) {
-		p = xdr_encode_current_server_time(p, &attr->ia_mtime);
-	} else {
-		*p++ = not_set;	
-		*p++ = not_set;
-	}
-  	return p;
-}
-
 /*
  * NFS encode functions
  */
-/*
- * Encode file handle argument
- * GETATTR, READLINK, STATFS
- */
-static int
-nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
-{
-	p = xdr_encode_fhandle(p, fh);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
 
 static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
 				struct nfs_fh *fh)
@@ -541,18 +467,6 @@ static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode SETATTR arguments
- */
-static int
-nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fh);
-	p = xdr_encode_sattr(p, args->sattr);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
-/*
  * 2.2.3.  sattrargs
  *
  *	struct sattrargs {
@@ -571,19 +485,6 @@ static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p,
 	return 0;
 }
 
-/*
- * Encode directory ops argument
- * LOOKUP, RMDIR
- */
-static int
-nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fh);
-	p = xdr_encode_array(p, args->name, args->len);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
 static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
 				  struct nfs_diropargs *args)
 {
@@ -594,18 +495,6 @@ static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p,
 	return 0;
 }
 
-/*
- * Encode REMOVE argument
- */
-static int
-nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fh);
-	p = xdr_encode_array(p, args->name.name, args->name.len);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
 static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p,
 				   struct nfs_removeargs *args)
 {
@@ -634,33 +523,6 @@ static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Arguments to a READ call. Since we read data directly into the page
- * cache, we also set up the reply iovec here so that iov[1] points
- * exactly to the page we want to fetch.
- */
-static int
-nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
-{
-	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
-	unsigned int replen;
-	u32 offset = (u32)args->offset;
-	u32 count = args->count;
-
-	p = xdr_encode_fhandle(p, args->fh);
-	*p++ = htonl(offset);
-	*p++ = htonl(count);
-	*p++ = htonl(count);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-
-	/* Inline the page array */
-	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
-	xdr_inline_pages(&req->rq_rcv_buf, replen,
-			 args->pages, args->pgbase, count);
-	req->rq_rcv_buf.flags |= XDRBUF_READ;
-	return 0;
-}
-
-/*
  * 2.2.7.  readargs
  *
  *	struct readargs {
@@ -738,29 +600,6 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
 
 
 /*
- * Write arguments. Splice the buffer to be written into the iovec.
- */
-static int
-nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
-{
-	struct xdr_buf *sndbuf = &req->rq_snd_buf;
-	u32 offset = (u32)args->offset;
-	u32 count = args->count;
-
-	p = xdr_encode_fhandle(p, args->fh);
-	*p++ = htonl(offset);
-	*p++ = htonl(offset);
-	*p++ = htonl(count);
-	*p++ = htonl(count);
-	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
-
-	/* Copy the page array */
-	xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
-	sndbuf->flags |= XDRBUF_WRITE;
-	return 0;
-}
-
-/*
  * 2.2.9.  writeargs
  *
  *	struct writeargs {
@@ -796,20 +635,6 @@ static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode create arguments
- * CREATE, MKDIR
- */
-static int
-nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fh);
-	p = xdr_encode_array(p, args->name, args->len);
-	p = xdr_encode_sattr(p, args->sattr);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
-/*
  * 2.2.10.  createargs
  *
  *	struct createargs {
@@ -829,20 +654,6 @@ static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode RENAME arguments
- */
-static int
-nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fromfh);
-	p = xdr_encode_array(p, args->fromname, args->fromlen);
-	p = xdr_encode_fhandle(p, args->tofh);
-	p = xdr_encode_array(p, args->toname, args->tolen);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
-/*
  * 2.2.12.  renameargs
  *
  *	struct renameargs {
@@ -862,19 +673,6 @@ static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode LINK arguments
- */
-static int
-nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
-{
-	p = xdr_encode_fhandle(p, args->fromfh);
-	p = xdr_encode_fhandle(p, args->tofh);
-	p = xdr_encode_array(p, args->toname, args->tolen);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-	return 0;
-}
-
-/*
  * 2.2.13.  linkargs
  *
  *	struct linkargs {
@@ -894,35 +692,6 @@ static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode SYMLINK arguments
- */
-static int
-nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
-{
-	struct xdr_buf *sndbuf = &req->rq_snd_buf;
-	size_t pad;
-
-	p = xdr_encode_fhandle(p, args->fromfh);
-	p = xdr_encode_array(p, args->fromname, args->fromlen);
-	*p++ = htonl(args->pathlen);
-	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
-
-	xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
-
-	/*
-	 * xdr_encode_pages may have added a few bytes to ensure the
-	 * pathname ends on a 4-byte boundary.  Start encoding the
-	 * attributes after the pad bytes.
-	 */
-	pad = sndbuf->tail->iov_len;
-	if (pad > 0)
-		p++;
-	p = xdr_encode_sattr(p, args->sattr);
-	sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
-	return 0;
-}
-
-/*
  * 2.2.14.  symlinkargs
  *
  *	struct symlinkargs {
@@ -944,28 +713,6 @@ static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Encode arguments to readdir call
- */
-static int
-nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
-{
-	struct rpc_task	*task = req->rq_task;
-	struct rpc_auth	*auth = task->tk_msg.rpc_cred->cr_auth;
-	unsigned int replen;
-	u32 count = args->count;
-
-	p = xdr_encode_fhandle(p, args->fh);
-	*p++ = htonl(args->cookie);
-	*p++ = htonl(count); /* see above */
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-
-	/* Inline the page array */
-	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
-	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
-	return 0;
-}
-
-/*
  * 2.2.17.  readdirargs
  *
  *	struct readdirargs {
@@ -1156,24 +903,6 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
 }
 
 /*
- * Encode READLINK args
- */
-static int
-nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
-{
-	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
-	unsigned int replen;
-
-	p = xdr_encode_fhandle(p, args->fh);
-	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
-
-	/* Inline the page array */
-	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
-	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
-	return 0;
-}
-
-/*
  * Decode READLINK reply
  */
 static int
@@ -1306,7 +1035,7 @@ nfs_stat_to_errno(int stat)
 #define PROC(proc, argtype, restype, timer)				\
 [NFSPROC_##proc] = {							\
 	.p_proc	    =  NFSPROC_##proc,					\
-	.p_encode   =  (kxdrproc_t) nfs_xdr_##argtype,			\
+	.p_encode   =  (kxdrproc_t) nfs2_xdr_enc_##argtype,		\
 	.p_decode   =  (kxdrproc_t) nfs_xdr_##restype,			\
 	.p_arglen   =  NFS_##argtype##_sz,				\
 	.p_replen   =  NFS_##restype##_sz,				\


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 15/24] NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (13 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 14/24] NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:47   ` [PATCH 16/24] NFS: Decode NFSv2 stat reply using an xdr_stream Chuck Lever
                     ` (9 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Clean up: Use the proper type for the argument of nfs_stat_to_errno().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/internal.h |    2 +-
 fs/nfs/nfs2xdr.c  |   16 +++++++++-------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 07587e8..905df35 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -179,7 +179,7 @@ extern int __init nfs_init_directcache(void);
 extern void nfs_destroy_directcache(void);
 
 /* nfs2xdr.c */
-extern int nfs_stat_to_errno(int);
+extern int nfs_stat_to_errno(enum nfs_stat);
 extern struct rpc_procinfo nfs_procedures[];
 extern __be32 * nfs_decode_dirent(__be32 *, struct nfs_entry *, int);
 
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index eb86e55..f0eab7e 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1015,20 +1015,22 @@ static struct {
 	{ -1,			-EIO		}
 };
 
-/*
- * Convert an NFS error code to a local one.
- * This one is used jointly by NFSv2 and NFSv3.
+/**
+ * nfs_stat_to_errno - convert an NFS status code to a local errno
+ * @status: NFS status code to convert
+ *
+ * Returns a local errno value, or -EIO if the NFS status code is
+ * not recognized.  This function is used jointly by NFSv2 and NFSv3.
  */
-int
-nfs_stat_to_errno(int stat)
+int nfs_stat_to_errno(enum nfs_stat status)
 {
 	int i;
 
 	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
-		if (nfs_errtbl[i].stat == stat)
+		if (nfs_errtbl[i].stat == (int)status)
 			return nfs_errtbl[i].errno;
 	}
-	dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
+	dprintk("NFS: Unrecognized nfs status value: %u\n", status);
 	return nfs_errtbl[i].errno;
 }
 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 16/24] NFS: Decode NFSv2 stat reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (14 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 15/24] NFS: Use the "nfs_stat" enum for nfs_stat_to_errno() Chuck Lever
@ 2010-05-17  2:47   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 17/24] NFS: Decode NFSv2 attrstat " Chuck Lever
                     ` (8 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:47 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index f0eab7e..db04feb 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -871,6 +871,20 @@ nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
 	return status;
 }
 
+static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p,
+			     void *__unused)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	return 0;
+}
+
 /*
  * Decode attrstat reply
  * GETATTR, SETATTR, WRITE


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 17/24] NFS: Decode NFSv2 attrstat reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (15 preceding siblings ...)
  2010-05-17  2:47   ` [PATCH 16/24] NFS: Decode NFSv2 stat reply using an xdr_stream Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 18/24] NFS: Decode NFSv2 dirop " Chuck Lever
                     ` (7 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index db04feb..049f139 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -901,6 +901,30 @@ nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
 }
 
 /*
+ * 2.3.9.  attrstat
+ *
+ *	union attrstat switch (stat status) {
+ *	case NFS_OK:
+ *		fattr attributes;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p,
+				 struct nfs_fattr *result)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	return decode_fattr(&xdr, result);
+}
+
+/*
  * Decode diropres reply
  * LOOKUP, CREATE, MKDIR
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 18/24] NFS: Decode NFSv2 dirop reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (16 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 17/24] NFS: Decode NFSv2 attrstat " Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 19/24] NFS: Decode NFSv2 readlink " Chuck Lever
                     ` (6 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 049f139..b464c0b 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -941,6 +941,33 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
 }
 
 /*
+ * 2.3.11.  diropres
+ *
+ *	union diropres switch (stat status) {
+ *	case NFS_OK:
+ *		struct {
+ *			fhandle file;
+ *			fattr   attributes;
+ *		} diropok;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p,
+				 struct nfs_diropok *result)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	return decode_diropok(&xdr, result->fh, result->fattr);
+}
+
+/*
  * Decode READLINK reply
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 19/24] NFS: Decode NFSv2 readlink reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (17 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 18/24] NFS: Decode NFSv2 dirop " Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 20/24] NFS: Decode NFSv2 read " Chuck Lever
                     ` (5 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index b464c0b..164c06d 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1008,6 +1008,30 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
 }
 
 /*
+ * 2.2.6.  readlinkres
+ *
+ *	union readlinkres switch (stat status) {
+ *	case NFS_OK:
+ *		path data;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, __be32 *p,
+				    void *__unused)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	return decode_path(&xdr);
+}
+
+/*
  * Decode WRITE reply
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 20/24] NFS: Decode NFSv2 read reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (18 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 19/24] NFS: Decode NFSv2 readlink " Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 21/24] NFS: Decode NFSv2 write " Chuck Lever
                     ` (4 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 164c06d..807c1b1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1032,6 +1032,55 @@ static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
+ * 2.2.7.  readres
+ *
+ *	union readres switch (stat status) {
+ *	case NFS_OK:
+ *		fattr attributes;
+ *		nfsdata data;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_readres(struct rpc_rqst *req, __be32 *p,
+				struct nfs_readres *result)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+	u32 recvd, count;
+	size_t hdrlen;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	if (decode_fattr(&xdr, result->fattr) != 0)
+		return -EIO;
+
+	/* nfsdata */
+	p = xdr_inline_decode(&xdr, 4);
+	if (unlikely(p == NULL)) {
+		print_overflow_msg(__func__, &xdr);
+		return -EIO;
+	}
+	count = be32_to_cpup(p);
+	hdrlen = (u8 *)xdr.p - (u8 *)xdr.iov->iov_base;
+	recvd = xdr.buf->len - hdrlen;
+	if (count > recvd) {
+		dprintk("NFS: server cheating in read result: "
+			"count %u > recvd %u\n", count, recvd);
+		count = recvd;
+	}
+	xdr_read_pages(&xdr, count);
+
+	/* NFSv2 doesn't pass EOF flag on the wire. */
+	result->eof = 0;
+	result->count = count;
+	return count;
+}
+
+/*
  * Decode WRITE reply
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 21/24] NFS: Decode NFSv2 write reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (19 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 20/24] NFS: Decode NFSv2 read " Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:48   ` [PATCH 22/24] NFS: Decode NFSv2 readdir " Chuck Lever
                     ` (3 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 807c1b1..565a5c6 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1090,6 +1090,25 @@ nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
 	return nfs_xdr_attrstat(req, p, res->fattr);
 }
 
+static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p,
+				 struct nfs_writeres *result)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	if (decode_fattr(&xdr, result->fattr) != 0)
+		return -EIO;
+
+	/* All NFSv2 writes are "file sync" writes */
+	result->verf->committed = NFS_FILE_SYNC;
+	return 0;
+}
+
 /*
  * Decode STATFS reply
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 22/24] NFS: Decode NFSv2 readdir reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (20 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 21/24] NFS: Decode NFSv2 write " Chuck Lever
@ 2010-05-17  2:48   ` Chuck Lever
  2010-05-17  2:49   ` [PATCH 23/24] NFS: Decode NFSv2 statfs " Chuck Lever
                     ` (2 subsequent siblings)
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:48 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |  173 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 152 insertions(+), 21 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 565a5c6..1d65103 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -834,27 +834,6 @@ err_unmap:
 	goto out;
 }
 
-__be32 *
-nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
-{
-	if (!*p++) {
-		if (!*p)
-			return ERR_PTR(-EAGAIN);
-		entry->eof = 1;
-		return ERR_PTR(-EBADCOOKIE);
-	}
-
-	entry->ino	  = ntohl(*p++);
-	entry->len	  = ntohl(*p++);
-	entry->name	  = (const char *) p;
-	p		 += XDR_QUADLEN(entry->len);
-	entry->prev_cookie	  = entry->cookie;
-	entry->cookie	  = ntohl(*p++);
-	entry->eof	  = !p[0] && p[1];
-
-	return p;
-}
-
 /*
  * NFS XDR decode functions
  */
@@ -1110,6 +1089,158 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
+ * 2.2.17.  entry
+ *
+ * struct entry {
+ *	unsigned fileid;
+ *	filename name;
+ *	nfscookie cookie;
+ *	entry *nextentry;
+ * };
+ *
+ * The type (size) of nfscookie isn't defined in RFC 1094.
+ * The "nextentry" field is not used; instead, each entry
+ * is preceded by a boolean "entry follows" field.
+ *
+ * The Linux implementation is limited to receiving not more
+ * than a single page of entries at a time.
+ *
+ * Here, the XDR buffer is checked for correct syntax.  The
+ * actual decoding is done by nfs_decode_entry() during
+ * subsequent nfs_readdir() calls.
+ */
+static int decode_readdirok(struct xdr_stream *xdr)
+{
+	struct xdr_buf *rcvbuf = xdr->buf;
+	struct page **page = rcvbuf->pages;
+	__be32 *p, *end, *entry, *kaddr;
+	unsigned int nr, pglen, recvd;
+	size_t hdrlen;
+
+	pglen = rcvbuf->page_len;
+	hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+	recvd = rcvbuf->len - hdrlen;
+	if (pglen > recvd)
+		pglen = recvd;
+	xdr_read_pages(xdr, pglen);
+	kaddr = p = kmap_atomic(*page, KM_USER0);
+	end = (__be32 *)((char *)p + pglen);
+	entry = p;
+
+	/* Make sure the packet actually has a value_follows and EOF entry */
+	if ((entry + 1) > end)
+		goto short_pkt;
+
+	nr = 0;
+	for (; *p++; nr++) {
+		u32 len;
+
+		if (p + 2 > end)
+			goto short_pkt;
+		p++;	/* fileid */
+		len = be32_to_cpup(p++);
+		if (len > NFS2_MAXNAMLEN) {
+			dprintk("NFS: giant filename in readdir (len 0x%x)!\n",
+					len);
+			goto err_unmap;
+		}
+		p += XDR_QUADLEN(len) + 1;	/* name plus cookie */
+		if (p + 2 > end)
+			goto short_pkt;
+		entry = p;
+	}
+
+	/*
+	 * Apparently some server sends responses that are a valid size, but
+	 * contain no entries, and have value_follows==0 and EOF==0. For
+	 * those, just set the EOF marker.
+	 */
+	if (!nr && entry[1] == 0) {
+		dprintk("NFS: readdir reply truncated!\n");
+		entry[1] = 1;
+	}
+out:
+	kunmap_atomic(kaddr, KM_USER0);
+	return nr;
+short_pkt:
+	/*
+	 * When we get a short packet there are 2 possibilities. We can
+	 * return an error, or fix up the response to look like a valid
+	 * response and return what we have so far. If there are no
+	 * entries and the packet was short, then return -EIO. If there
+	 * are valid entries in the response, return them and pretend that
+	 * the call was successful, but incomplete. The caller can retry the
+	 * readdir starting at the last cookie.
+	 */
+	dprintk("%s: short packet at entry %d\n", __func__, nr);
+	entry[0] = entry[1] = 0;
+	if (nr)
+		goto out;
+err_unmap:
+	kunmap_atomic(kaddr, KM_USER0);
+	return -EIO;
+}
+
+/*
+ * 2.2.17.  readdirres
+ *
+ *	union readdirres switch (stat status) {
+ *	case NFS_OK:
+ *		struct {
+ *			entry *entries;
+ *			bool eof;
+ *		} readdirok;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, __be32 *p,
+				   void *__unused)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+	return decode_readdirok(&xdr);
+}
+
+/**
+ * nfs_decode_dirent - Decode a single NFSv2 directory entry stored in
+ *                     the local page cache.
+ * @p: pointer to buffer where entry resides
+ * @entry: entry struct to fill out with data
+ * @plus: boolean indicating whether this should be a readdirplus entry
+ *
+ * Returns the position of the next item in the buffer, or an ERR_PTR.
+ *
+ * This function is not invoked during READDIR reply processing, but
+ * rather whenever an application invokes the getdents(2) system call.
+ */
+__be32 *nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
+{
+	if (!*p++) {
+		if (!*p)
+			return ERR_PTR(-EAGAIN);
+		entry->eof = 1;
+		return ERR_PTR(-EBADCOOKIE);
+	}
+
+	entry->ino = be32_to_cpup(p++);
+	entry->len = be32_to_cpup(p++);
+	entry->name = (const char *)p;
+	p += XDR_QUADLEN(entry->len);
+	entry->prev_cookie = entry->cookie;
+	entry->cookie = be32_to_cpup(p++);
+
+	entry->eof = !p[0] && p[1];
+	return p;
+}
+
+/*
  * Decode STATFS reply
  */
 static int


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 23/24] NFS: Decode NFSv2 statfs reply using an xdr_stream
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (21 preceding siblings ...)
  2010-05-17  2:48   ` [PATCH 22/24] NFS: Decode NFSv2 readdir " Chuck Lever
@ 2010-05-17  2:49   ` Chuck Lever
  2010-05-17  2:49   ` [PATCH 24/24] NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones Chuck Lever
  2010-05-17 20:57   ` [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders Chuck Lever
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:49 UTC (permalink / raw)
  To: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 1d65103..3d373d1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -1260,6 +1260,47 @@ nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
 }
 
 /*
+ * 2.2.18.  statfsres
+ *
+ *	union statfsres (stat status) {
+ *	case NFS_OK:
+ *		struct {
+ *			unsigned tsize;
+ *			unsigned bsize;
+ *			unsigned blocks;
+ *			unsigned bfree;
+ *			unsigned bavail;
+ *		} info;
+ *	default:
+ *		void;
+ *	};
+ */
+static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, __be32 *p,
+				  struct nfs2_fsstat *result)
+{
+	struct xdr_stream xdr;
+	enum nfs_stat status;
+
+	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+	if (decode_stat(&xdr, &status) != 0)
+		return -EIO;
+	if (status != NFS_OK)
+		return nfs_stat_to_errno(status);
+
+	/* info */
+	p = xdr_inline_decode(&xdr, NFS_info_sz << 2);
+	if (unlikely(p == NULL))
+		return -EIO;
+	result->tsize  = be32_to_cpup(p++);
+	result->bsize  = be32_to_cpup(p++);
+	result->blocks = be32_to_cpup(p++);
+	result->bfree  = be32_to_cpup(p++);
+	result->bavail = be32_to_cpup(p);
+	return 0;
+}
+
+
+/*
  * We need to translate between nfs status return values and
  * the local errno values which may not be the same.
  */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 24/24] NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (22 preceding siblings ...)
  2010-05-17  2:49   ` [PATCH 23/24] NFS: Decode NFSv2 statfs " Chuck Lever
@ 2010-05-17  2:49   ` Chuck Lever
  2010-05-17 20:57   ` [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders Chuck Lever
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17  2:49 UTC (permalink / raw)
  To: linux-nfs

Clean up.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 fs/nfs/nfs2xdr.c |  297 ------------------------------------------------------
 1 files changed, 1 insertions(+), 296 deletions(-)

diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 3d373d1..0ed18b1 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -404,55 +404,6 @@ static int decode_diropok(struct xdr_stream *xdr, struct nfs_fh *fh,
 
 
 /*
- * Common NFS XDR functions as inlines
- */
-static inline __be32 *
-xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
-{
-	/* NFSv2 handles have a fixed length */
-	fhandle->size = NFS2_FHSIZE;
-	memcpy(fhandle->data, p, NFS2_FHSIZE);
-	return p + XDR_QUADLEN(NFS2_FHSIZE);
-}
-
-static inline __be32*
-xdr_decode_time(__be32 *p, struct timespec *timep)
-{
-	timep->tv_sec = ntohl(*p++);
-	/* Convert microseconds into nanoseconds */
-	timep->tv_nsec = ntohl(*p++) * 1000;
-	return p;
-}
-
-static __be32 *
-xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
-{
-	u32 rdev, type;
-	type = ntohl(*p++);
-	fattr->mode = ntohl(*p++);
-	fattr->nlink = ntohl(*p++);
-	fattr->uid = ntohl(*p++);
-	fattr->gid = ntohl(*p++);
-	fattr->size = ntohl(*p++);
-	fattr->du.nfs2.blocksize = ntohl(*p++);
-	rdev = ntohl(*p++);
-	fattr->du.nfs2.blocks = ntohl(*p++);
-	fattr->fsid.major = ntohl(*p++);
-	fattr->fsid.minor = 0;
-	fattr->fileid = ntohl(*p++);
-	p = xdr_decode_time(p, &fattr->atime);
-	p = xdr_decode_time(p, &fattr->mtime);
-	p = xdr_decode_time(p, &fattr->ctime);
-	fattr->valid |= NFS_ATTR_FATTR_V2;
-	fattr->rdev = new_decode_dev(rdev);
-	if (type == NFCHR && rdev == NFS2_FIFO_DEV) {
-		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
-		fattr->rdev = 0;
-	}
-	return p;
-}
-
-/*
  * NFS encode functions
  */
 
@@ -558,48 +509,6 @@ static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Decode READ reply
- */
-static int
-nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
-{
-	struct kvec *iov = req->rq_rcv_buf.head;
-	size_t hdrlen;
-	u32 count, recvd;
-	int status;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-	p = xdr_decode_fattr(p, res->fattr);
-
-	count = ntohl(*p++);
-	res->eof = 0;
-	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len < hdrlen) {
-		dprintk("NFS: READ reply header overflowed:"
-				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
-		return -errno_NFSERR_IO;
-	} else if (iov->iov_len != hdrlen) {
-		dprintk("NFS: READ header is short. iovec will be shifted.\n");
-		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
-	}
-
-	recvd = req->rq_rcv_buf.len - hdrlen;
-	if (count > recvd) {
-		dprintk("NFS: server cheating in read reply: "
-			"count %u > recvd %u\n", count, recvd);
-		count = recvd;
-	}
-
-	dprintk("RPC:      readres OK count %u\n", count);
-	if (count < res->count)
-		res->count = count;
-
-	return count;
-}
-
-
-/*
  * 2.2.9.  writeargs
  *
  *	struct writeargs {
@@ -743,112 +652,8 @@ static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Decode the result of a readdir call.
- * We're not really decoding anymore, we just leave the buffer untouched
- * and only check that it is syntactically correct.
- * The real decoding happens in nfs_decode_entry below, called directly
- * from nfs_readdir for each entry.
- */
-static int
-nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
-{
-	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
-	struct kvec *iov = rcvbuf->head;
-	struct page **page;
-	size_t hdrlen;
-	unsigned int pglen, recvd;
-	u32 len;
-	int status, nr = 0;
-	__be32 *end, *entry, *kaddr;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-
-	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len < hdrlen) {
-		dprintk("NFS: READDIR reply header overflowed:"
-				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
-		return -errno_NFSERR_IO;
-	} else if (iov->iov_len != hdrlen) {
-		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
-		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
-	}
-
-	pglen = rcvbuf->page_len;
-	recvd = rcvbuf->len - hdrlen;
-	if (pglen > recvd)
-		pglen = recvd;
-	page = rcvbuf->pages;
-	kaddr = p = kmap_atomic(*page, KM_USER0);
-	end = (__be32 *)((char *)p + pglen);
-	entry = p;
-
-	/* Make sure the packet actually has a value_follows and EOF entry */
-	if ((entry + 1) > end)
-		goto short_pkt;
-
-	for (; *p++; nr++) {
-		if (p + 2 > end)
-			goto short_pkt;
-		p++; /* fileid */
-		len = ntohl(*p++);
-		p += XDR_QUADLEN(len) + 1;	/* name plus cookie */
-		if (len > NFS2_MAXNAMLEN) {
-			dprintk("NFS: giant filename in readdir (len 0x%x)!\n",
-						len);
-			goto err_unmap;
-		}
-		if (p + 2 > end)
-			goto short_pkt;
-		entry = p;
-	}
-
-	/*
-	 * Apparently some server sends responses that are a valid size, but
-	 * contain no entries, and have value_follows==0 and EOF==0. For
-	 * those, just set the EOF marker.
-	 */
-	if (!nr && entry[1] == 0) {
-		dprintk("NFS: readdir reply truncated!\n");
-		entry[1] = 1;
-	}
- out:
-	kunmap_atomic(kaddr, KM_USER0);
-	return nr;
- short_pkt:
-	/*
-	 * When we get a short packet there are 2 possibilities. We can
-	 * return an error, or fix up the response to look like a valid
-	 * response and return what we have so far. If there are no
-	 * entries and the packet was short, then return -EIO. If there
-	 * are valid entries in the response, return them and pretend that
-	 * the call was successful, but incomplete. The caller can retry the
-	 * readdir starting at the last cookie.
-	 */
-	entry[0] = entry[1] = 0;
-	if (!nr)
-		nr = -errno_NFSERR_IO;
-	goto out;
-err_unmap:
-	nr = -errno_NFSERR_IO;
-	goto out;
-}
-
-/*
  * NFS XDR decode functions
  */
-/*
- * Decode simple status reply
- */
-static int
-nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
-{
-	int	status;
-
-	if ((status = ntohl(*p++)) != 0)
-		status = nfs_stat_to_errno(status);
-	return status;
-}
 
 static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p,
 			     void *__unused)
@@ -865,21 +670,6 @@ static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Decode attrstat reply
- * GETATTR, SETATTR, WRITE
- */
-static int
-nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
-{
-	int	status;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-	xdr_decode_fattr(p, fattr);
-	return 0;
-}
-
-/*
  * 2.3.9.  attrstat
  *
  *	union attrstat switch (stat status) {
@@ -904,22 +694,6 @@ static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Decode diropres reply
- * LOOKUP, CREATE, MKDIR
- */
-static int
-nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
-{
-	int	status;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-	p = xdr_decode_fhandle(p, res->fh);
-	xdr_decode_fattr(p, res->fattr);
-	return 0;
-}
-
-/*
  * 2.3.11.  diropres
  *
  *	union diropres switch (stat status) {
@@ -947,46 +721,6 @@ static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p,
 }
 
 /*
- * Decode READLINK reply
- */
-static int
-nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
-{
-	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
-	struct kvec *iov = rcvbuf->head;
-	size_t hdrlen;
-	u32 len, recvd;
-	int	status;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-	/* Convert length of symlink */
-	len = ntohl(*p++);
-	if (len >= rcvbuf->page_len) {
-		dprintk("nfs: server returned giant symlink!\n");
-		return -ENAMETOOLONG;
-	}
-	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
-	if (iov->iov_len < hdrlen) {
-		dprintk("NFS: READLINK reply header overflowed:"
-				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
-		return -errno_NFSERR_IO;
-	} else if (iov->iov_len != hdrlen) {
-		dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
-		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
-	}
-	recvd = req->rq_rcv_buf.len - hdrlen;
-	if (recvd < len) {
-		dprintk("NFS: server cheating in readlink reply: "
-				"count %u > recvd %u\n", len, recvd);
-		return -EIO;
-	}
-
-	xdr_terminate_string(rcvbuf, len);
-	return 0;
-}
-
-/*
  * 2.2.6.  readlinkres
  *
  *	union readlinkres switch (stat status) {
@@ -1059,16 +793,6 @@ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, __be32 *p,
 	return count;
 }
 
-/*
- * Decode WRITE reply
- */
-static int
-nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
-{
-	res->verf->committed = NFS_FILE_SYNC;
-	return nfs_xdr_attrstat(req, p, res->fattr);
-}
-
 static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p,
 				 struct nfs_writeres *result)
 {
@@ -1241,25 +965,6 @@ __be32 *nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
 }
 
 /*
- * Decode STATFS reply
- */
-static int
-nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
-{
-	int	status;
-
-	if ((status = ntohl(*p++)))
-		return nfs_stat_to_errno(status);
-
-	res->tsize  = ntohl(*p++);
-	res->bsize  = ntohl(*p++);
-	res->blocks = ntohl(*p++);
-	res->bfree  = ntohl(*p++);
-	res->bavail = ntohl(*p++);
-	return 0;
-}
-
-/*
  * 2.2.18.  statfsres
  *
  *	union statfsres (stat status) {
@@ -1367,7 +1072,7 @@ int nfs_stat_to_errno(enum nfs_stat status)
 [NFSPROC_##proc] = {							\
 	.p_proc	    =  NFSPROC_##proc,					\
 	.p_encode   =  (kxdrproc_t) nfs2_xdr_enc_##argtype,		\
-	.p_decode   =  (kxdrproc_t) nfs_xdr_##restype,			\
+	.p_decode   =  (kxdrproc_t) nfs2_xdr_dec_##restype,		\
 	.p_arglen   =  NFS_##argtype##_sz,				\
 	.p_replen   =  NFS_##restype##_sz,				\
 	.p_timer    =  timer,						\


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders
       [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
                     ` (23 preceding siblings ...)
  2010-05-17  2:49   ` [PATCH 24/24] NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones Chuck Lever
@ 2010-05-17 20:57   ` Chuck Lever
  24 siblings, 0 replies; 26+ messages in thread
From: Chuck Lever @ 2010-05-17 20:57 UTC (permalink / raw)
  To: linux-nfs

Note: I now have some minor clean ups for this series.  I can post again 
after a few days, after any review comments.

On 05/16/10 10:45 PM, Chuck Lever wrote:
> This series backports patches I did 3 years ago that update the NFS
> client's NFSv2 XDR encoders and decoders to use xdr_stream style
> marshalling, similar to NFSv4.  The immediate advantage is better
> bounds checking during marshalling and unmarshalling.
>
> I've already done the kernel's MNT client, lockd's NSM client, and
> the kernel's rpcbind client.  Eventually, we should convert NFSv3 and
> NLM to use this style of marshalling XDR so that we can streamline
> call_encode() and call_decode().
>
> ---
>
> Chuck Lever (24):
>        NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones
>        NFS: Decode NFSv2 statfs reply using an xdr_stream
>        NFS: Decode NFSv2 readdir reply using an xdr_stream
>        NFS: Decode NFSv2 write reply using an xdr_stream
>        NFS: Decode NFSv2 read reply using an xdr_stream
>        NFS: Decode NFSv2 readlink reply using an xdr_stream
>        NFS: Decode NFSv2 dirop reply using an xdr_stream
>        NFS: Decode NFSv2 attrstat reply using an xdr_stream
>        NFS: Decode NFSv2 stat reply using an xdr_stream
>        NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()
>        NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones
>        NFS: Encode NFSv2 readdir argument using an xdr_stream
>        NFS: Encode NFSv2 symlink argument using an xdr_stream
>        NFS: Encode NFSv2 link argument using an xdr_stream
>        NFS: Encode NFSv2 rename argument using an xdr_stream
>        NFS: Encode NFSv2 create argument using an xdr_stream
>        NFS: Encode NFSv2 write argument using an xdr_stream
>        NFS: Encode NFSv2 read argument using an xdr_stream
>        NFS: Encode NFSv2 readlink argument using an xdr_stream
>        NFS: Encode dirop argument using an xdr_stream
>        NFS: Encode v2 setattr argument using an xdr_stream
>        NFS: Encode NFSv2 fhandle argument using an xdr_stream
>        NFS: Introduce XDR helpers for basic NFSv2 data types
>        SUNRPC: Refactor logic to NUL-terminate strings in pages
>
>
>   fs/nfs/internal.h          |    2
>   fs/nfs/nfs2xdr.c           | 1169 +++++++++++++++++++++++++++++---------------
>   fs/nfs/nfs3xdr.c           |    6
>   fs/nfs/nfs4xdr.c           |    5
>   include/linux/sunrpc/xdr.h |    1
>   net/sunrpc/xdr.c           |   17 +
>   6 files changed, 779 insertions(+), 421 deletions(-)
>


^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2010-05-17 20:58 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-17  2:45 [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders Chuck Lever
     [not found] ` <20100517023905.20258.86631.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2010-05-17  2:45   ` [PATCH 01/24] SUNRPC: Refactor logic to NUL-terminate strings in pages Chuck Lever
2010-05-17  2:45   ` [PATCH 02/24] NFS: Introduce XDR helpers for basic NFSv2 data types Chuck Lever
2010-05-17  2:46   ` [PATCH 03/24] NFS: Encode NFSv2 fhandle argument using an xdr_stream Chuck Lever
2010-05-17  2:46   ` [PATCH 04/24] NFS: Encode v2 setattr " Chuck Lever
2010-05-17  2:46   ` [PATCH 05/24] NFS: Encode dirop " Chuck Lever
2010-05-17  2:46   ` [PATCH 06/24] NFS: Encode NFSv2 readlink " Chuck Lever
2010-05-17  2:46   ` [PATCH 07/24] NFS: Encode NFSv2 read " Chuck Lever
2010-05-17  2:46   ` [PATCH 08/24] NFS: Encode NFSv2 write " Chuck Lever
2010-05-17  2:46   ` [PATCH 09/24] NFS: Encode NFSv2 create " Chuck Lever
2010-05-17  2:47   ` [PATCH 10/24] NFS: Encode NFSv2 rename " Chuck Lever
2010-05-17  2:47   ` [PATCH 11/24] NFS: Encode NFSv2 link " Chuck Lever
2010-05-17  2:47   ` [PATCH 12/24] NFS: Encode NFSv2 symlink " Chuck Lever
2010-05-17  2:47   ` [PATCH 13/24] NFS: Encode NFSv2 readdir " Chuck Lever
2010-05-17  2:47   ` [PATCH 14/24] NFS: Replace old NFSv2 encoder functions with xdr_stream-based ones Chuck Lever
2010-05-17  2:47   ` [PATCH 15/24] NFS: Use the "nfs_stat" enum for nfs_stat_to_errno() Chuck Lever
2010-05-17  2:47   ` [PATCH 16/24] NFS: Decode NFSv2 stat reply using an xdr_stream Chuck Lever
2010-05-17  2:48   ` [PATCH 17/24] NFS: Decode NFSv2 attrstat " Chuck Lever
2010-05-17  2:48   ` [PATCH 18/24] NFS: Decode NFSv2 dirop " Chuck Lever
2010-05-17  2:48   ` [PATCH 19/24] NFS: Decode NFSv2 readlink " Chuck Lever
2010-05-17  2:48   ` [PATCH 20/24] NFS: Decode NFSv2 read " Chuck Lever
2010-05-17  2:48   ` [PATCH 21/24] NFS: Decode NFSv2 write " Chuck Lever
2010-05-17  2:48   ` [PATCH 22/24] NFS: Decode NFSv2 readdir " Chuck Lever
2010-05-17  2:49   ` [PATCH 23/24] NFS: Decode NFSv2 statfs " Chuck Lever
2010-05-17  2:49   ` [PATCH 24/24] NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones Chuck Lever
2010-05-17 20:57   ` [PATCH 00/24] Modernize NFSv2 XDR encoder/decoders Chuck Lever

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.