Re: [patch 7/13] Encode and decode arbitrary XDR arrays

From: Andreas Gruenbacher
Date: Wed Feb 16 2005 - 11:13:46 EST


On Tue, 2005-02-15 at 20:17, Trond Myklebust wrote:
> lau den 22.01.2005 Klokka 21:34 (+0100) skreiv Andreas Gruenbacher:
> > vanlig tekstdokument vedlegg (patches.suse)
> > Add xdr_encode_array2 and xdr_decode_array2 functions for encoding
> > end decoding arrays with arbitrary entries, such as acl entries. The
> > goal here is to do this without allocating a contiguous temporary
> > buffer.
>
> net/sunrpc/xdr.c:1024:3: warning: mixing declarations and code
> net/sunrpc/xdr.c:967:16: warning: bad constant expression
>
> Please don't use these gcc extensions in the kernel.

Andrew has anready fixed the "mixing declarations and code" thing. The
attached patch kmallocs the buffer if needed. This uglifies the code
quite a bit though...

Cheers,
--
Andreas Gruenbacher <agruen@xxxxxxx>
SUSE Labs, SUSE LINUX GMBH
Index: linux-2.6.11-rc3/net/sunrpc/xdr.c
===================================================================
--- linux-2.6.11-rc3.orig/net/sunrpc/xdr.c
+++ linux-2.6.11-rc3/net/sunrpc/xdr.c
@@ -964,10 +964,10 @@ static int
xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
struct xdr_array2_desc *desc, int encode)
{
- char elem[desc->elem_size], *c;
+ char *elem = NULL, *c;
unsigned int copied = 0, todo, avail_here;
struct page **ppages = NULL;
- int err = 0;
+ int err;

if (encode) {
if (xdr_encode_word(buf, base, desc->array_len) != 0)
@@ -1000,6 +1000,12 @@ xdr_xcode_array2(struct xdr_buf *buf, un
avail_here -= desc->elem_size;
}
if (avail_here) {
+ if (!elem) {
+ elem = kmalloc(desc->elem_size, GFP_KERNEL);
+ err = -ENOMEM;
+ if (!elem)
+ goto out;
+ }
if (encode) {
err = desc->xcode(desc, elem);
if (err)
@@ -1032,6 +1038,13 @@ xdr_xcode_array2(struct xdr_buf *buf, un
if (copied || avail_page < desc->elem_size) {
unsigned int l = min(avail_page,
desc->elem_size - copied);
+ if (!elem) {
+ elem = kmalloc(desc->elem_size,
+ GFP_KERNEL);
+ err = -ENOMEM;
+ if (!elem)
+ goto out;
+ }
if (encode) {
if (!copied) {
err = desc->xcode(desc, elem);
@@ -1065,6 +1078,13 @@ xdr_xcode_array2(struct xdr_buf *buf, un
if (avail_page) {
unsigned int l = min(avail_page,
desc->elem_size - copied);
+ if (!elem) {
+ elem = kmalloc(desc->elem_size,
+ GFP_KERNEL);
+ err = -ENOMEM;
+ if (!elem)
+ goto out;
+ }
if (encode) {
if (!copied) {
err = desc->xcode(desc, elem);
@@ -1124,8 +1144,11 @@ xdr_xcode_array2(struct xdr_buf *buf, un
todo -= desc->elem_size;
}
}
+ err = 0;

out:
+ if (elem)
+ kfree(elem);
if (ppages)
kunmap(*ppages);
return err;