* [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