[pnfs] [PATCH 1/2] NFS: Fix an illegal allocation...
Trond Myklebust
Trond.Myklebust at netapp.com
Mon Jul 14 23:39:25 EDT 2008
Routines that may be run in the NFS writeback path may not allocate memory
using GFP_KERNEL, since that may initiate more I/O in order to free up
resources.
Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
---
fs/nfs/nfs4proc.c | 9 +++++++++
fs/nfs/nfs4xdr.c | 3 +--
fs/nfs/pnfs.c | 3 ---
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7c3bc50..40f5eef 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5140,6 +5140,8 @@ static void nfs4_pnfs_layoutget_release(void *calldata)
dprintk("--> %s\n", __func__);
pnfs_layout_release(lo);
+ if (lgp->res.layout.buf != NULL)
+ free_page((unsigned long) lgp->res.layout.buf);
kfree(calldata);
dprintk("<-- %s\n", __func__);
}
@@ -5171,6 +5173,13 @@ static int nfs4_proc_pnfs_layoutget(struct nfs4_pnfs_layoutget *lgp)
dprintk("--> %s\n", __func__);
+ lgp->res.layout.buf = (void *)__get_free_page(GFP_KERNEL);
+ if (lgp->res.layout.buf == NULL) {
+ nfs4_pnfs_layoutget_release(lgp);
+ status = -ENOMEM;
+ goto out;
+ }
+
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task)) {
status = PTR_ERR(task);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 884c42d..50478b5 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -5562,8 +5562,7 @@ static int decode_pnfs_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
res->type,
res->layout.len);
- res->layout.buf = kmalloc(res->layout.len, GFP_KERNEL);
- if (!res->layout.buf)
+ if (res->layout.len > PAGE_SIZE)
return -ENOMEM;
READ_BUF(res->layout.len);
COPYMEM(res->layout.buf, res->layout.len);
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index afb3d71..79208e6 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1049,9 +1049,6 @@ get_out:
/* Done processing layoutget. Set the layout stateid */
pnfs_set_layout_stateid(lo, &res->stateid);
- /* res->layout.buf kalloc'ed by the xdr decoder? */
- kfree(res->layout.buf);
-
dprintk("%s end (err:%d) state 0x%lx lseg %p\n",
__func__, lgp->status, nfsi->pnfs_layout_state, lseg);
if (lgp->lsegpp)
More information about the pNFS
mailing list