Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/netbsd32 Fix locking botch, and ...



details:   https://anonhg.NetBSD.org/src/rev/4fa79f12d1f9
branches:  trunk
changeset: 326287:4fa79f12d1f9
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jan 24 22:10:09 2014 +0000

description:
Fix locking botch, and ...
Yes, we want to be careful because the sizes are different.

diffstat:

 sys/compat/netbsd32/netbsd32_compat_20.c |  87 +++++++++++++++++--------------
 1 files changed, 47 insertions(+), 40 deletions(-)

diffs (180 lines):

diff -r c83cdc4e8016 -r 4fa79f12d1f9 sys/compat/netbsd32/netbsd32_compat_20.c
--- a/sys/compat/netbsd32/netbsd32_compat_20.c  Fri Jan 24 17:30:18 2014 +0000
+++ b/sys/compat/netbsd32/netbsd32_compat_20.c  Fri Jan 24 22:10:09 2014 +0000
@@ -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 @@
        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 @@
                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 @@
                        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 @@
                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 @@
        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 @@
        } */
        file_t *fp;
        struct mount *mp;
-       struct statvfs *sp;
+       struct statvfs *sb;
        struct netbsd32_statfs s32;
        int error;
 
@@ -187,11 +194,11 @@
        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));



Home | Main Index | Thread Index | Old Index