mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-21 17:25:09 +00:00
Avoid code duplication in serval places by introducing universal
kern_getfsstat() function. Obtained from: jhb
This commit is contained in:
parent
ecc12766a1
commit
13a82b9623
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147178
|
@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
|
|||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/jail.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
@ -156,56 +155,39 @@ osf1_getfsstat(td, uap)
|
|||
struct thread *td;
|
||||
register struct osf1_getfsstat_args *uap;
|
||||
{
|
||||
long count, error, maxcount;
|
||||
caddr_t osf_sfsp;
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sp, sb;
|
||||
struct statfs *buf, *sp;
|
||||
struct osf1_statfs osfs;
|
||||
size_t count, size;
|
||||
int error, flags;
|
||||
|
||||
if (uap->flags & ~OSF1_GETFSSTAT_FLAGS)
|
||||
return (EINVAL);
|
||||
flags = 0;
|
||||
if (uap->flags & OSF1_MNT_WAIT)
|
||||
flags |= MNT_WAIT;
|
||||
if (uap->flags & OSF1_MNT_NOWAIT)
|
||||
flags |= MNT_NOWAIT;
|
||||
|
||||
maxcount = uap->bufsize / sizeof(struct osf1_statfs);
|
||||
osf_sfsp = (caddr_t)uap->buf;
|
||||
for (count = 0, mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
if (osf_sfsp && count < maxcount) {
|
||||
if (!prison_check_mount(td->td_ucred, mp))
|
||||
continue;
|
||||
#ifdef MAC
|
||||
if (mac_check_mount_stat(td->td_ucred, mp) != 0)
|
||||
continue;
|
||||
#endif
|
||||
sp = &mp->mnt_stat;
|
||||
/*
|
||||
* If OSF1_MNT_NOWAIT is specified, do not refresh the
|
||||
* fsstat cache. OSF1_MNT_WAIT overrides
|
||||
* OSF1_MNT_NOWAIT.
|
||||
*/
|
||||
if (((uap->flags & OSF1_MNT_NOWAIT) == 0 ||
|
||||
(uap->flags & OSF1_MNT_WAIT)) &&
|
||||
(error = VFS_STATFS(mp, sp, td)))
|
||||
continue;
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
if (suser(td)) {
|
||||
bcopy(sp, &sb, sizeof(sb));
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
bsd2osf_statfs(sp, &osfs);
|
||||
if ((error = copyout(&osfs, osf_sfsp,
|
||||
sizeof (struct osf1_statfs))))
|
||||
return (error);
|
||||
osf_sfsp += sizeof (struct osf1_statfs);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (osf_sfsp && count > maxcount)
|
||||
td->td_retval[0] = maxcount;
|
||||
count = uap->bufsize / sizeof(struct ostatfs);
|
||||
size = count * sizeof(struct statfs);
|
||||
if (size > 0)
|
||||
buf = malloc(size, M_TEMP, M_WAITOK);
|
||||
else
|
||||
td->td_retval[0] = count;
|
||||
|
||||
return (0);
|
||||
buf = NULL;
|
||||
error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, flags);
|
||||
if (buf != NULL) {
|
||||
count = td->td_retval[0];
|
||||
sp = buf;
|
||||
while (count > 0 && error == 0) {
|
||||
bsd2osf_statfs(sp, &osfs);
|
||||
error = copyout(&osfs, uap->buf, sizeof(osfs));
|
||||
sp++;
|
||||
uap->buf++;
|
||||
count--;
|
||||
}
|
||||
free(buf, M_TEMP);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -156,32 +156,29 @@ copy_statfs(struct statfs *in, struct statfs32 *out)
|
|||
int
|
||||
freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
|
||||
{
|
||||
struct statfs *buf, *sp;
|
||||
struct statfs32 stat32;
|
||||
size_t count, size;
|
||||
int error;
|
||||
caddr_t sg;
|
||||
struct statfs32 *sp32, stat32;
|
||||
struct statfs *sp = NULL, stat;
|
||||
int maxcount, count, i;
|
||||
|
||||
sp32 = uap->buf;
|
||||
maxcount = uap->bufsize / sizeof(struct statfs32);
|
||||
|
||||
if (sp32) {
|
||||
sg = stackgap_init();
|
||||
sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
|
||||
uap->buf = (struct statfs32 *)sp;
|
||||
}
|
||||
error = getfsstat(td, (struct getfsstat_args *) uap);
|
||||
if (sp32 && !error) {
|
||||
count = uap->bufsize / sizeof(struct statfs32);
|
||||
size = count * sizeof(struct statfs);
|
||||
if (size > 0)
|
||||
buf = malloc(size, M_TEMP, M_WAITOK);
|
||||
else
|
||||
buf = NULL;
|
||||
error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
|
||||
if (buf != NULL) {
|
||||
count = td->td_retval[0];
|
||||
for (i = 0; i < count; i++) {
|
||||
error = copyin(&sp[i], &stat, sizeof(stat));
|
||||
if (error)
|
||||
return (error);
|
||||
copy_statfs(&stat, &stat32);
|
||||
error = copyout(&stat32, &sp32[i], sizeof(stat32));
|
||||
if (error)
|
||||
return (error);
|
||||
sp = buf;
|
||||
while (count > 0 && error == 0) {
|
||||
copy_statfs(sp, &stat32);
|
||||
error = copyout(&stat32, uap->buf, sizeof(stat32));
|
||||
sp++;
|
||||
uap->buf++;
|
||||
count--;
|
||||
}
|
||||
free(buf, M_TEMP);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -373,13 +373,22 @@ getfsstat(td, uap)
|
|||
int flags;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sp, sb;
|
||||
caddr_t sfsp;
|
||||
long count, maxcount, error;
|
||||
|
||||
maxcount = uap->bufsize / sizeof(struct statfs);
|
||||
sfsp = (caddr_t)uap->buf;
|
||||
return (kern_getfsstat(td, uap->buf, uap->bufsize, UIO_USERSPACE,
|
||||
uap->flags));
|
||||
}
|
||||
|
||||
int
|
||||
kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
|
||||
enum uio_seg bufseg, int flags)
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sfsp, *sp, sb;
|
||||
size_t count, maxcount;
|
||||
int error;
|
||||
|
||||
maxcount = bufsize / sizeof(struct statfs);
|
||||
sfsp = buf;
|
||||
count = 0;
|
||||
mtx_lock(&Giant);
|
||||
mtx_lock(&mountlist_mtx);
|
||||
|
@ -412,8 +421,8 @@ getfsstat(td, uap)
|
|||
* refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
|
||||
* overrides MNT_WAIT.
|
||||
*/
|
||||
if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(uap->flags & MNT_WAIT)) &&
|
||||
if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(flags & MNT_WAIT)) &&
|
||||
(error = VFS_STATFS(mp, sp, td))) {
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
|
@ -425,13 +434,16 @@ getfsstat(td, uap)
|
|||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
error = copyout(sp, sfsp, sizeof(*sp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
sfsp += sizeof(*sp);
|
||||
if (bufseg == UIO_USERSPACE) {
|
||||
error = copyout(sp, sfsp, sizeof(*sp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
} else
|
||||
bcopy(sp, sfsp, sizeof(*sp));
|
||||
sfsp++;
|
||||
}
|
||||
count++;
|
||||
mtx_lock(&mountlist_mtx);
|
||||
|
@ -525,74 +537,31 @@ freebsd4_getfsstat(td, uap)
|
|||
int flags;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sp, sb;
|
||||
struct statfs *buf, *sp;
|
||||
struct ostatfs osb;
|
||||
caddr_t sfsp;
|
||||
long count, maxcount, error;
|
||||
size_t count, size;
|
||||
int error;
|
||||
|
||||
maxcount = uap->bufsize / sizeof(struct ostatfs);
|
||||
sfsp = (caddr_t)uap->buf;
|
||||
count = 0;
|
||||
mtx_lock(&Giant);
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
if (!prison_check_mount(td->td_ucred, mp)) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#ifdef MAC
|
||||
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
if (sfsp && count < maxcount) {
|
||||
sp = &mp->mnt_stat;
|
||||
/*
|
||||
* If MNT_NOWAIT or MNT_LAZY is specified, do not
|
||||
* refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
|
||||
* overrides MNT_WAIT.
|
||||
*/
|
||||
if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(uap->flags & MNT_WAIT)) &&
|
||||
(error = VFS_STATFS(mp, sp, td))) {
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp, td);
|
||||
continue;
|
||||
}
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
if (suser(td)) {
|
||||
bcopy(sp, &sb, sizeof(sb));
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
cvtstatfs(sp, &osb);
|
||||
error = copyout(&osb, sfsp, sizeof(osb));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
sfsp += sizeof(osb);
|
||||
}
|
||||
count++;
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp, td);
|
||||
}
|
||||
mtx_unlock(&mountlist_mtx);
|
||||
mtx_unlock(&Giant);
|
||||
if (sfsp && count > maxcount)
|
||||
td->td_retval[0] = maxcount;
|
||||
count = uap->bufsize / sizeof(struct ostatfs);
|
||||
size = count * sizeof(struct statfs);
|
||||
if (size > 0)
|
||||
buf = malloc(size, M_TEMP, M_WAITOK);
|
||||
else
|
||||
td->td_retval[0] = count;
|
||||
return (0);
|
||||
buf = NULL;
|
||||
error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
|
||||
if (buf != NULL) {
|
||||
count = td->td_retval[0];
|
||||
sp = buf;
|
||||
while (count > 0 && error == 0) {
|
||||
cvtstatfs(sp, &osb);
|
||||
error = copyout(&osb, uap->buf, sizeof(osb));
|
||||
sp++;
|
||||
uap->buf++;
|
||||
count--;
|
||||
}
|
||||
free(buf, M_TEMP);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -373,13 +373,22 @@ getfsstat(td, uap)
|
|||
int flags;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sp, sb;
|
||||
caddr_t sfsp;
|
||||
long count, maxcount, error;
|
||||
|
||||
maxcount = uap->bufsize / sizeof(struct statfs);
|
||||
sfsp = (caddr_t)uap->buf;
|
||||
return (kern_getfsstat(td, uap->buf, uap->bufsize, UIO_USERSPACE,
|
||||
uap->flags));
|
||||
}
|
||||
|
||||
int
|
||||
kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
|
||||
enum uio_seg bufseg, int flags)
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sfsp, *sp, sb;
|
||||
size_t count, maxcount;
|
||||
int error;
|
||||
|
||||
maxcount = bufsize / sizeof(struct statfs);
|
||||
sfsp = buf;
|
||||
count = 0;
|
||||
mtx_lock(&Giant);
|
||||
mtx_lock(&mountlist_mtx);
|
||||
|
@ -412,8 +421,8 @@ getfsstat(td, uap)
|
|||
* refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
|
||||
* overrides MNT_WAIT.
|
||||
*/
|
||||
if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(uap->flags & MNT_WAIT)) &&
|
||||
if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(flags & MNT_WAIT)) &&
|
||||
(error = VFS_STATFS(mp, sp, td))) {
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
|
@ -425,13 +434,16 @@ getfsstat(td, uap)
|
|||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
error = copyout(sp, sfsp, sizeof(*sp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
sfsp += sizeof(*sp);
|
||||
if (bufseg == UIO_USERSPACE) {
|
||||
error = copyout(sp, sfsp, sizeof(*sp));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
} else
|
||||
bcopy(sp, sfsp, sizeof(*sp));
|
||||
sfsp++;
|
||||
}
|
||||
count++;
|
||||
mtx_lock(&mountlist_mtx);
|
||||
|
@ -525,74 +537,31 @@ freebsd4_getfsstat(td, uap)
|
|||
int flags;
|
||||
} */ *uap;
|
||||
{
|
||||
struct mount *mp, *nmp;
|
||||
struct statfs *sp, sb;
|
||||
struct statfs *buf, *sp;
|
||||
struct ostatfs osb;
|
||||
caddr_t sfsp;
|
||||
long count, maxcount, error;
|
||||
size_t count, size;
|
||||
int error;
|
||||
|
||||
maxcount = uap->bufsize / sizeof(struct ostatfs);
|
||||
sfsp = (caddr_t)uap->buf;
|
||||
count = 0;
|
||||
mtx_lock(&Giant);
|
||||
mtx_lock(&mountlist_mtx);
|
||||
for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
|
||||
if (!prison_check_mount(td->td_ucred, mp)) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#ifdef MAC
|
||||
if (mac_check_mount_stat(td->td_ucred, mp) != 0) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (vfs_busy(mp, LK_NOWAIT, &mountlist_mtx, td)) {
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
continue;
|
||||
}
|
||||
if (sfsp && count < maxcount) {
|
||||
sp = &mp->mnt_stat;
|
||||
/*
|
||||
* If MNT_NOWAIT or MNT_LAZY is specified, do not
|
||||
* refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
|
||||
* overrides MNT_WAIT.
|
||||
*/
|
||||
if (((uap->flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
|
||||
(uap->flags & MNT_WAIT)) &&
|
||||
(error = VFS_STATFS(mp, sp, td))) {
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp, td);
|
||||
continue;
|
||||
}
|
||||
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
|
||||
if (suser(td)) {
|
||||
bcopy(sp, &sb, sizeof(sb));
|
||||
sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
|
||||
sp = &sb;
|
||||
}
|
||||
cvtstatfs(sp, &osb);
|
||||
error = copyout(&osb, sfsp, sizeof(osb));
|
||||
if (error) {
|
||||
vfs_unbusy(mp, td);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
}
|
||||
sfsp += sizeof(osb);
|
||||
}
|
||||
count++;
|
||||
mtx_lock(&mountlist_mtx);
|
||||
nmp = TAILQ_NEXT(mp, mnt_list);
|
||||
vfs_unbusy(mp, td);
|
||||
}
|
||||
mtx_unlock(&mountlist_mtx);
|
||||
mtx_unlock(&Giant);
|
||||
if (sfsp && count > maxcount)
|
||||
td->td_retval[0] = maxcount;
|
||||
count = uap->bufsize / sizeof(struct ostatfs);
|
||||
size = count * sizeof(struct statfs);
|
||||
if (size > 0)
|
||||
buf = malloc(size, M_TEMP, M_WAITOK);
|
||||
else
|
||||
td->td_retval[0] = count;
|
||||
return (0);
|
||||
buf = NULL;
|
||||
error = kern_getfsstat(td, buf, size, UIO_SYSSPACE, uap->flags);
|
||||
if (buf != NULL) {
|
||||
count = td->td_retval[0];
|
||||
sp = buf;
|
||||
while (count > 0 && error == 0) {
|
||||
cvtstatfs(sp, &osb);
|
||||
error = copyout(&osb, uap->buf, sizeof(osb));
|
||||
sp++;
|
||||
uap->buf++;
|
||||
count--;
|
||||
}
|
||||
free(buf, M_TEMP);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -69,6 +69,8 @@ int kern_fstat(struct thread *td, int fd, struct stat *sbp);
|
|||
int kern_fstatfs(struct thread *td, int fd, struct statfs *buf);
|
||||
int kern_futimes(struct thread *td, int fd, struct timeval *tptr,
|
||||
enum uio_seg tptrseg);
|
||||
int kern_getfsstat(struct thread *td, struct statfs *buf, size_t bufsize,
|
||||
enum uio_seg bufseg, int flags);
|
||||
int kern_getitimer(struct thread *, u_int, struct itimerval *);
|
||||
int kern_getrusage(struct thread *td, int who, struct rusage *rup);
|
||||
int kern_getsockopt(struct thread *td, int s, int level, int name,
|
||||
|
|
Loading…
Reference in a new issue