aboutsummaryrefslogtreecommitdiff
path: root/net/sunrpc/sched.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:29:58 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-09 15:29:58 -0700
commitd0b6e0e380d6a32d479120a8b5d98cdff936ec8c (patch)
tree57b584f4ba8504eb39e9f12234fc78db7fff0477 /net/sunrpc/sched.c
parent5329571b3c978635f6d832cc884fdd61ff94e0da (diff)
parent7a13e932281e7042a592f4f14db0b348199e7aac (diff)
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: NFS: Kill the obsolete NFS_PARANOIA NFS: use __set_current_state() sunrpc: fix crash in rpc_malloc() NFS: Clean up NFSv4 XDR error message NFS: NFS client underestimates how large an NFSv4 SETATTR reply can be SUNRPC: Fix pointer arithmetic bug recently introduced in rpc_malloc/free NFS: Remove redundant check in nfs_check_verifier() NFS: Fix a jiffie wraparound issue
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r--net/sunrpc/sched.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 99014516b73c..b011eb625e49 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -736,6 +736,11 @@ static void rpc_async_schedule(struct work_struct *work)
__rpc_execute(container_of(work, struct rpc_task, u.tk_work));
}
+struct rpc_buffer {
+ size_t len;
+ char data[];
+};
+
/**
* rpc_malloc - allocate an RPC buffer
* @task: RPC task that will use this buffer
@@ -754,18 +759,22 @@ static void rpc_async_schedule(struct work_struct *work)
*/
void *rpc_malloc(struct rpc_task *task, size_t size)
{
- size_t *buf;
+ struct rpc_buffer *buf;
gfp_t gfp = RPC_IS_SWAPPER(task) ? GFP_ATOMIC : GFP_NOWAIT;
- size += sizeof(size_t);
+ size += sizeof(struct rpc_buffer);
if (size <= RPC_BUFFER_MAXSIZE)
buf = mempool_alloc(rpc_buffer_mempool, gfp);
else
buf = kmalloc(size, gfp);
- *buf = size;
+
+ if (!buf)
+ return NULL;
+
+ buf->len = size;
dprintk("RPC: %5u allocated buffer of size %zu at %p\n",
task->tk_pid, size, buf);
- return ++buf;
+ return &buf->data;
}
/**
@@ -775,15 +784,18 @@ void *rpc_malloc(struct rpc_task *task, size_t size)
*/
void rpc_free(void *buffer)
{
- size_t size, *buf = buffer;
+ size_t size;
+ struct rpc_buffer *buf;
if (!buffer)
return;
- size = *buf;
- buf--;
+
+ buf = container_of(buffer, struct rpc_buffer, data);
+ size = buf->len;
dprintk("RPC: freeing buffer of size %zu at %p\n",
size, buf);
+
if (size <= RPC_BUFFER_MAXSIZE)
mempool_free(buf, rpc_buffer_mempool);
else