Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 May 2016 12:20:19 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Konstantin Belousov <kostikbel@gmail.com>, fs@freebsd.org
Subject:   Re: fix for per-mount i/o counting in ffs
Message-ID:  <20160519120557.A2250@besplex.bde.org>
In-Reply-To: <20160519094901.O1798@besplex.bde.org>
References:  <20160517072104.I2137@besplex.bde.org> <20160517084241.GY89104@kib.kiev.ua> <20160518061040.D5948@besplex.bde.org> <20160518070252.F6121@besplex.bde.org> <20160517220055.GF89104@kib.kiev.ua> <20160518084931.T6534@besplex.bde.org> <20160518110834.GJ89104@kib.kiev.ua> <20160519065714.H1393@besplex.bde.org> <20160519094901.O1798@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160519120557.A2250>