nfsd4: reduce do_open_lookup() stack usage
I get 320 bytes for struct svc_fh on x86_64, really a little large to be putting on the stack; kmalloc() instead. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Родитель
41fd1e42f8
Коммит
59deeb9e5a
|
@ -193,10 +193,13 @@ static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
|
||||||
static __be32
|
static __be32
|
||||||
do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
|
do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
|
||||||
{
|
{
|
||||||
struct svc_fh resfh;
|
struct svc_fh *resfh;
|
||||||
__be32 status;
|
__be32 status;
|
||||||
|
|
||||||
fh_init(&resfh, NFS4_FHSIZE);
|
resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
|
||||||
|
if (!resfh)
|
||||||
|
return nfserr_jukebox;
|
||||||
|
fh_init(resfh, NFS4_FHSIZE);
|
||||||
open->op_truncate = 0;
|
open->op_truncate = 0;
|
||||||
|
|
||||||
if (open->op_create) {
|
if (open->op_create) {
|
||||||
|
@ -221,7 +224,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
|
||||||
*/
|
*/
|
||||||
status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
|
status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
|
||||||
open->op_fname.len, &open->op_iattr,
|
open->op_fname.len, &open->op_iattr,
|
||||||
&resfh, open->op_createmode,
|
resfh, open->op_createmode,
|
||||||
(u32 *)open->op_verf.data,
|
(u32 *)open->op_verf.data,
|
||||||
&open->op_truncate, &open->op_created);
|
&open->op_truncate, &open->op_created);
|
||||||
|
|
||||||
|
@ -235,28 +238,29 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
|
||||||
FATTR4_WORD1_TIME_MODIFY);
|
FATTR4_WORD1_TIME_MODIFY);
|
||||||
} else {
|
} else {
|
||||||
status = nfsd_lookup(rqstp, current_fh,
|
status = nfsd_lookup(rqstp, current_fh,
|
||||||
open->op_fname.data, open->op_fname.len, &resfh);
|
open->op_fname.data, open->op_fname.len, resfh);
|
||||||
fh_unlock(current_fh);
|
fh_unlock(current_fh);
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
status = nfsd_check_obj_isreg(&resfh);
|
status = nfsd_check_obj_isreg(resfh);
|
||||||
}
|
}
|
||||||
if (status)
|
if (status)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (is_create_with_attrs(open) && open->op_acl != NULL)
|
if (is_create_with_attrs(open) && open->op_acl != NULL)
|
||||||
do_set_nfs4_acl(rqstp, &resfh, open->op_acl, open->op_bmval);
|
do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
|
||||||
|
|
||||||
/* set reply cache */
|
/* set reply cache */
|
||||||
fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
|
fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
|
||||||
&resfh.fh_handle);
|
&resfh->fh_handle);
|
||||||
if (!open->op_created)
|
if (!open->op_created)
|
||||||
status = do_open_permission(rqstp, &resfh, open,
|
status = do_open_permission(rqstp, resfh, open,
|
||||||
NFSD_MAY_NOP);
|
NFSD_MAY_NOP);
|
||||||
set_change_info(&open->op_cinfo, current_fh);
|
set_change_info(&open->op_cinfo, current_fh);
|
||||||
fh_dup2(current_fh, &resfh);
|
fh_dup2(current_fh, resfh);
|
||||||
out:
|
out:
|
||||||
fh_put(&resfh);
|
fh_put(resfh);
|
||||||
|
kfree(resfh);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче