Adjust vfinddev() to return a referenced vnode in *vpp.
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 31 Mar 2009 22:17:33 +0000 (15:17 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 31 Mar 2009 22:17:33 +0000 (15:17 -0700)
Fix a small race condition in sys_linux_ustat() related to accessing
a vnode which can get ripped out from under the procedure.

share/examples/rconfig/hammer.sh
sys/emulation/linux/linux_stats.c
sys/kern/vfs_subr.c

index 62ef446..02086b5 100644 (file)
@@ -117,6 +117,8 @@ chflags nohistory /mnt/usr/obj
 # Install the system from the live CD
 #
 cpdup -o / /mnt
+cpdup -o /boot /mnt/boot
+cpdup -o /usr /mnt/usr
 cpdup -o /var /mnt/var
 cpdup -o /dev /mnt/dev
 cpdup -i0 /etc.hdd /mnt/etc
index 74ebcb4..72b125a 100644 (file)
@@ -322,10 +322,12 @@ sys_linux_ustat(struct linux_ustat_args *args)
        dev = udev2dev(makeudev(args->dev >> 8, args->dev & 0xFF), 0);
        if (dev != NULL && vfinddev(dev, VCHR, &vp)) {
                if (vp->v_mount == NULL) {
+                       vrele(vp);
                        return (EINVAL);
                }
                stat = &(vp->v_mount->mnt_stat);
                error = VFS_STATFS(vp->v_mount, stat, curproc->p_ucred);
+               vrele(vp);
                if (error) {
                        return (error);
                }
index 6064667..9a4c039 100644 (file)
@@ -1343,6 +1343,9 @@ vgone_vxlocked(struct vnode *vp)
 
 /*
  * Lookup a vnode by device number.
+ *
+ * Returns non-zero and *vpp set to a vref'd vnode on success.
+ * Returns zero on failure.
  */
 int
 vfinddev(cdev_t dev, enum vtype type, struct vnode **vpp)
@@ -1354,6 +1357,7 @@ vfinddev(cdev_t dev, enum vtype type, struct vnode **vpp)
        SLIST_FOREACH(vp, &dev->si_hlist, v_cdevnext) {
                if (type == vp->v_type) {
                        *vpp = vp;
+                       vref(vp);
                        lwkt_reltoken(&ilock);
                        return (1);
                }