Do not allocate struct statfs on kernel stack.

Right now size of the structure is 472 bytes on amd64, which is
already large and stack allocations are indesirable.  With the ino64
work, MNAMELEN is increased to 1024, which will make it impossible to have
struct statfs on the stack.

Extracted from:	ino64 work by gleb
Discussed with:	mckusick
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2017-01-05 17:19:26 +00:00
parent 2677b6e77f
commit 2f304845e2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=311452
13 changed files with 257 additions and 172 deletions

View File

@ -265,7 +265,7 @@ freebsd4_freebsd32_getfsstat(struct thread *td,
uap->buf++;
copycount--;
}
free(buf, M_TEMP);
free(buf, M_STATFS);
}
if (error == 0)
td->td_retval[0] = count;
@ -1394,14 +1394,17 @@ int
freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
{
struct statfs32 s32;
struct statfs s;
struct statfs *sp;
int error;
error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
if (error)
return (error);
copy_statfs(&s, &s32);
return (copyout(&s32, uap->buf, sizeof(s32)));
sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, uap->path, UIO_USERSPACE, sp);
if (error == 0) {
copy_statfs(sp, &s32);
error = copyout(&s32, uap->buf, sizeof(s32));
}
free(sp, M_STATFS);
return (error);
}
#endif
@ -1410,14 +1413,17 @@ int
freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
{
struct statfs32 s32;
struct statfs s;
struct statfs *sp;
int error;
error = kern_fstatfs(td, uap->fd, &s);
if (error)
return (error);
copy_statfs(&s, &s32);
return (copyout(&s32, uap->buf, sizeof(s32)));
sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, sp);
if (error == 0) {
copy_statfs(sp, &s32);
error = copyout(&s32, uap->buf, sizeof(s32));
}
free(sp, M_STATFS);
return (error);
}
#endif
@ -1426,17 +1432,20 @@ int
freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
{
struct statfs32 s32;
struct statfs s;
struct statfs *sp;
fhandle_t fh;
int error;
if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
return (error);
error = kern_fhstatfs(td, fh, &s);
if (error)
return (error);
copy_statfs(&s, &s32);
return (copyout(&s32, uap->buf, sizeof(s32)));
sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fhstatfs(td, fh, sp);
if (error == 0) {
copy_statfs(sp, &s32);
error = copyout(&s32, uap->buf, sizeof(s32));
}
free(sp, M_STATFS);
return (error);
}
#endif

View File

@ -415,7 +415,7 @@ int
linux_statfs(struct thread *td, struct linux_statfs_args *args)
{
struct l_statfs linux_statfs;
struct statfs bsd_statfs;
struct statfs *bsd_statfs;
char *path;
int error;
@ -425,12 +425,13 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args)
if (ldebug(statfs))
printf(ARGS(statfs, "%s, *"), path);
#endif
error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs);
bsd_statfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, path, UIO_SYSSPACE, bsd_statfs);
LFREEPATH(path);
if (error)
return (error);
error = bsd_to_linux_statfs(&bsd_statfs, &linux_statfs);
if (error)
if (error == 0)
error = bsd_to_linux_statfs(bsd_statfs, &linux_statfs);
free(bsd_statfs, M_STATFS);
if (error != 0)
return (error);
return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs)));
}
@ -456,7 +457,7 @@ int
linux_statfs64(struct thread *td, struct linux_statfs64_args *args)
{
struct l_statfs64 linux_statfs;
struct statfs bsd_statfs;
struct statfs *bsd_statfs;
char *path;
int error;
@ -469,11 +470,14 @@ linux_statfs64(struct thread *td, struct linux_statfs64_args *args)
if (ldebug(statfs64))
printf(ARGS(statfs64, "%s, *"), path);
#endif
error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs);
bsd_statfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, path, UIO_SYSSPACE, bsd_statfs);
LFREEPATH(path);
if (error)
if (error == 0)
bsd_to_linux_statfs64(bsd_statfs, &linux_statfs);
free(bsd_statfs, M_STATFS);
if (error != 0)
return (error);
bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs);
return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs)));
}
@ -481,7 +485,7 @@ int
linux_fstatfs64(struct thread *td, struct linux_fstatfs64_args *args)
{
struct l_statfs64 linux_statfs;
struct statfs bsd_statfs;
struct statfs *bsd_statfs;
int error;
#ifdef DEBUG
@ -491,10 +495,13 @@ linux_fstatfs64(struct thread *td, struct linux_fstatfs64_args *args)
if (args->bufsize != sizeof(struct l_statfs64))
return (EINVAL);
error = kern_fstatfs(td, args->fd, &bsd_statfs);
if (error)
return error;
bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs);
bsd_statfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, args->fd, bsd_statfs);
if (error == 0)
bsd_to_linux_statfs64(bsd_statfs, &linux_statfs);
free(bsd_statfs, M_STATFS);
if (error != 0)
return (error);
return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs)));
}
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
@ -503,18 +510,19 @@ int
linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args)
{
struct l_statfs linux_statfs;
struct statfs bsd_statfs;
struct statfs *bsd_statfs;
int error;
#ifdef DEBUG
if (ldebug(fstatfs))
printf(ARGS(fstatfs, "%d, *"), args->fd);
#endif
error = kern_fstatfs(td, args->fd, &bsd_statfs);
if (error)
return (error);
error = bsd_to_linux_statfs(&bsd_statfs, &linux_statfs);
if (error)
bsd_statfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, args->fd, bsd_statfs);
if (error == 0)
error = bsd_to_linux_statfs(bsd_statfs, &linux_statfs);
free(bsd_statfs, M_STATFS);
if (error != 0)
return (error);
return (copyout(&linux_statfs, args->buf, sizeof(linux_statfs)));
}

