From: Chuck Lever <chuck.lever@oracle.com>
To: linux-nfs@vger.kernel.org
Subject: [PATCH 08/22] NFS: Introduce new-style XDR decoding functions for NFSv2
Date: Fri, 02 Jul 2010 13:19:44 -0400 [thread overview]
Message-ID: <20100702171943.8761.37289.stgit@ellison.1015granger.net> (raw)
In-Reply-To: <20100702165935.8761.88528.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/internal.h | 2
fs/nfs/nfs2xdr.c | 562 +++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfs/proc.c | 2
3 files changed, 563 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index f516424..916adec 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -181,7 +181,7 @@ extern void nfs_destroy_directcache(void);
/* nfs2xdr.c */
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);
+extern __be32 *nfs2_decode_dirent(__be32 *, struct nfs_entry *, int);
/* nfs3xdr.c */
extern struct rpc_procinfo nfs3_procedures[];
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 068e38a..486f6c7 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -77,6 +77,16 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
}
+/*
+ * Handle decode buffer overflows out-of-line.
+ */
+static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+{
+ dprintk("NFS: %s prematurely hit the end of our receive buffer. "
+ "Remaining buffer length is %tu words.\n",
+ func, xdr->end - xdr->p);
+}
+
/*
* Common NFS XDR functions as inlines
@@ -139,6 +149,74 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
*/
/*
+ * typedef opaque nfsdata<>;
+ */
+static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
+{
+ u32 recvd, count;
+ size_t hdrlen;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ count = be32_to_cpup(p);
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(count > recvd))
+ goto out_cheating;
+out:
+ xdr_read_pages(xdr, count);
+ result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */
+ result->count = count;
+ return count;
+out_cheating:
+ dprintk("NFS: server cheating in read result: "
+ "count %u > recvd %u\n", count, recvd);
+ count = recvd;
+ goto out;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * enum stat {
+ * NFS_OK = 0,
+ * NFSERR_PERM = 1,
+ * NFSERR_NOENT = 2,
+ * NFSERR_IO = 5,
+ * NFSERR_NXIO = 6,
+ * NFSERR_ACCES = 13,
+ * NFSERR_EXIST = 17,
+ * NFSERR_NODEV = 19,
+ * NFSERR_NOTDIR = 20,
+ * NFSERR_ISDIR = 21,
+ * NFSERR_FBIG = 27,
+ * NFSERR_NOSPC = 28,
+ * NFSERR_ROFS = 30,
+ * NFSERR_NAMETOOLONG = 63,
+ * NFSERR_NOTEMPTY = 66,
+ * NFSERR_DQUOT = 69,
+ * NFSERR_STALE = 70,
+ * NFSERR_WFLUSH = 99
+ * };
+ */
+static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ *status = be32_to_cpup(p);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
* 2.3.3. fhandle
*
* typedef opaque fhandle[FHSIZE];
@@ -153,6 +231,21 @@ static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
memcpy(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))
+ goto out_overflow;
+ fh->size = NFS2_FHSIZE;
+ memcpy(fh->data, p, NFS2_FHSIZE);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
/*
* 2.3.4. timeval
*
@@ -187,6 +280,41 @@ static __be32 *xdr_encode_current_server_time(__be32 *p,
}
/*
+ * 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)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ xdr_decode_fattr(p, fattr);
+ return 0;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
* 2.3.6. sattr
*
* struct sattr {
@@ -278,6 +406,65 @@ static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
xdr_write_pages(xdr, pages, 0, length);
}
+static int decode_path(struct xdr_stream *xdr)
+{
+ u32 length, recvd;
+ size_t hdrlen;
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, 4);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ length = be32_to_cpup(p);
+ if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
+ goto out_size;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (unlikely(length > recvd))
+ goto out_cheating;
+
+ xdr_read_pages(xdr, length);
+ xdr_terminate_string(xdr->buf, length);
+ return 0;
+out_size:
+ dprintk("NFS: returned pathname too long: %u\n", length);
+ return -ENAMETOOLONG;
+out_cheating:
+ dprintk("NFS: server cheating in pathname result: "
+ "length %u > received %u\n", length, recvd);
+ return -EIO;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+/*
+ * 2.3.9. attrstat
+ *
+ * union attrstat switch (stat status) {
+ * case NFS_OK:
+ * fattr attributes;
+ * default:
+ * void;
+ * };
+ */
+static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_fattr(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
/*
* 2.3.10. diropargs
*
@@ -293,6 +480,48 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
encode_filename(xdr, name, length);
}
+/*
+ * 2.3.11. diropres
+ *
+ * union diropres switch (stat status) {
+ * case NFS_OK:
+ * struct {
+ * fhandle file;
+ * fattr attributes;
+ * } diropok;
+ * default:
+ * void;
+ * };
+ */
+static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
+{
+ int error;
+
+ error = decode_fhandle(xdr, result->fh);
+ if (unlikely(error))
+ goto out;
+ error = decode_fattr(xdr, result->fattr);
+out:
+ return error;
+}
+
+static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
+{
+ enum nfs_stat status;
+ int error;
+
+ error = decode_stat(xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_diropok(xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
/*
* NFSv2 XDR encode functions
@@ -726,6 +955,25 @@ 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;
+ int error;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ error = decode_stat(&xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
/*
* Decode attrstat reply
* GETATTR, SETATTR, WRITE
@@ -741,6 +989,15 @@ nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
return 0;
}
+static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p,
+ struct nfs_fattr *result)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ return decode_attrstat(&xdr, result);
+}
+
/*
* Decode diropres reply
* LOOKUP, CREATE, MKDIR
@@ -757,6 +1014,15 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
return 0;
}
+static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p,
+ struct nfs_diropok *result)
+{
+ struct xdr_stream xdr;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ return decode_diropres(&xdr, result);
+}
+
/*
* Decode READLINK reply
*/
@@ -798,6 +1064,70 @@ 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;
+ int error;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ error = decode_stat(&xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_path(&xdr);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
+/*
+ * 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;
+ int error;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ error = decode_stat(&xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_fattr(&xdr, result->fattr);
+ if (unlikely(error))
+ goto out;
+ error = decode_nfsdata(&xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
+/*
* Decode WRITE reply
*/
static int
@@ -807,6 +1137,181 @@ 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;
+
+ /* All NFSv2 writes are "file sync" writes */
+ result->verf->committed = NFS_FILE_SYNC;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ return decode_attrstat(&xdr, result->fattr);
+}
+
+/*
+ * 2.2.17. readdirres
+ *
+ * struct entry {
+ * unsigned fileid;
+ * filename name;
+ * nfscookie cookie;
+ * entry *nextentry;
+ * };
+ *
+ * union readdirres switch (stat status) {
+ * case NFS_OK:
+ * struct {
+ * entry *entries;
+ * bool eof;
+ * } readdirok;
+ * default:
+ * void;
+ * };
+ *
+ * The type (size) of nfscookie isn't defined in RFC 1094.
+ *
+ * The Linux implementation of readdir 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 on readdir data cached in the page cache.
+ */
+static int decode_readdirok(struct xdr_stream *xdr)
+{
+ __be32 *p, *end, *entry, *kaddr;
+ unsigned int nr, pglen, recvd;
+ struct page **page;
+ size_t hdrlen;
+ u32 count;
+
+ pglen = xdr->buf->page_len;
+ hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base;
+ recvd = xdr->buf->len - hdrlen;
+ if (pglen > recvd)
+ pglen = recvd;
+ xdr_read_pages(xdr, pglen);
+
+ page = xdr->buf->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 (unlikely((entry + 1) > end))
+ goto out_short_reply;
+
+ nr = 0;
+ for (; *p++ != xdr_zero; nr++) {
+ if (unlikely(p + 2 > end))
+ goto out_short_reply;
+ p++; /* fileid */
+ count = be32_to_cpup(p++);
+ if (unlikely(count > NFS2_MAXNAMLEN))
+ goto out_nametoolong;
+ p += XDR_QUADLEN(count) + 1; /* name plus cookie */
+ if (unlikely(p + 2 > end))
+ goto out_short_reply;
+ 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 (unlikely(!nr && entry[1] == xdr_zero))
+ goto out_truncated;
+out:
+ kunmap_atomic(kaddr, KM_USER0);
+ return nr;
+out_short_reply:
+ /*
+ * When we get a short reply 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 reply 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("NFS: short readdir reply at entry %d\n", nr);
+ entry[0] = entry[1] = xdr_zero;
+ if (!nr)
+ nr = -EIO;
+ goto out;
+out_nametoolong:
+ dprintk("NFS: filename too long during readdir (len 0x%x)\n", count);
+ nr = -EIO;
+ goto out;
+out_truncated:
+ dprintk("NFS: readdir reply truncated\n");
+ entry[1] = xdr_one;
+ goto out;
+}
+
+static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, __be32 *p,
+ void *__unused)
+{
+ struct xdr_stream xdr;
+ enum nfs_stat status;
+ int error;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ error = decode_stat(&xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_readdirok(&xdr);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
+/**
+ * nfs2_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 decoding, but
+ * rather whenever an application invokes the getdents(2) system call.
+ *
+ * 2.2.17. entry
+ *
+ * struct entry {
+ * unsigned fileid;
+ * filename name;
+ * nfscookie cookie;
+ * entry *nextentry;
+ * };
+ */
+__be32 *nfs2_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
+{
+ if (*p++ == xdr_zero) {
+ if (*p == xdr_zero)
+ return ERR_PTR(-EAGAIN);
+ entry->eof = 1;
+ return ERR_PTR(-EBADCOOKIE);
+ }
+
+ entry->ino = be32_to_cpup(p++);
+ p = xdr_decode_string_inplace(p, (char **)&entry->name,
+ &entry->len, NFS2_MAXNAMLEN);
+ entry->prev_cookie = entry->cookie;
+ entry->cookie = be32_to_cpup(p++);
+
+ /* Peek at the next entry */
+ entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
+ return p;
+}
+
/*
* Decode STATFS reply
*/
@@ -827,6 +1332,61 @@ 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 decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
+{
+ __be32 *p;
+
+ p = xdr_inline_decode(xdr, NFS_info_sz << 2);
+ if (unlikely(p == NULL))
+ goto out_overflow;
+ 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;
+out_overflow:
+ print_overflow_msg(__func__, xdr);
+ return -EIO;
+}
+
+static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, __be32 *p,
+ struct nfs2_fsstat *result)
+{
+ struct xdr_stream xdr;
+ enum nfs_stat status;
+ int error;
+
+ xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
+ error = decode_stat(&xdr, &status);
+ if (unlikely(error))
+ goto out;
+ if (status != NFS_OK)
+ goto out_default;
+ error = decode_info(&xdr, result);
+out:
+ return error;
+out_default:
+ return nfs_stat_to_errno(status);
+}
+
+
+/*
* We need to translate between nfs status return values and
* the local errno values which may not be the same.
*/
@@ -893,7 +1453,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, \
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 611bec2..12a0200 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -714,7 +714,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
.statfs = nfs_proc_statfs,
.fsinfo = nfs_proc_fsinfo,
.pathconf = nfs_proc_pathconf,
- .decode_dirent = nfs_decode_dirent,
+ .decode_dirent = nfs2_decode_dirent,
.read_setup = nfs_proc_read_setup,
.read_done = nfs_read_done,
.write_setup = nfs_proc_write_setup,
next prev parent reply other threads:[~2010-07-02 17:19 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-02 17:18 [PATCH 00/22] NFS v2 and v3 XDR overhaul Chuck Lever
[not found] ` <20100702165935.8761.88528.stgit-ewv44WTpT0t9HhUboXbp9zCvJB+x5qRC@public.gmane.org>
2010-07-02 17:18 ` [PATCH 01/22] Fix NFSv3 debugging messages in fs/nfs/nfs3proc.c Chuck Lever
2010-07-02 17:18 ` [PATCH 02/22] SUNRPC: Correct an rpcbind debugging message Chuck Lever
2010-07-02 17:18 ` [PATCH 03/22] SUNRPC: Refactor logic to NUL-terminate strings in pages Chuck Lever
2010-07-02 17:19 ` [PATCH 04/22] NFS: Introduce new-style XDR encoding functions for NFSv2 Chuck Lever
2010-07-02 17:19 ` [PATCH 05/22] NFS: Remove old NFSv2 encoder functions Chuck Lever
2010-07-02 17:19 ` [PATCH 06/22] NFS: Move and update xdr_encode_foo() functions that we're keeping Chuck Lever
2010-07-02 17:19 ` [PATCH 07/22] NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()'s argument Chuck Lever
2010-07-02 17:19 ` Chuck Lever [this message]
2010-07-02 17:19 ` [PATCH 09/22] NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones Chuck Lever
2010-07-02 17:20 ` [PATCH 10/22] NFS: Move and update xdr_decode_foo() functions that we're keeping Chuck Lever
2010-07-02 17:20 ` [PATCH 11/22] lockd: Introduce new-style XDR functions for NLMv3 Chuck Lever
2010-07-02 17:20 ` [PATCH 12/22] NFS: Introduce new-style XDR encoding functions for NFSv3 Chuck Lever
2010-07-02 17:20 ` [PATCH 13/22] NFS: Replace old NFSv3 encoder functions with xdr_stream-based ones Chuck Lever
2010-07-02 17:20 ` [PATCH 14/22] NFS: Remove unused old NFSv3 encoder functions Chuck Lever
2010-07-02 17:20 ` [PATCH 15/22] NFS: Move and update xdr_encode_foo() functions that we're keeping Chuck Lever
2010-07-02 17:20 ` [PATCH 16/22] NFS: Introduce new-style XDR decoding functions for NFSv2 Chuck Lever
2010-07-02 17:21 ` [PATCH 17/22] NFS: Switch in new NFSv3 decoder functions Chuck Lever
2010-07-02 17:21 ` [PATCH 18/22] NFS: Remove unused old " Chuck Lever
2010-07-02 17:21 ` [PATCH 19/22] NFS: Move and update xdr_decode_foo() functions that we're keeping Chuck Lever
2010-07-02 17:21 ` [PATCH 20/22] lockd: Introduce new-style XDR functions for NLMv4 Chuck Lever
2010-07-02 17:21 ` [PATCH 21/22] lockd: Move nlmdbg_cookie2a() to svclock.c Chuck Lever
2010-07-02 17:21 ` [PATCH 22/22] NFS: Fix hdrlen calculation in NFSv4's decode_read() Chuck Lever
-- strict thread matches above, loose matches on Subject: below --
2010-09-17 16:26 [PATCH 00/22] Full NFSv2/v3 XDR overhaul series Chuck Lever
2010-09-17 16:27 ` [PATCH 08/22] NFS: Introduce new-style XDR decoding functions for NFSv2 Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100702171943.8761.37289.stgit@ellison.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).