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:
parent
2677b6e77f
commit
2f304845e2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=311452
@ -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
|
||||
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user