Avoid code duplication in serval places by introducing universal

kern_getfsstat() function.

Obtained from:	jhb
This commit is contained in:
Pawel Jakub Dawidek 2005-06-09 17:44:46 +00:00
parent ecc12766a1
commit 13a82b9623
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147178
5 changed files with 146 additions and 227 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}
/*

View file

@ -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);
}
/*

View file

@ -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,