From patchwork Mon May 16 16:21:42 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benny Halevy X-Patchwork-Id: 788622 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p4GGKjC6018574 for ; Mon, 16 May 2011 16:21:48 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750976Ab1EPQVp (ORCPT ); Mon, 16 May 2011 12:21:45 -0400 Received: from daytona.panasas.com ([67.152.220.89]:34589 "EHLO daytona.panasas.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750876Ab1EPQVp (ORCPT ); Mon, 16 May 2011 12:21:45 -0400 Received: from lt.bhalevy.com.com ([172.17.142.149]) by daytona.panasas.com with Microsoft SMTPSVC(6.0.3790.4675); Mon, 16 May 2011 12:21:44 -0400 From: Benny Halevy To: Trond Myklebust Cc: linux-nfs@vger.kernel.org, bharrosh@panasas.com Subject: [PATCH v3 08/29] NFSD: introduce exp_xdr.h Date: Mon, 16 May 2011 09:21:42 -0700 Message-Id: <1305562902-7584-1-git-send-email-bhalevy@panasas.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <4DD14D8E.1070701@panasas.com> References: <4DD14D8E.1070701@panasas.com> X-OriginalArrivalTime: 16 May 2011 16:21:44.0893 (UTC) FILETIME=[59065ED0:01CC13E5] Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 16 May 2011 16:21:48 +0000 (UTC) Containing xdr encoding helpers. Cc: J. Bruce Fields [nfsd: fix exp_xdr_encode_u64 parameter type] Reported-by: J. Bruce Fields [exportfs: exp_xdr.h: Use #include instead of ] Signed-off-by: Benny Halevy --- include/linux/exp_xdr.h | 141 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 141 insertions(+), 0 deletions(-) create mode 100644 include/linux/exp_xdr.h diff --git a/include/linux/exp_xdr.h b/include/linux/exp_xdr.h new file mode 100644 index 0000000..b69c309 --- /dev/null +++ b/include/linux/exp_xdr.h @@ -0,0 +1,141 @@ +#ifndef _LINUX_EXP_XDR_H +#define _LINUX_EXP_XDR_H + +#include +#include +#include + +struct exp_xdr_stream { + __be32 *p; + __be32 *end; +}; + +/** + * exp_xdr_qwords - Calculate the number of quad-words holding nbytes + * @nbytes: number of bytes to encode + */ +static inline size_t +exp_xdr_qwords(__u32 nbytes) +{ + return DIV_ROUND_UP(nbytes, 4); +} + +/** + * exp_xdr_qbytes - Calculate the number of bytes holding qwords + * @qwords: number of quad-words to encode + */ +static inline size_t +exp_xdr_qbytes(size_t qwords) +{ + return qwords << 2; +} + +/** + * exp_xdr_reserve_space - Reserve buffer space for sending + * @xdr: pointer to exp_xdr_stream + * @nbytes: number of bytes to reserve + * + * Checks that we have enough buffer space to encode 'nbytes' more + * bytes of data. If so, update the xdr stream. + */ +static inline __be32 * +exp_xdr_reserve_space(struct exp_xdr_stream *xdr, size_t nbytes) +{ + __be32 *p = xdr->p; + __be32 *q; + + /* align nbytes on the next 32-bit boundary */ + q = p + exp_xdr_qwords(nbytes); + if (unlikely(q > xdr->end || q < p)) + return NULL; + xdr->p = q; + return p; +} + +/** + * exp_xdr_reserve_qwords - Reserve buffer space for sending + * @xdr: pointer to exp_xdr_stream + * @nwords: number of quad words (u32's) to reserve + */ +static inline __be32 * +exp_xdr_reserve_qwords(struct exp_xdr_stream *xdr, size_t qwords) +{ + return exp_xdr_reserve_space(xdr, exp_xdr_qbytes(qwords)); +} + +/** + * exp_xdr_encode_u32 - Encode an unsigned 32-bit value onto a xdr stream + * @p: pointer to encoding destination + * @val: value to encode + */ +static inline __be32 * +exp_xdr_encode_u32(__be32 *p, __u32 val) +{ + *p = cpu_to_be32(val); + return p + 1; +} + +/** + * exp_xdr_encode_u64 - Encode an unsigned 64-bit value onto a xdr stream + * @p: pointer to encoding destination + * @val: value to encode + */ +static inline __be32 * +exp_xdr_encode_u64(__be32 *p, __u64 val) +{ + put_unaligned_be64(val, p); + return p + 2; +} + +/** + * exp_xdr_encode_bytes - Encode an array of bytes onto a xdr stream + * @p: pointer to encoding destination + * @ptr: pointer to the array of bytes + * @nbytes: number of bytes to encode + */ +static inline __be32 * +exp_xdr_encode_bytes(__be32 *p, const void *ptr, __u32 nbytes) +{ + if (likely(nbytes != 0)) { + unsigned int qwords = exp_xdr_qwords(nbytes); + unsigned int padding = exp_xdr_qbytes(qwords) - nbytes; + + memcpy(p, ptr, nbytes); + if (padding != 0) + memset((char *)p + nbytes, 0, padding); + p += qwords; + } + return p; +} + +/** + * exp_xdr_encode_opaque - Encode an opaque type onto a xdr stream + * @p: pointer to encoding destination + * @ptr: pointer to the opaque array + * @nbytes: number of bytes to encode + * + * Encodes the 32-bit opaque size in bytes followed by the opaque value. + */ +static inline __be32 * +exp_xdr_encode_opaque(__be32 *p, const void *ptr, __u32 nbytes) +{ + p = exp_xdr_encode_u32(p, nbytes); + return exp_xdr_encode_bytes(p, ptr, nbytes); +} + +/** + * exp_xdr_encode_opaque_qlen - Encode the opaque length onto a xdr stream + * @lenp: pointer to the opaque length destination + * @endp: pointer to the end of the opaque array + * + * Encodes the 32-bit opaque size in bytes given the start and end pointers + */ +static inline __be32 * +exp_xdr_encode_opaque_len(__be32 *lenp, const void *endp) +{ + size_t nbytes = (char *)endp - (char *)(lenp + 1); + + exp_xdr_encode_u32(lenp, nbytes); + return lenp + 1 + exp_xdr_qwords(nbytes); +} +#endif /* _LINUX_EXP_XDR_H */