Module Name: src
Committed By: christos
Date: Fri Jan 24 22:10:09 UTC 2014
Modified Files:
src/sys/compat/netbsd32: netbsd32_compat_20.c
Log Message:
Fix locking botch, and ...
Yes, we want to be careful because the sizes are different.
To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/sys/compat/netbsd32/netbsd32_compat_20.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/compat/netbsd32/netbsd32_compat_20.c
diff -u src/sys/compat/netbsd32/netbsd32_compat_20.c:1.31 src/sys/compat/netbsd32/netbsd32_compat_20.c:1.32
--- src/sys/compat/netbsd32/netbsd32_compat_20.c:1.31 Wed Nov 27 12:24:44 2013
+++ src/sys/compat/netbsd32/netbsd32_compat_20.c Fri Jan 24 17:10:09 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_compat_20.c,v 1.31 2013/11/27 17:24:44 christos Exp $ */
+/* $NetBSD: netbsd32_compat_20.c,v 1.32 2014/01/24 22:10:09 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.31 2013/11/27 17:24:44 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_compat_20.c,v 1.32 2014/01/24 22:10:09 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,21 +67,12 @@ compat_20_netbsd32_from_statvfs(struct s
sb32p->f_spare[1] = 0;
sb32p->f_spare[2] = 0;
sb32p->f_spare[3] = 0;
-#if 1
- /* May as well do the whole batch in one go */
- (void)memcpy(sb32p->f_fstypename, sbp->f_fstypename,
- sizeof(sb32p->f_fstypename) +
- sizeof(sb32p->f_mntonname) +
- sizeof(sb32p->f_mntfromname));
-#else
- /* If we want to be careful */
(void)memcpy(sb32p->f_fstypename, sbp->f_fstypename,
sizeof(sb32p->f_fstypename));
(void)memcpy(sb32p->f_mntonname, sbp->f_mntonname,
sizeof(sb32p->f_mntonname));
(void)memcpy(sb32p->f_mntfromname, sbp->f_mntfromname,
sizeof(sb32p->f_mntfromname));
-#endif
}
int
@@ -92,12 +83,16 @@ compat_20_netbsd32_getfsstat(struct lwp
syscallarg(netbsd32_long) bufsize;
syscallarg(int) flags;
} */
+ int root = 0;
+ struct proc *p = l->l_proc;
struct mount *mp, *nmp;
- struct statvfs *sp;
+ struct statvfs *sb;
struct netbsd32_statfs sb32;
void *sfsp;
- long count, maxcount, error;
+ size_t count, maxcount;
+ int error = 0;
+ sb = STATVFSBUF_GET();
maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs);
sfsp = SCARG_P32(uap, buf);
mutex_enter(&mountlist_lock);
@@ -107,40 +102,52 @@ compat_20_netbsd32_getfsstat(struct lwp
continue;
}
if (sfsp && count < maxcount) {
- sp = &mp->mnt_stat;
- /*
- * If MNT_NOWAIT or MNT_LAZY is specified, do not
- * refresh the fsstat cache. MNT_WAIT or MNT_LAZY
- * overrides MNT_NOWAIT.
- */
- if (SCARG(uap, flags) != MNT_NOWAIT &&
- SCARG(uap, flags) != MNT_LAZY &&
- (SCARG(uap, flags) == MNT_WAIT ||
- SCARG(uap, flags) == 0) &&
- (error = VFS_STATVFS(mp, sp)) != 0) {
- mutex_enter(&mountlist_lock);
+ error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0);
+ if (error) {
vfs_unbusy(mp, false, &nmp);
+ error = 0;
continue;
}
- sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
- compat_20_netbsd32_from_statvfs(sp, &sb32);
+ sb->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
+ compat_20_netbsd32_from_statvfs(sb, &sb32);
error = copyout(&sb32, sfsp, sizeof(sb32));
if (error) {
vfs_unbusy(mp, false, NULL);
- return (error);
+ goto out;
}
sfsp = (char *)sfsp + sizeof(sb32);
+ root |= strcmp(sb->f_mntonname, "/") == 0;
}
count++;
- mutex_enter(&mountlist_lock);
vfs_unbusy(mp, false, &nmp);
}
mutex_exit(&mountlist_lock);
+
+ if (root == 0 && p->p_cwdi->cwdi_rdir) {
+ /*
+ * fake a root entry
+ */
+ error = dostatvfs(p->p_cwdi->cwdi_rdir->v_mount,
+ sb, l, SCARG(uap, flags), 1);
+ if (error != 0)
+ goto out;
+ if (sfsp) {
+ sb->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
+ compat_20_netbsd32_from_statvfs(sb, &sb32);
+ error = copyout(&sb32, sfsp, sizeof(sb32));
+ if (error != 0)
+ goto out;
+ }
+ count++;
+ }
+
if (sfsp && count > maxcount)
*retval = maxcount;
else
*retval = count;
- return (0);
+out:
+ STATVFSBUF_PUT(sb);
+ return error;
}
int
@@ -151,7 +158,7 @@ compat_20_netbsd32_statfs(struct lwp *l,
syscallarg(netbsd32_statfsp_t) buf;
} */
struct mount *mp;
- struct statvfs *sp;
+ struct statvfs *sb;
struct netbsd32_statfs s32;
int error;
struct vnode *vp;
@@ -161,12 +168,12 @@ compat_20_netbsd32_statfs(struct lwp *l,
if (error != 0)
return (error);
mp = vp->v_mount;
- sp = &mp->mnt_stat;
+ sb = &mp->mnt_stat;
vrele(vp);
- if ((error = VFS_STATVFS(mp, sp)) != 0)
+ if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0)
return (error);
- sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
- compat_20_netbsd32_from_statvfs(sp, &s32);
+ sb->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
+ compat_20_netbsd32_from_statvfs(sb, &s32);
return copyout(&s32, SCARG_P32(uap, buf), sizeof(s32));
}
@@ -179,7 +186,7 @@ compat_20_netbsd32_fstatfs(struct lwp *l
} */
file_t *fp;
struct mount *mp;
- struct statvfs *sp;
+ struct statvfs *sb;
struct netbsd32_statfs s32;
int error;
@@ -187,11 +194,11 @@ compat_20_netbsd32_fstatfs(struct lwp *l
if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
return (error);
mp = ((struct vnode *)fp->f_data)->v_mount;
- sp = &mp->mnt_stat;
- if ((error = VFS_STATVFS(mp, sp)) != 0)
+ sb = &mp->mnt_stat;
+ if ((error = dostatvfs(mp, sb, l, 0, 0)) != 0)
goto out;
- sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
- compat_20_netbsd32_from_statvfs(sp, &s32);
+ sb->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
+ compat_20_netbsd32_from_statvfs(sb, &s32);
error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32));
out:
fd_putfile(SCARG(uap, fd));