View File

@ -1430,17 +1430,20 @@ svr4_sys_statvfs(td, uap)
struct svr4_sys_statvfs_args *uap;
{
struct svr4_statvfs sfs;
struct statfs bfs;
struct statfs *bfs;
char *path;
int error;
CHECKALTEXIST(td, uap->path, &path);
error = kern_statfs(td, path, UIO_SYSSPACE, &bfs);
bfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, path, UIO_SYSSPACE, bfs);
free(path, M_TEMP);
if (error)
if (error == 0)
bsd_statfs_to_svr4_statvfs(bfs, &sfs);
free(bfs, M_STATFS);
if (error != 0)
return (error);
bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
return copyout(&sfs, uap->fs, sizeof(sfs));
}
@ -1451,13 +1454,16 @@ svr4_sys_fstatvfs(td, uap)
struct svr4_sys_fstatvfs_args *uap;
{
struct svr4_statvfs sfs;
struct statfs bfs;
struct statfs *bfs;
int error;
error = kern_fstatfs(td, uap->fd, &bfs);
if (error)
bfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, bfs);
if (error == 0)
bsd_statfs_to_svr4_statvfs(bfs, &sfs);
free(bfs, M_STATFS);
if (error != 0)
return (error);
bsd_statfs_to_svr4_statvfs(&bfs, &sfs);
return copyout(&sfs, uap->fs, sizeof(sfs));
}
@ -1468,17 +1474,20 @@ svr4_sys_statvfs64(td, uap)
struct svr4_sys_statvfs64_args *uap;
{
struct svr4_statvfs64 sfs;
struct statfs bfs;
struct statfs *bfs;
char *path;
int error;
CHECKALTEXIST(td, uap->path, &path);
error = kern_statfs(td, path, UIO_SYSSPACE, &bfs);
bfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, path, UIO_SYSSPACE, bfs);
free(path, M_TEMP);
if (error)
if (error == 0)
bsd_statfs_to_svr4_statvfs64(bfs, &sfs);
free(bfs, M_STATFS);
if (error != 0)
return (error);
bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
return copyout(&sfs, uap->fs, sizeof(sfs));
}
@ -1489,13 +1498,16 @@ svr4_sys_fstatvfs64(td, uap)
struct svr4_sys_fstatvfs64_args *uap;
{
struct svr4_statvfs64 sfs;
struct statfs bfs;
struct statfs *bfs;
int error;
error = kern_fstatfs(td, uap->fd, &bfs);
if (error)
bfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, bfs);
if (error == 0)
bsd_statfs_to_svr4_statvfs64(bfs, &sfs);
free(bfs, M_STATFS);
if (error != 0)
return (error);
bsd_statfs_to_svr4_statvfs64(&bfs, &sfs);
return copyout(&sfs, uap->fs, sizeof(sfs));
}

