don't allocate struct statvfs on stack as it's too large.
This commit is contained in:
parent
fa6adb2a78
commit
7729c57a0f
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.240 2006/05/04 17:48:56 christos Exp $ */
|
||||
/* $NetBSD: vfs_syscalls.c,v 1.241 2006/05/10 11:02:29 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.240 2006/05/04 17:48:56 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.241 2006/05/10 11:02:29 yamt Exp $");
|
||||
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_43.h"
|
||||
@ -778,7 +778,7 @@ sys_statvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct mount *mp;
|
||||
struct statvfs sbuf;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
@ -787,9 +787,13 @@ sys_statvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
return error;
|
||||
mp = nd.ni_vp->v_mount;
|
||||
vrele(nd.ni_vp);
|
||||
if ((error = dostatvfs(mp, &sbuf, l, SCARG(uap, flags), 1)) != 0)
|
||||
return error;
|
||||
return copyout(&sbuf, SCARG(uap, buf), sizeof(sbuf));
|
||||
sb = STATVFSBUF_GET();
|
||||
error = dostatvfs(mp, sb, l, SCARG(uap, flags), 1);
|
||||
if (error == 0) {
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
}
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -807,18 +811,20 @@ sys_fstatvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
struct proc *p = l->l_proc;
|
||||
struct file *fp;
|
||||
struct mount *mp;
|
||||
struct statvfs sbuf;
|
||||
struct statvfs *sb;
|
||||
int error;
|
||||
|
||||
/* getvnode() will use the descriptor for us */
|
||||
if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
|
||||
return (error);
|
||||
mp = ((struct vnode *)fp->f_data)->v_mount;
|
||||
if ((error = dostatvfs(mp, &sbuf, l, SCARG(uap, flags), 1)) != 0)
|
||||
sb = STATVFSBUF_GET();
|
||||
if ((error = dostatvfs(mp, sb, l, SCARG(uap, flags), 1)) != 0)
|
||||
goto out;
|
||||
error = copyout(&sbuf, SCARG(uap, buf), sizeof(sbuf));
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
out:
|
||||
FILE_UNUSE(fp, l);
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -837,11 +843,12 @@ sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
||||
int root = 0;
|
||||
struct proc *p = l->l_proc;
|
||||
struct mount *mp, *nmp;
|
||||
struct statvfs sbuf;
|
||||
struct statvfs *sb;
|
||||
struct statvfs *sfsp;
|
||||
size_t count, maxcount;
|
||||
int error = 0;
|
||||
|
||||
sb = STATVFSBUF_GET();
|
||||
maxcount = SCARG(uap, bufsize) / sizeof(struct statvfs);
|
||||
sfsp = SCARG(uap, buf);
|
||||
simple_lock(&mountlist_slock);
|
||||
@ -853,20 +860,20 @@ sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
||||
continue;
|
||||
}
|
||||
if (sfsp && count < maxcount) {
|
||||
error = dostatvfs(mp, &sbuf, l, SCARG(uap, flags), 0);
|
||||
error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0);
|
||||
if (error) {
|
||||
simple_lock(&mountlist_slock);
|
||||
nmp = CIRCLEQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp);
|
||||
continue;
|
||||
}
|
||||
error = copyout(&sbuf, sfsp, sizeof(*sfsp));
|
||||
error = copyout(sb, sfsp, sizeof(*sfsp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
sfsp++;
|
||||
root |= strcmp(sbuf.f_mntonname, "/") == 0;
|
||||
root |= strcmp(sb->f_mntonname, "/") == 0;
|
||||
}
|
||||
count++;
|
||||
simple_lock(&mountlist_slock);
|
||||
@ -878,17 +885,19 @@ sys_getvfsstat(struct lwp *l, void *v, register_t *retval)
|
||||
/*
|
||||
* fake a root entry
|
||||
*/
|
||||
if ((error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, &sbuf, l,
|
||||
if ((error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount, sb, l,
|
||||
SCARG(uap, flags), 1)) != 0)
|
||||
return error;
|
||||
goto out;
|
||||
if (sfsp)
|
||||
error = copyout(&sbuf, sfsp, sizeof(*sfsp));
|
||||
error = copyout(sb, sfsp, sizeof(*sfsp));
|
||||
count++;
|
||||
}
|
||||
if (sfsp && count > maxcount)
|
||||
*retval = maxcount;
|
||||
else
|
||||
*retval = count;
|
||||
out:
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -1418,7 +1427,7 @@ sys_fhstatvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
syscallarg(int) flags;
|
||||
} */ *uap = v;
|
||||
struct proc *p = l->l_proc;
|
||||
struct statvfs sbuf;
|
||||
struct statvfs *sb;
|
||||
fhandle_t fh;
|
||||
struct mount *mp;
|
||||
struct vnode *vp;
|
||||
@ -1441,12 +1450,16 @@ sys_fhstatvfs1(struct lwp *l, void *v, register_t *retval)
|
||||
return error;
|
||||
|
||||
mp = vp->v_mount;
|
||||
if ((error = dostatvfs(mp, &sbuf, l, SCARG(uap, flags), 1)) != 0) {
|
||||
sb = STATVFSBUF_GET();
|
||||
if ((error = dostatvfs(mp, sb, l, SCARG(uap, flags), 1)) != 0) {
|
||||
vput(vp);
|
||||
return error;
|
||||
goto out;
|
||||
}
|
||||
vput(vp);
|
||||
return copyout(&sbuf, SCARG(uap, buf), sizeof(sbuf));
|
||||
error = copyout(sb, SCARG(uap, buf), sizeof(*sb));
|
||||
out:
|
||||
STATVFSBUF_PUT(sb);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: statvfs.h,v 1.9 2006/02/12 01:32:07 chs Exp $ */
|
||||
/* $NetBSD: statvfs.h,v 1.10 2006/05/10 11:02:29 yamt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
@ -167,4 +167,10 @@ int fhstatvfs1(const fhandle_t *, struct statvfs *, int);
|
||||
#endif /* _NETBSD_SOURCE */
|
||||
__END_DECLS
|
||||
#endif /* _KERNEL || _STANDALONE */
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#define STATVFSBUF_GET() malloc(sizeof(struct statvfs), M_TEMP, M_WAITOK)
|
||||
#define STATVFSBUF_PUT(sb) free(sb, M_TEMP);
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
#endif /* !_SYS_STATVFS_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user