NFS: Reduce the stack footprint of nfs_link()

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Trond Myklebust 2010-04-16 16:22:49 -04:00
Родитель aa49b4cf7d
Коммит 136f2627c9
2 изменённых файлов: 21 добавлений и 17 удалений

Просмотреть файл

@ -468,30 +468,32 @@ out:
static int static int
nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
{ {
struct nfs_fattr dir_attr, fattr;
struct nfs3_linkargs arg = { struct nfs3_linkargs arg = {
.fromfh = NFS_FH(inode), .fromfh = NFS_FH(inode),
.tofh = NFS_FH(dir), .tofh = NFS_FH(dir),
.toname = name->name, .toname = name->name,
.tolen = name->len .tolen = name->len
}; };
struct nfs3_linkres res = { struct nfs3_linkres res;
.dir_attr = &dir_attr,
.fattr = &fattr
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs3_procedures[NFS3PROC_LINK], .rpc_proc = &nfs3_procedures[NFS3PROC_LINK],
.rpc_argp = &arg, .rpc_argp = &arg,
.rpc_resp = &res, .rpc_resp = &res,
}; };
int status; int status = -ENOMEM;
dprintk("NFS call link %s\n", name->name); dprintk("NFS call link %s\n", name->name);
nfs_fattr_init(&dir_attr); res.fattr = nfs_alloc_fattr();
nfs_fattr_init(&fattr); res.dir_attr = nfs_alloc_fattr();
if (res.fattr == NULL || res.dir_attr == NULL)
goto out;
status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
nfs_post_op_update_inode(dir, &dir_attr); nfs_post_op_update_inode(dir, res.dir_attr);
nfs_post_op_update_inode(inode, &fattr); nfs_post_op_update_inode(inode, res.fattr);
out:
nfs_free_fattr(res.dir_attr);
nfs_free_fattr(res.fattr);
dprintk("NFS reply link: %d\n", status); dprintk("NFS reply link: %d\n", status);
return status; return status;
} }

Просмотреть файл

@ -2707,28 +2707,30 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
.name = name, .name = name,
.bitmask = server->attr_bitmask, .bitmask = server->attr_bitmask,
}; };
struct nfs_fattr fattr, dir_attr;
struct nfs4_link_res res = { struct nfs4_link_res res = {
.server = server, .server = server,
.fattr = &fattr,
.dir_attr = &dir_attr,
}; };
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK], .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LINK],
.rpc_argp = &arg, .rpc_argp = &arg,
.rpc_resp = &res, .rpc_resp = &res,
}; };
int status; int status = -ENOMEM;
res.fattr = nfs_alloc_fattr();
res.dir_attr = nfs_alloc_fattr();
if (res.fattr == NULL || res.dir_attr == NULL)
goto out;
nfs_fattr_init(res.fattr);
nfs_fattr_init(res.dir_attr);
status = nfs4_call_sync(server, &msg, &arg, &res, 1); status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (!status) { if (!status) {
update_changeattr(dir, &res.cinfo); update_changeattr(dir, &res.cinfo);
nfs_post_op_update_inode(dir, res.dir_attr); nfs_post_op_update_inode(dir, res.dir_attr);
nfs_post_op_update_inode(inode, res.fattr); nfs_post_op_update_inode(inode, res.fattr);
} }
out:
nfs_free_fattr(res.dir_attr);
nfs_free_fattr(res.fattr);
return status; return status;
} }