View File

@ -2047,7 +2047,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
nfsattrbit_t *retbitp = &retbits;
u_int32_t freenum, *retnump;
u_int64_t uquad;
struct statfs fs;
struct statfs *fs;
struct nfsfsinfo fsinf;
struct timespec temptime;
NFSACL_T *aclp, *naclp = NULL;
@ -2079,11 +2079,13 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
/*
* Get the VFS_STATFS(), since some attributes need them.
*/
fs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
if (NFSISSETSTATFS_ATTRBIT(retbitp)) {
error = VFS_STATFS(mp, &fs);
error = VFS_STATFS(mp, fs);
if (error != 0) {
if (reterr) {
nd->nd_repstat = NFSERR_ACCES;
free(fs, M_STATFS);
return (0);
}
NFSCLRSTATFS_ATTRBIT(retbitp);
@ -2115,6 +2117,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
if (error != 0) {
if (reterr) {
nd->nd_repstat = NFSERR_ACCES;
free(fs, M_STATFS);
return (0);
}
NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACL);
@ -2256,7 +2259,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
/*
* Check quota and use min(quota, f_ffree).
*/
freenum = fs.f_ffree;
freenum = fs->f_ffree;
#ifdef QUOTA
/*
* ufs_quotactl() insists that the uid argument
@ -2279,13 +2282,13 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
case NFSATTRBIT_FILESFREE:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
*tl++ = 0;
*tl = txdr_unsigned(fs.f_ffree);
*tl = txdr_unsigned(fs->f_ffree);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_FILESTOTAL:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
*tl++ = 0;
*tl = txdr_unsigned(fs.f_files);
*tl = txdr_unsigned(fs->f_files);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_FSLOCATIONS:
@ -2361,9 +2364,9 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
break;
case NFSATTRBIT_QUOTAHARD:
if (priv_check_cred(cred, PRIV_VFS_EXCEEDQUOTA, 0))
freenum = fs.f_bfree;
freenum = fs->f_bfree;
else
freenum = fs.f_bavail;
freenum = fs->f_bavail;
#ifdef QUOTA
/*
* ufs_quotactl() insists that the uid argument
@ -2379,15 +2382,15 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
#endif /* QUOTA */
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
uquad = (u_int64_t)freenum;
NFSQUOTABLKTOBYTE(uquad, fs.f_bsize);
NFSQUOTABLKTOBYTE(uquad, fs->f_bsize);
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_QUOTASOFT:
if (priv_check_cred(cred, PRIV_VFS_EXCEEDQUOTA, 0))
freenum = fs.f_bfree;
freenum = fs->f_bfree;
else
freenum = fs.f_bavail;
freenum = fs->f_bavail;
#ifdef QUOTA
/*
* ufs_quotactl() insists that the uid argument
@ -2403,7 +2406,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
#endif /* QUOTA */
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
uquad = (u_int64_t)freenum;
NFSQUOTABLKTOBYTE(uquad, fs.f_bsize);
NFSQUOTABLKTOBYTE(uquad, fs->f_bsize);
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
@ -2424,7 +2427,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
#endif /* QUOTA */
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
uquad = (u_int64_t)freenum;
NFSQUOTABLKTOBYTE(uquad, fs.f_bsize);
NFSQUOTABLKTOBYTE(uquad, fs->f_bsize);
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
@ -2437,24 +2440,24 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
case NFSATTRBIT_SPACEAVAIL:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
if (priv_check_cred(cred, PRIV_VFS_BLOCKRESERVE, 0))
uquad = (u_int64_t)fs.f_bfree;
uquad = (u_int64_t)fs->f_bfree;
else
uquad = (u_int64_t)fs.f_bavail;
uquad *= fs.f_bsize;
uquad = (u_int64_t)fs->f_bavail;
uquad *= fs->f_bsize;
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_SPACEFREE:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
uquad = (u_int64_t)fs.f_bfree;
uquad *= fs.f_bsize;
uquad = (u_int64_t)fs->f_bfree;
uquad *= fs->f_bsize;
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
case NFSATTRBIT_SPACETOTAL:
NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
uquad = (u_int64_t)fs.f_blocks;
uquad *= fs.f_bsize;
uquad = (u_int64_t)fs->f_blocks;
uquad *= fs->f_bsize;
txdr_hyper(uquad, tl);
retnum += NFSX_HYPER;
break;
@ -2531,6 +2534,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
}
if (naclp != NULL)
acl_free(naclp);
free(fs, M_STATFS);
*retnump = txdr_unsigned(retnum);
return (retnum + prefixnum);
}

