cvs commit: src/sys/kern vfs_syscalls.c
John Baldwin
jhb at FreeBSD.org
Fri May 27 12:36:33 PDT 2005
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 <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the cvs-src
mailing list