geom_vfs: disallow multiple readonly mounts of a device
Andriy Gapon
avg at freebsd.org
Wed Mar 31 14:54:46 UTC 2010
If no one has objections, suggestions or opinions, I am going to commit this.
on 22/03/2010 20:41 Andriy Gapon said the following:
> Currently FreeBSD allows multiple readonly mounts of the same device.
> This feature seems to be introduced along with GEOM. Before that, only one mount
> of a device was allowed, whether readonly or not. Other (major) BSDs still work
> that way.
> Unfortunately, the feature has never really worked correctly because of some
> architectural/design issues in our buffer cache layer/interface.
> Multiple shared mounts are allowed to happen but later on, during filesystem
> access or at unmount time, a system would crash.
>
> Because of this, I propose to disable shared mounting feature for time being.
> In my opinion it is very unlikely that anybody depends on this feature now, but
> nullfs can be used as its replacement. In fact, it could be even more efficient
> if the same files are access via different mount points.
>
> The proposed patch is a greatly reduced version of a patch by Pawel Jakub Dawidek:
> http://people.freebsd.org/~pjd/patches/mro_mount.patch
> Pawel's patch, in fact, fixes the shared mounting feature.
> Unfortunately, at least one filesystem (FFS) is quite intrusive at what it does
> with a device vnode (or rather its bufobj) when it attempts mounting.
> So, in some edge cases (synthetic or accidental) a system may still crash even
> with the Pawel's patch. So, I think that it should not be committed until after
> all filesystems in the tree are made to play nice. Otherwise, I like it.
>
> As an afterthought, perhaps it is the Pawel's patch that we should actually use
> with one change - add a sysctl that enables/disables shared mounts and make them
> disabled by default.
>
> Thank you very for the feedback.
>
> --- a/sys/geom/geom_vfs.c
> +++ b/sys/geom/geom_vfs.c
> @@ -161,6 +161,10 @@ g_vfs_open
> g_topology_assert();
>
> *cpp = NULL;
> + bo = &vp->v_bufobj;
> + if (bo->bo_private != vp)
> + return (EBUSY);
> +
> pp = g_dev_getprovider(vp->v_rdev);
> if (pp == NULL)
> return (ENOENT);
> @@ -176,6 +180,6 @@ g_vfs_open
> vnode_create_vobject(vp, pp->mediasize, curthread);
> VFS_UNLOCK_GIANT(vfslocked);
> *cpp = cp;
> - bo = &vp->v_bufobj;
> + cp->private = vp;
> bo->bo_ops = g_vfs_bufops;
> bo->bo_private = cp;
> @@ -196,5 +200,6 @@ g_vfs_close
> gp = cp->geom;
> bo = gp->softc;
> bufobj_invalbuf(bo, V_SAVE, 0, 0);
> + bo->bo_private = cp->private;
> g_wither_geom_close(gp, ENXIO);
> }
>
--
Andriy Gapon
More information about the freebsd-fs
mailing list