summaryrefslogtreecommitdiffstats
path: root/sys/fs/tmpfs/tmpfs_subr.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-05-02 18:44:31 +0000
committerkib <kib@FreeBSD.org>2013-05-02 18:44:31 +0000
commit5830ee0d3ff65246d6a80a17030fb0131023a3ce (patch)
tree9d3aeb6624a9893d4aa6ff0ec6a26d367985da7a /sys/fs/tmpfs/tmpfs_subr.c
parent3a177062d539e9291599fc04488ad378853d27ec (diff)
downloadFreeBSD-src-5830ee0d3ff65246d6a80a17030fb0131023a3ce.zip
FreeBSD-src-5830ee0d3ff65246d6a80a17030fb0131023a3ce.tar.gz
For the new regular tmpfs vnode, v_object is initialized before
insmntque() is called. The standard insmntque destructor resets the vop vector to deadfs one, and calls vgone() on the vnode. As result, v_object is kept unchanged, which triggers an assertion in the reclaim code, on instmntque() failure. Also, in this case, OBJ_TMPFS flag on the backed vm object is not cleared. Provide the tmpfs insmntque() destructor which properly clears OBJ_TMPFS flag and resets v_object. Reported and tested by: pho Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'sys/fs/tmpfs/tmpfs_subr.c')
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index f639b09..e751331 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -429,6 +429,36 @@ tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de)
/* --------------------------------------------------------------------- */
+void
+tmpfs_destroy_vobject(struct vnode *vp, vm_object_t obj)
+{
+
+ if (vp->v_type != VREG || obj == NULL)
+ return;
+
+ VM_OBJECT_WLOCK(obj);
+ VI_LOCK(vp);
+ vm_object_clear_flag(obj, OBJ_TMPFS);
+ obj->un_pager.swp.swp_tmpfs = NULL;
+ VI_UNLOCK(vp);
+ VM_OBJECT_WUNLOCK(obj);
+}
+
+/*
+ * Need to clear v_object for insmntque failure.
+ */
+static void
+tmpfs_insmntque_dtr(struct vnode *vp, void *dtr_arg)
+{
+
+ tmpfs_destroy_vobject(vp, vp->v_object);
+ vp->v_object = NULL;
+ vp->v_data = NULL;
+ vp->v_op = &dead_vnodeops;
+ vgone(vp);
+ vput(vp);
+}
+
/*
* Allocates a new vnode for the node node or returns a new reference to
* an existing one if the node had already a vnode referencing it. The
@@ -540,7 +570,7 @@ loop:
panic("tmpfs_alloc_vp: type %p %d", node, (int)node->tn_type);
}
- error = insmntque(vp, mp);
+ error = insmntque1(vp, mp, tmpfs_insmntque_dtr, NULL);
if (error)
vp = NULL;
OpenPOWER on IntegriCloud