From owner-cvs-src@FreeBSD.ORG Fri May 27 19:36:33 2005 Return-Path: X-Original-To: cvs-src@FreeBSD.org Delivered-To: cvs-src@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C275216A41C for ; Fri, 27 May 2005 19:36:33 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: from mail26.sea5.speakeasy.net (mail26.sea5.speakeasy.net [69.17.117.28]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9C29243D4C for ; Fri, 27 May 2005 19:36:32 +0000 (GMT) (envelope-from jhb@FreeBSD.org) Received: (qmail 14597 invoked from network); 27 May 2005 19:36:32 -0000 Received: from server.baldwin.cx ([216.27.160.63]) (envelope-sender ) by mail26.sea5.speakeasy.net (qmail-ldap-1.03) with AES256-SHA encrypted SMTP for ; 27 May 2005 19:36:31 -0000 Received: from [10.50.40.212] (gw1.twc.weather.com [216.133.140.1]) (authenticated bits=0) by server.baldwin.cx (8.13.1/8.13.1) with ESMTP id j4RJaK4t015810; Fri, 27 May 2005 15:36:24 -0400 (EDT) (envelope-from jhb@FreeBSD.org) From: John Baldwin To: Pawel Jakub Dawidek Date: Fri, 27 May 2005 15:36:17 -0400 User-Agent: KMail/1.8 References: <200505271921.j4RJL8qX017361@repoman.freebsd.org> In-Reply-To: <200505271921.j4RJL8qX017361@repoman.freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-6" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200505271536.18979.jhb@FreeBSD.org> X-Spam-Status: No, score=-102.8 required=4.2 tests=ALL_TRUSTED, USER_IN_WHITELIST autolearn=failed version=3.0.2 X-Spam-Checker-Version: SpamAssassin 3.0.2 (2004-11-16) on server.baldwin.cx Cc: cvs-src@FreeBSD.org, src-committers@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/kern vfs_syscalls.c X-BeenThere: cvs-src@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 May 2005 19:36:33 -0000 On Friday 27 May 2005 03:21 pm, Pawel Jakub Dawidek wrote: > pjd 2005-05-27 19:21:08 UTC > > FreeBSD src repository > > Modified files: > sys/kern vfs_syscalls.c > Log: > Sync locking in freebsd4_getfsstat() with getfsstat(). > Giant is probably also needed in kern_fhstatfs(). Hmm, can you possibly hold up on this? I have a patch to create kern_getfsstat() that will save you a lot of trouble if you want to test it at http://www.freebsd.org/~jhb/patches/getfsstat.patch and below: --- //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, -- John Baldwin <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org