Date: Mon, 22 Mar 2010 20:41:39 +0200 From: Andriy Gapon <avg@freebsd.org> To: freebsd-fs@freebsd.org, freebsd-geom@freebsd.org Cc: Pawel Jakub Dawidek <pjd@freebsd.org> Subject: geom_vfs: disallow multiple readonly mounts of a device Message-ID: <4BA7B9E3.3080003@freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BA7B9E3.3080003>