diff options
author | avg <avg@FreeBSD.org> | 2010-04-03 08:53:53 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2010-04-03 08:53:53 +0000 |
commit | 5b3e4a4ae87b9d269a42ec394518307ea8148de7 (patch) | |
tree | b6a35e533cc90af9b50076d3fd923086bc69922f /sys/geom/geom_vfs.c | |
parent | 91cd4478c28e9e9767d53821be2578fc94be748b (diff) | |
download | FreeBSD-src-5b3e4a4ae87b9d269a42ec394518307ea8148de7.zip FreeBSD-src-5b3e4a4ae87b9d269a42ec394518307ea8148de7.tar.gz |
g_vfs_open: allow only one mount per device vnode
In other words, deny multiple read-only mounts of the same device.
Shared read-only mounts should theoretically be possible, but,
unfortunately, can not be implemented correctly using current
buffer cache code/interface and results in an eventual system crash.
Also, using nullfs seems to be a more efficient way to achieve the same
goal.
This gets us back to where we were before GEOM and where other BSDs are.
Submitted by: pjd (idea for checking for shared mounting)
Discussed with: phk, pjd
Silence from: fs@, geom@
MFC after: 2 weeks
Diffstat (limited to 'sys/geom/geom_vfs.c')
-rw-r--r-- | sys/geom/geom_vfs.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/geom/geom_vfs.c b/sys/geom/geom_vfs.c index 9d01f40..e50e17b 100644 --- a/sys/geom/geom_vfs.c +++ b/sys/geom/geom_vfs.c @@ -161,6 +161,10 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr 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,7 +180,7 @@ g_vfs_open(struct vnode *vp, struct g_consumer **cpp, const char *fsname, int wr 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; bo->bo_bsize = pp->sectorsize; @@ -196,5 +200,6 @@ g_vfs_close(struct g_consumer *cp) gp = cp->geom; bo = gp->softc; bufobj_invalbuf(bo, V_SAVE, 0, 0); + bo->bo_private = cp->private; g_wither_geom_close(gp, ENXIO); } |