NFS: Reduce the stack footprint of nfs_proc_create
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
39967ddf19
commit
eb872f0c8e
118
fs/nfs/proc.c
118
fs/nfs/proc.c
@ -224,35 +224,60 @@ static int nfs_proc_readlink(struct inode *inode, struct page *page,
|
||||
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
|
||||
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
int flags, struct nameidata *nd)
|
||||
{
|
||||
struct nfs_fh fhandle;
|
||||
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 nfs_createdata *data;
|
||||
struct rpc_message msg = {
|
||||
.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);
|
||||
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);
|
||||
nfs_mark_for_revalidate(dir);
|
||||
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);
|
||||
return status;
|
||||
}
|
||||
@ -264,24 +289,12 @@ static int
|
||||
nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
|
||||
dev_t rdev)
|
||||
{
|
||||
struct nfs_fh fhandle;
|
||||
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 nfs_createdata *data;
|
||||
struct rpc_message msg = {
|
||||
.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);
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
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);
|
||||
nfs_mark_for_revalidate(dir);
|
||||
|
||||
if (status == -EINVAL && S_ISFIFO(mode)) {
|
||||
sattr->ia_mode = mode;
|
||||
nfs_fattr_init(&fattr);
|
||||
nfs_fattr_init(data->res.fattr);
|
||||
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 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);
|
||||
return status;
|
||||
}
|
||||
@ -440,31 +460,25 @@ nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
|
||||
static int
|
||||
nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
|
||||
{
|
||||
struct nfs_fh fhandle;
|
||||
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 nfs_createdata *data;
|
||||
struct rpc_message msg = {
|
||||
.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);
|
||||
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);
|
||||
nfs_mark_for_revalidate(dir);
|
||||
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);
|
||||
return status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user