--- //depot/projects/smpng/sys/alpha/osf1/osf1_mount.c 2005/05/27 14:58:46 +++ //depot/user/jhb/proc/alpha/osf1/osf1_mount.c 2005/05/27 19:03:47 @@ -156,56 +156,44 @@ 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; + 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) { 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); + 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 --- //depot/projects/smpng/sys/compat/freebsd32/freebsd32_misc.c 2005/05/27 14:58:46 +++ //depot/user/jhb/proc/compat/freebsd32/freebsd32_misc.c 2005/05/27 19:03:47 @@ -155,32 +155,29 @@ 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); } --- //depot/projects/smpng/sys/compat/linux/linux_misc.c 2005/05/27 14:58:46 +++ //depot/user/jhb/proc/compat/linux/linux_misc.c 2005/05/27 19:03:47 --- //depot/projects/smpng/sys/kern/vfs_syscalls.c 2005/05/27 14:58:46 +++ //depot/user/jhb/proc/kern/vfs_syscalls.c 2005/05/27 19:03:47 @@ -363,13 +363,22 @@ 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); @@ -402,8 +411,8 @@ * 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); @@ -415,13 +424,16 @@ 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); @@ -515,71 +527,36 @@ 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(&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; + 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) { if (suser(td)) { bcopy(sp, &sb, sizeof(sb)); sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; sp = &sb; } cvtstatfs(td, sp, &osb); - error = copyout(&osb, sfsp, sizeof(osb)); - if (error) { - vfs_unbusy(mp, td); - 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); - if (sfsp && count > maxcount) - td->td_retval[0] = maxcount; - else - td->td_retval[0] = count; - return (0); + return (error); } /* --- //depot/projects/smpng/sys/sys/syscallsubr.h 2005/04/01 18:38:57 +++ //depot/user/jhb/proc/sys/syscallsubr.h 2005/04/14 15:51:26 @@ -68,6 +68,8 @@ 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,