View File

@ -2035,14 +2035,14 @@ nfsrvd_statfs(struct nfsrv_descript *nd, __unused int isdgram,
u_int32_t *tl;
int getret = 1;
struct nfsvattr at;
struct statfs sfs;
u_quad_t tval;
sf = NULL;
if (nd->nd_repstat) {
nfsrv_postopattr(nd, getret, &at);
goto out;
}
sf = &sfs;
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
nd->nd_repstat = nfsvno_statfs(vp, sf);
getret = nfsvno_getattr(vp, &at, nd->nd_cred, p, 1);
vput(vp);
@ -2078,6 +2078,7 @@ nfsrvd_statfs(struct nfsrv_descript *nd, __unused int isdgram,
}
out:
free(sf, M_STATFS);
NFSEXITCODE2(0, nd);
return (0);
}
@ -3603,19 +3604,20 @@ nfsrvd_verify(struct nfsrv_descript *nd, int isdgram,
{
int error = 0, ret, fhsize = NFSX_MYFH;
struct nfsvattr nva;
struct statfs sf;
struct statfs *sf;
struct nfsfsinfo fs;
fhandle_t fh;
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_statfs(vp, &sf);
nd->nd_repstat = nfsvno_statfs(vp, sf);
if (!nd->nd_repstat)
nd->nd_repstat = nfsvno_getfh(vp, &fh, p);
if (!nd->nd_repstat) {
nfsvno_getfs(&fs, isdgram);
error = nfsv4_loadattr(nd, vp, &nva, NULL, &fh, fhsize, NULL,
&sf, NULL, &fs, NULL, 1, &ret, NULL, NULL, p, nd->nd_cred);
sf, NULL, &fs, NULL, 1, &ret, NULL, NULL, p, nd->nd_cred);
if (!error) {
if (nd->nd_procnum == NFSV4OP_NVERIFY) {
if (ret == 0)
@ -3627,6 +3629,7 @@ nfsrvd_verify(struct nfsrv_descript *nd, int isdgram,
}
}
vput(vp);
free(sf, M_STATFS);
NFSEXITCODE2(error, nd);
return (error);
}

View File

@ -301,29 +301,33 @@ nullfs_statfs(mp, sbp)
struct statfs *sbp;
{
int error;
struct statfs mstat;
struct statfs *mstat;
NULLFSDEBUG("nullfs_statfs(mp = %p, vp = %p->%p)\n", (void *)mp,
(void *)MOUNTTONULLMOUNT(mp)->nullm_rootvp,
(void *)NULLVPTOLOWERVP(MOUNTTONULLMOUNT(mp)->nullm_rootvp));
bzero(&mstat, sizeof(mstat));
mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO);
error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat);
if (error)
error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, mstat);
if (error) {
free(mstat, M_STATFS);
return (error);
}
/* now copy across the "interesting" information and fake the rest */
sbp->f_type = mstat.f_type;
sbp->f_type = mstat->f_type;
sbp->f_flags = (sbp->f_flags & (MNT_RDONLY | MNT_NOEXEC | MNT_NOSUID |
MNT_UNION | MNT_NOSYMFOLLOW)) | (mstat.f_flags & ~MNT_ROOTFS);
sbp->f_bsize = mstat.f_bsize;
sbp->f_iosize = mstat.f_iosize;
sbp->f_blocks = mstat.f_blocks;
sbp->f_bfree = mstat.f_bfree;
sbp->f_bavail = mstat.f_bavail;
sbp->f_files = mstat.f_files;
sbp->f_ffree = mstat.f_ffree;
MNT_UNION | MNT_NOSYMFOLLOW)) | (mstat->f_flags & ~MNT_ROOTFS);
sbp->f_bsize = mstat->f_bsize;
sbp->f_iosize = mstat->f_iosize;
sbp->f_blocks = mstat->f_blocks;
sbp->f_bfree = mstat->f_bfree;
sbp->f_bavail = mstat->f_bavail;
sbp->f_files = mstat->f_files;
sbp->f_ffree = mstat->f_ffree;
free(mstat, M_STATFS);
return (0);
}

