Commit eb872f0c authored by Trond Myklebust's avatar Trond Myklebust

NFS: Reduce the stack footprint of nfs_proc_create

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 39967ddf
...@@ -224,35 +224,60 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page, ...@@ -224,35 +224,60 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page,
return status; return status;
} }
struct nfs_createdata {
struct nfs_createargs arg;
struct nfs_diropok res;
struct nfs_fh fhandle;
struct nfs_fattr fattr;
};
static struct nfs_createdata *nfs_alloc_createdata(struct inode *dir,
struct dentry *dentry, struct iattr *sattr)
{
struct nfs_createdata *data;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (data != NULL) {
data->arg.fh = NFS_FH(dir);
data->arg.name = dentry->d_name.name;
data->arg.len = dentry->d_name.len;
data->arg.sattr = sattr;
nfs_fattr_init(&data->fattr);
data->fhandle.size = 0;
data->res.fh = &data->fhandle;
data->res.fattr = &data->fattr;
}
return data;
};
static void nfs_free_createdata(const struct nfs_createdata *data)
{
kfree(data);
}
static int static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags, struct nameidata *nd) int flags, struct nameidata *nd)
{ {
struct nfs_fh fhandle; struct nfs_createdata *data;
struct nfs_fattr fattr;
struct nfs_createargs arg = {
.fh = NFS_FH(dir),
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs_diropok res = {
.fh = &fhandle,
.fattr = &fattr
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_CREATE], .rpc_proc = &nfs_procedures[NFSPROC_CREATE],
.rpc_argp = &arg,
.rpc_resp = &res,
}; };
int status; int status = -ENOMEM;
nfs_fattr_init(&fattr);
dprintk("NFS call create %s\n", dentry->d_name.name); dprintk("NFS call create %s\n", dentry->d_name.name);
data = nfs_alloc_createdata(dir, dentry, sattr);
if (data == NULL)
goto out;
msg.rpc_argp = &data->arg;
msg.rpc_resp = &data->res;
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir); nfs_mark_for_revalidate(dir);
if (status == 0) if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply create: %d\n", status); dprintk("NFS reply create: %d\n", status);
return status; return status;
} }
...@@ -264,24 +289,12 @@ static int ...@@ -264,24 +289,12 @@ static int
nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
dev_t rdev) dev_t rdev)
{ {
struct nfs_fh fhandle; struct nfs_createdata *data;
struct nfs_fattr fattr;
struct nfs_createargs arg = {
.fh = NFS_FH(dir),
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs_diropok res = {
.fh = &fhandle,
.fattr = &fattr
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_CREATE], .rpc_proc = &nfs_procedures[NFSPROC_CREATE],
.rpc_argp = &arg,
.rpc_resp = &res,
}; };
int status, mode; umode_t mode;
int status = -ENOMEM;
dprintk("NFS call mknod %s\n", dentry->d_name.name); dprintk("NFS call mknod %s\n", dentry->d_name.name);
...@@ -294,17 +307,24 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ...@@ -294,17 +307,24 @@ nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */ sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
} }
nfs_fattr_init(&fattr); data = nfs_alloc_createdata(dir, dentry, sattr);
if (data == NULL)
goto out;
msg.rpc_argp = &data->arg;
msg.rpc_resp = &data->res;
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir); nfs_mark_for_revalidate(dir);
if (status == -EINVAL && S_ISFIFO(mode)) { if (status == -EINVAL && S_ISFIFO(mode)) {
sattr->ia_mode = mode; sattr->ia_mode = mode;
nfs_fattr_init(&fattr); nfs_fattr_init(data->res.fattr);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
} }
if (status == 0) if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply mknod: %d\n", status); dprintk("NFS reply mknod: %d\n", status);
return status; return status;
} }
...@@ -440,31 +460,25 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, ...@@ -440,31 +460,25 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
static int static int
nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
{ {
struct nfs_fh fhandle; struct nfs_createdata *data;
struct nfs_fattr fattr;
struct nfs_createargs arg = {
.fh = NFS_FH(dir),
.name = dentry->d_name.name,
.len = dentry->d_name.len,
.sattr = sattr
};
struct nfs_diropok res = {
.fh = &fhandle,
.fattr = &fattr
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_MKDIR], .rpc_proc = &nfs_procedures[NFSPROC_MKDIR],
.rpc_argp = &arg,
.rpc_resp = &res,
}; };
int status; int status = -ENOMEM;
dprintk("NFS call mkdir %s\n", dentry->d_name.name); dprintk("NFS call mkdir %s\n", dentry->d_name.name);
nfs_fattr_init(&fattr); data = nfs_alloc_createdata(dir, dentry, sattr);
if (data == NULL)
goto out;
msg.rpc_argp = &data->arg;
msg.rpc_resp = &data->res;
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
nfs_mark_for_revalidate(dir); nfs_mark_for_revalidate(dir);
if (status == 0) if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
nfs_free_createdata(data);
out:
dprintk("NFS reply mkdir: %d\n", status); dprintk("NFS reply mkdir: %d\n", status);
return status; return status;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment