summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/nfs_xdr.h4
-rw-r--r--include/linux/sunrpc/xdr.h87
2 files changed, 91 insertions, 0 deletions
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 6c82048e2acf..970ffa785f78 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -398,6 +398,7 @@ struct nfs4_lookup {
};
struct nfs4_open {
+ struct nfs4_client * op_client_state; /* request */
u32 op_share_access; /* request */
u32 op_opentype; /* request */
u32 op_createmode; /* request */
@@ -472,6 +473,7 @@ struct nfs4_setclientid {
char sc_netid[4]; /* request */
char sc_uaddr[24]; /* request */
u32 sc_cb_ident; /* request */
+ struct nfs4_client * sc_state; /* response */
};
struct nfs4_write {
@@ -504,8 +506,10 @@ struct nfs4_op {
struct nfs4_readlink readlink;
struct nfs4_remove remove;
struct nfs4_rename rename;
+ struct nfs4_client * renew;
struct nfs4_setattr setattr;
struct nfs4_setclientid setclientid;
+ struct nfs4_client * setclientid_confirm;
struct nfs4_write write;
} u;
};
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 0233988f40b4..74c5260b2343 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -155,6 +155,93 @@ typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
skb_reader_t *, skb_read_actor_t);
+/*
+ * Provide some simple tools for XDR buffer overflow-checking etc.
+ */
+struct xdr_stream {
+ uint32_t *p; /* start of available buffer */
+ struct xdr_buf *buf; /* XDR buffer to read/write */
+
+ uint32_t *end; /* end of available buffer space */
+ struct iovec *iov; /* pointer to the current iovec */
+};
+
+/*
+ * Initialize an xdr_stream for encoding data.
+ *
+ * Note: at the moment the RPC client only passes the length of our
+ * scratch buffer in the xdr_buf's header iovec. Previously this
+ * meant we needed to call xdr_adjust_iovec() after encoding the
+ * data. With the new scheme, the xdr_stream manages the details
+ * of the buffer length, and takes care of adjusting the iovec
+ * length for us.
+ */
+static inline void
+xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+{
+ struct iovec *iov = buf->head;
+
+ xdr->buf = buf;
+ xdr->iov = iov;
+ xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
+ buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
+ xdr->p = p;
+}
+
+/*
+ * Check that we have enough buffer space to encode 'nbytes' more
+ * bytes of data. If so, update the total xdr_buf length, and
+ * adjust the length of the current iovec.
+ */
+static inline uint32_t *
+xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
+{
+ uint32_t *p = xdr->p;
+ uint32_t *q;
+
+ /* align nbytes on the next 32-bit boundary */
+ nbytes += 3;
+ nbytes &= ~3;
+ q = p + (nbytes >> 2);
+ if (unlikely(q > xdr->end || q < p))
+ return NULL;
+ xdr->p = q;
+ xdr->iov->iov_len += nbytes;
+ xdr->buf->len += nbytes;
+ return p;
+}
+
+/*
+ * Initialize an xdr_stream for decoding data.
+ */
+static inline void
+xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
+{
+ struct iovec *iov = buf->head;
+ xdr->buf = buf;
+ xdr->iov = iov;
+ xdr->p = p;
+ xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
+}
+
+/*
+ * Check if the input buffer is long enough to enable us to decode
+ * 'nbytes' more bytes of data starting at the current position.
+ * If so return the current pointer, then update the current
+ * position.
+ */
+static inline uint32_t *
+xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
+{
+ uint32_t *p = xdr->p;
+ uint32_t *q = p + XDR_QUADLEN(nbytes);
+
+ if (unlikely(q > xdr->end || q < p))
+ return NULL;
+ xdr->p = q;
+ return p;
+}
+
#endif /* __KERNEL__ */
#endif /* _SUNRPC_XDR_H_ */