View File

@ -390,7 +390,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp)
{
struct unionfs_mount *ump;
int error;
struct statfs mstat;
struct statfs *mstat;
uint64_t lbsize;
ump = MOUNTTOUNIONFSMOUNT(mp);
@ -398,39 +398,47 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp)
UNIONFSDEBUG("unionfs_statfs(mp = %p, lvp = %p, uvp = %p)\n",
(void *)mp, (void *)ump->um_lowervp, (void *)ump->um_uppervp);
bzero(&mstat, sizeof(mstat));
mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO);
error = VFS_STATFS(ump->um_lowervp->v_mount, &mstat);
if (error)
error = VFS_STATFS(ump->um_lowervp->v_mount, mstat);
if (error) {
free(mstat, M_STATFS);
return (error);
}
/* now copy across the "interesting" information and fake the rest */
sbp->f_blocks = mstat.f_blocks;
sbp->f_files = mstat.f_files;
sbp->f_blocks = mstat->f_blocks;
sbp->f_files = mstat->f_files;
lbsize = mstat.f_bsize;
lbsize = mstat->f_bsize;
error = VFS_STATFS(ump->um_uppervp->v_mount, &mstat);
if (error)
error = VFS_STATFS(ump->um_uppervp->v_mount, mstat);
if (error) {
free(mstat, M_STATFS);
return (error);
}
/*
* The FS type etc is copy from upper vfs.
* (write able vfs have priority)
*/
sbp->f_type = mstat.f_type;
sbp->f_flags = mstat.f_flags;
sbp->f_bsize = mstat.f_bsize;
sbp->f_iosize = mstat.f_iosize;
sbp->f_type = mstat->f_type;
sbp->f_flags = mstat->f_flags;
sbp->f_bsize = mstat->f_bsize;
sbp->f_iosize = mstat->f_iosize;
if (mstat.f_bsize != lbsize)
sbp->f_blocks = ((off_t)sbp->f_blocks * lbsize) / mstat.f_bsize;
if (mstat->f_bsize != lbsize)
sbp->f_blocks = ((off_t)sbp->f_blocks * lbsize) /
mstat->f_bsize;
sbp->f_blocks += mstat.f_blocks;
sbp->f_bfree = mstat.f_bfree;
sbp->f_bavail = mstat.f_bavail;
sbp->f_files += mstat.f_files;
sbp->f_ffree = mstat.f_ffree;
sbp->f_blocks += mstat->f_blocks;
sbp->f_bfree = mstat->f_bfree;
sbp->f_bavail = mstat->f_bavail;
sbp->f_files += mstat->f_files;
sbp->f_ffree = mstat->f_ffree;
free(mstat, M_STATFS);
return (0);
}

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/malloc.h>
#include <sys/vnode.h>
@ -108,16 +109,18 @@ ibcs2_statfs(td, uap)
struct thread *td;
struct ibcs2_statfs_args *uap;
{
struct statfs sf;
struct statfs *sf;
char *path;
int error;
CHECKALTEXIST(td, uap->path, &path);
error = kern_statfs(td, path, UIO_SYSSPACE, &sf);
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, path, UIO_SYSSPACE, sf);
free(path, M_TEMP);
if (error)
return (error);
return cvt_statfs(&sf, (caddr_t)uap->buf, uap->len);
if (error == 0)
error = cvt_statfs(sf, (caddr_t)uap->buf, uap->len);
free(sf, M_STATFS);
return (error);
}
int
@ -125,13 +128,15 @@ ibcs2_fstatfs(td, uap)
struct thread *td;
struct ibcs2_fstatfs_args *uap;
{
struct statfs sf;
struct statfs *sf;
int error;
error = kern_fstatfs(td, uap->fd, &sf);
if (error)
return (error);
return cvt_statfs(&sf, (caddr_t)uap->buf, uap->len);
sf = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, sf);
if (error == 0)
error = cvt_statfs(sf, (caddr_t)uap->buf, uap->len);
free(sf, M_STATFS);
return (error);
}
int

