diff options
author | pjd <pjd@FreeBSD.org> | 2005-06-09 17:44:46 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2005-06-09 17:44:46 +0000 |
commit | 3af857a21ae29e6bd992143c332930401686617d (patch) | |
tree | 11a9edf30c5981a81932d35c358f4a0ab56990f8 /sys | |
parent | cd5038ab36b62fd0d3378b0486ebd1c1a0b27b65 (diff) | |
download | FreeBSD-src-3af857a21ae29e6bd992143c332930401686617d.zip FreeBSD-src-3af857a21ae29e6bd992143c332930401686617d.tar.gz |
Avoid code duplication in serval places by introducing universal
kern_getfsstat() function.
Obtained from: jhb
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/osf1/osf1_mount.c | 70 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 41 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 123 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 123 | ||||
-rw-r--r-- | sys/sys/syscallsubr.h | 2 |
5 files changed, 139 insertions, 220 deletions
diff --git a/sys/alpha/osf1/osf1_mount.c b/sys/alpha/osf1/osf1_mount.c index 1d0ac2a..ca25854 100644 --- a/sys/alpha/osf1/osf1_mount.c +++ b/sys/alpha/osf1/osf1_mount.c @@ -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); - - 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; - } + flags = 0; + if (uap->flags & OSF1_MNT_WAIT) + flags |= MNT_WAIT; + if (uap->flags & OSF1_MNT_NOWAIT) + flags |= MNT_NOWAIT; + + count = uap->bufsize / sizeof(struct ostatfs); + 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, flags); + if (buf != NULL) { + count = td->td_retval[0]; + sp = buf; + while (count > 0 && error == 0) { bsd2osf_statfs(sp, &osfs); - if ((error = copyout(&osfs, osf_sfsp, - sizeof (struct osf1_statfs)))) - return (error); - osf_sfsp += sizeof (struct osf1_statfs); + error = copyout(&osfs, uap->buf, sizeof(osfs)); + sp++; + uap->buf++; + count--; } - count++; + free(buf, M_TEMP); } - if (osf_sfsp && count > maxcount) - td->td_retval[0] = maxcount; - else - td->td_retval[0] = count; - - return (0); + return (error); } int diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 1469c3e..1c003a0 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -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); } diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index bf92a6e..16975cc 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -373,13 +373,22 @@ getfsstat(td, uap) int flags; } */ *uap; { + + 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 *sp, sb; - caddr_t sfsp; - long count, maxcount, error; + struct statfs *sfsp, *sp, sb; + size_t count, maxcount; + int error; - maxcount = uap->bufsize / sizeof(struct statfs); - sfsp = (caddr_t)uap->buf; + 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; - } + count = uap->bufsize / sizeof(struct ostatfs); + 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]; + sp = buf; + while (count > 0 && error == 0) { cvtstatfs(sp, &osb); - error = copyout(&osb, sfsp, sizeof(osb)); - if (error) { - vfs_unbusy(mp, td); - mtx_unlock(&Giant); - return (error); - } - sfsp += sizeof(osb); + error = copyout(&osb, uap->buf, sizeof(osb)); + sp++; + uap->buf++; + count--; } - count++; - mtx_lock(&mountlist_mtx); - nmp = TAILQ_NEXT(mp, mnt_list); - vfs_unbusy(mp, td); + free(buf, M_TEMP); } - mtx_unlock(&mountlist_mtx); - mtx_unlock(&Giant); - if (sfsp && count > maxcount) - td->td_retval[0] = maxcount; - else - td->td_retval[0] = count; - return (0); + return (error); } /* diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index bf92a6e..16975cc 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -373,13 +373,22 @@ getfsstat(td, uap) int flags; } */ *uap; { + + 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 *sp, sb; - caddr_t sfsp; - long count, maxcount, error; + struct statfs *sfsp, *sp, sb; + size_t count, maxcount; + int error; - maxcount = uap->bufsize / sizeof(struct statfs); - sfsp = (caddr_t)uap->buf; + 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; - } + count = uap->bufsize / sizeof(struct ostatfs); + 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]; + sp = buf; + while (count > 0 && error == 0) { cvtstatfs(sp, &osb); - error = copyout(&osb, sfsp, sizeof(osb)); - if (error) { - vfs_unbusy(mp, td); - mtx_unlock(&Giant); - return (error); - } - sfsp += sizeof(osb); + error = copyout(&osb, uap->buf, sizeof(osb)); + sp++; + uap->buf++; + count--; } - count++; - mtx_lock(&mountlist_mtx); - nmp = TAILQ_NEXT(mp, mnt_list); - vfs_unbusy(mp, td); + free(buf, M_TEMP); } - mtx_unlock(&mountlist_mtx); - mtx_unlock(&Giant); - if (sfsp && count > maxcount) - td->td_retval[0] = maxcount; - else - td->td_retval[0] = count; - return (0); + return (error); } /* diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index c8f11e7..c09288e 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -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, |