fix for per-mount i/o counting in ffs
Bruce Evans
brde at optusnet.com.au
Thu May 19 02:26:17 UTC 2016
On Thu, 19 May 2016, Bruce Evans wrote:
> On Thu, 19 May 2016, Bruce Evans wrote:
>
>> ...
>> I think the following works to prevent multiple mounts via all of the
>> known buggy paths: early in every fsmount():
Here is a lightly tested version:
X Index: ffs_vfsops.c
X ===================================================================
X --- ffs_vfsops.c (revision 300160)
X +++ ffs_vfsops.c (working copy)
X @@ -771,18 +771,24 @@
X error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1);
X g_topology_unlock();
X PICKUP_GIANT();
X + /* XXX: v_bufobj is left set after errors. */
X + devvp->v_bufobj.bo_ops = &ffs_ops;
X VOP_UNLOCK(devvp, 0);
Since v_bufobj isn't cleaned after later errors, I didn't move the unlock
to keep it clean for this error alone.
X if (error)
X - goto out;
X - if (devvp->v_rdev->si_iosize_max != 0)
X - mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
X + goto out1;
X + dev_lock();
X + if (dev->si_mountpt != NULL) {
X + dev_unlock();
X + error = EBUSY;
X + goto out1;
X + }
X + dev->si_mountpt = mp;
X + dev_unlock();
X + if (dev->si_iosize_max != 0)
X + mp->mnt_iosize_max = dev->si_iosize_max;
X if (mp->mnt_iosize_max > MAXPHYS)
X mp->mnt_iosize_max = MAXPHYS;
X
X - devvp->v_bufobj.bo_ops = &ffs_ops;
X - if (devvp->v_type == VCHR)
X - devvp->v_rdev->si_mountpt = mp;
X -
X fs = NULL;
X sblockloc = 0;
X /*
X @@ -1081,10 +1087,14 @@
X #endif /* !UFS_EXTATTR */
X return (0);
X out:
X + dev_lock();
X + if (dev->si_mountpt == NULL)
X + panic("lost si_mountpt in mount");
X + dev->si_mountpt = NULL;
X + dev_unlock();
I don't want the debugging panics or KASSERTs in the final version.
Explicit locking the stores of NULL is probably not needed. dev_rel()
will soon make these stores visible and other locking and ordering
makes it very unlikely that they become visible too early.
X +out1:
X if (bp)
X brelse(bp);
X - if (devvp->v_type == VCHR && devvp->v_rdev != NULL)
X - devvp->v_rdev->si_mountpt = NULL;
X if (cp != NULL) {
X DROP_GIANT();
X g_topology_lock();
X @@ -1287,8 +1297,11 @@
X g_vfs_close(ump->um_cp);
X g_topology_unlock();
X PICKUP_GIANT();
X - if (ump->um_devvp->v_type == VCHR && ump->um_devvp->v_rdev != NULL)
X - ump->um_devvp->v_rdev->si_mountpt = NULL;
X + dev_lock();
X + if (ump->um_dev->si_mountpt == NULL)
X + panic("lost si_mountpt in unmount");
X + ump->um_dev->si_mountpt = NULL;
X + dev_unlock();
X vrele(ump->um_devvp);
X dev_rel(ump->um_dev);
X mtx_destroy(UFS_MTX(ump));
Bruce
More information about the freebsd-fs
mailing list