View File

@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kthread.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@ -552,7 +553,7 @@ encode_long(long val)
static void
acctwatch(void)
{
struct statfs sb;
struct statfs *sp;
sx_assert(&acct_sx, SX_XLOCKED);
@ -580,21 +581,25 @@ acctwatch(void)
* Stopping here is better than continuing, maybe it will be VBAD
* next time around.
*/
if (VFS_STATFS(acct_vp->v_mount, &sb) < 0)
sp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
if (VFS_STATFS(acct_vp->v_mount, sp) < 0) {
free(sp, M_STATFS);
return;
}
if (acct_suspended) {
if (sb.f_bavail > (int64_t)(acctresume * sb.f_blocks /
if (sp->f_bavail > (int64_t)(acctresume * sp->f_blocks /
100)) {
acct_suspended = 0;
log(LOG_NOTICE, "Accounting resumed\n");
}
} else {
if (sb.f_bavail <= (int64_t)(acctsuspend * sb.f_blocks /
if (sp->f_bavail <= (int64_t)(acctsuspend * sp->f_blocks /
100)) {
acct_suspended = 1;
log(LOG_NOTICE, "Accounting suspended\n");
}
}
free(sp, M_STATFS);
}
/*

View File

@ -931,7 +931,8 @@ int
vop_stdallocate(struct vop_allocate_args *ap)
{
#ifdef __notyet__
struct statfs sfs;
struct statfs *sfs;
off_t maxfilesize = 0;
#endif
struct iovec aiov;
struct vattr vattr, *vap;
@ -967,12 +968,16 @@ vop_stdallocate(struct vop_allocate_args *ap)
* Check if the filesystem sets f_maxfilesize; if not use
* VOP_SETATTR to perform the check.
*/
error = VFS_STATFS(vp->v_mount, &sfs, td);
sfs = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = VFS_STATFS(vp->v_mount, sfs, td);
if (error == 0)
maxfilesize = sfs->f_maxfilesize;
free(sfs, M_STATFS);
if (error != 0)
goto out;
if (sfs.f_maxfilesize) {
if (offset > sfs.f_maxfilesize || len > sfs.f_maxfilesize ||
offset + len > sfs.f_maxfilesize) {
if (maxfilesize) {
if (offset > maxfilesize || len > maxfilesize ||
offset + len > maxfilesize) {
error = EFBIG;
goto out;
}

View File

@ -79,6 +79,7 @@ SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
"Unprivileged users may mount and unmount file systems");
MALLOC_DEFINE(M_MOUNT, "mount", "vfs mount structure");
MALLOC_DEFINE(M_STATFS, "statfs", "statfs structure");
static uma_zone_t mount_zone;
/* List of mounted filesystems. */

View File

@ -298,12 +298,14 @@ sys_statfs(td, uap)
struct statfs *buf;
} */ *uap;
{
struct statfs sf;
struct statfs *sfp;
int error;
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
if (error == 0)
error = copyout(&sf, uap->buf, sizeof(sf));
error = copyout(sfp, uap->buf, sizeof(struct statfs));
free(sfp, M_STATFS);
return (error);
}
@ -344,12 +346,14 @@ sys_fstatfs(td, uap)
struct statfs *buf;
} */ *uap;
{
struct statfs sf;
struct statfs *sfp;
int error;
error = kern_fstatfs(td, uap->fd, &sf);
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, sfp);
if (error == 0)
error = copyout(&sf, uap->buf, sizeof(sf));
error = copyout(sfp, uap->buf, sizeof(struct statfs));
free(sfp, M_STATFS);
return (error);
}
@ -420,7 +424,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
size_t *countp, enum uio_seg bufseg, int mode)
{
struct mount *mp, *nmp;
struct statfs *sfsp, *sp, sb, *tofree;
struct statfs *sfsp, *sp, *sptmp, *tofree;
size_t count, maxcount;
int error;
@ -451,7 +455,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
if (maxcount > count)
maxcount = count;
tofree = sfsp = *buf = malloc(maxcount * sizeof(struct statfs),
M_TEMP, M_WAITOK);
M_STATFS, M_WAITOK);
}
count = 0;
mtx_lock(&mountlist_mtx);
@ -476,7 +480,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
* no other choice than to start over.
*/
mtx_unlock(&mountlist_mtx);
free(tofree, M_TEMP);
free(tofree, M_STATFS);
goto restart;
}
} else {
@ -508,15 +512,20 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
}
}
if (priv_check(td, PRIV_VFS_GENERATION)) {
bcopy(sp, &sb, sizeof(sb));
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, &sb);
sp = &sb;
}
if (bufseg == UIO_SYSSPACE)
sptmp = malloc(sizeof(struct statfs), M_STATFS,
M_WAITOK);
*sptmp = *sp;
sptmp->f_fsid.val[0] = sptmp->f_fsid.val[1] = 0;
prison_enforce_statfs(td->td_ucred, mp, sptmp);
sp = sptmp;
} else
sptmp = NULL;
if (bufseg == UIO_SYSSPACE) {
bcopy(sp, sfsp, sizeof(*sp));
else /* if (bufseg == UIO_USERSPACE) */ {
free(sptmp, M_STATFS);
} else /* if (bufseg == UIO_USERSPACE) */ {
error = copyout(sp, sfsp, sizeof(*sp));
free(sptmp, M_STATFS);
if (error != 0) {
vfs_unbusy(mp);
return (error);
@ -558,14 +567,17 @@ freebsd4_statfs(td, uap)
} */ *uap;
{
struct ostatfs osb;
struct statfs sf;
struct statfs *sfp;
int error;
error = kern_statfs(td, uap->path, UIO_USERSPACE, &sf);
if (error != 0)
return (error);
cvtstatfs(&sf, &osb);
return (copyout(&osb, uap->buf, sizeof(osb)));
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
if (error == 0) {
cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
return (error);
}
/*
@ -586,14 +598,17 @@ freebsd4_fstatfs(td, uap)
} */ *uap;
{
struct ostatfs osb;
struct statfs sf;
struct statfs *sfp;
int error;
error = kern_fstatfs(td, uap->fd, &sf);
if (error != 0)
return (error);
cvtstatfs(&sf, &osb);
return (copyout(&osb, uap->buf, sizeof(osb)));
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, sfp);
if (error == 0) {
cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
return (error);
}
/*
@ -638,7 +653,7 @@ freebsd4_getfsstat(td, uap)
uap->buf++;
count--;
}
free(buf, M_TEMP);
free(buf, M_STATFS);
}
return (error);
}
@ -661,18 +676,21 @@ freebsd4_fhstatfs(td, uap)
} */ *uap;
{
struct ostatfs osb;
struct statfs sf;
struct statfs *sfp;
fhandle_t fh;
int error;
error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
if (error != 0)
return (error);
error = kern_fhstatfs(td, fh, &sf);
if (error != 0)
return (error);
cvtstatfs(&sf, &osb);
return (copyout(&osb, uap->buf, sizeof(osb)));
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fhstatfs(td, fh, sfp);
if (error == 0) {
cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
return (error);
}
/*
@ -4407,17 +4425,19 @@ sys_fhstatfs(td, uap)
struct statfs *buf;
} */ *uap;
{
struct statfs sf;
struct statfs *sfp;
fhandle_t fh;
int error;
error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
if (error != 0)
return (error);
error = kern_fhstatfs(td, fh, &sf);
if (error != 0)
return (error);
return (copyout(&sf, uap->buf, sizeof(sf)));
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fhstatfs(td, fh, sfp);
if (error == 0)
error = copyout(sfp, uap->buf, sizeof(*sfp));
free(sfp, M_STATFS);
return (error);
}
int

View File

@ -597,6 +597,7 @@ struct uio;
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_MOUNT);
MALLOC_DECLARE(M_STATFS);
#endif
extern int maxvfsconf; /* highest defined filesystem type */