svn commit: r250189 - head/sys/fs/tmpfs
Konstantin Belousov
kib at FreeBSD.org
Thu May 2 18:44:33 UTC 2013
Author: kib
Date: Thu May 2 18:44:31 2013
New Revision: 250189
URL: http://svnweb.freebsd.org/changeset/base/250189
Log:
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
Modified:
head/sys/fs/tmpfs/tmpfs.h
head/sys/fs/tmpfs/tmpfs_subr.c
head/sys/fs/tmpfs/tmpfs_vnops.c
Modified: head/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs.h Thu May 2 18:36:52 2013 (r250188)
+++ head/sys/fs/tmpfs/tmpfs.h Thu May 2 18:44:31 2013 (r250189)
@@ -402,6 +402,7 @@ int tmpfs_alloc_dirent(struct tmpfs_moun
const char *, u_int, struct tmpfs_dirent **);
void tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *);
void tmpfs_dirent_init(struct tmpfs_dirent *, const char *, u_int);
+void tmpfs_destroy_vobject(struct vnode *vp, vm_object_t obj);
int tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, int,
struct vnode **);
void tmpfs_free_vp(struct vnode *);
Modified: head/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c Thu May 2 18:36:52 2013 (r250188)
+++ head/sys/fs/tmpfs/tmpfs_subr.c Thu May 2 18:44:31 2013 (r250189)
@@ -429,6 +429,36 @@ tmpfs_free_dirent(struct tmpfs_mount *tm
/* --------------------------------------------------------------------- */
+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;
Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c Thu May 2 18:36:52 2013 (r250188)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c Thu May 2 18:44:31 2013 (r250189)
@@ -1468,23 +1468,12 @@ tmpfs_reclaim(struct vop_reclaim_args *v
struct tmpfs_mount *tmp;
struct tmpfs_node *node;
- vm_object_t obj;
node = VP_TO_TMPFS_NODE(vp);
tmp = VFS_TO_TMPFS(vp->v_mount);
- if (node->tn_type == VREG) {
- obj = node->tn_reg.tn_aobj;
- if (obj != NULL) {
- /* Instead of vnode_destroy_vobject() */
- 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);
- }
- }
+ if (vp->v_type == VREG)
+ tmpfs_destroy_vobject(vp, node->tn_reg.tn_aobj);
vp->v_object = NULL;
cache_purge(vp);
More information about the svn-src-all
mailing list