kernel - TMPFS - Stabilization pass, fix VM object leak, msync
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 20 Feb 2010 03:07:43 +0000 (19:07 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 20 Feb 2010 03:07:43 +0000 (19:07 -0800)
* The swap vm_object backing regular files was not being deallocated
  properly and leaked kernel memory.

* Truncate deleted files a little earlier in the INACTIVE path.

* Set MNTK_NOMSYNC.  This prevents msync(), sync(), and the
  periodic filesystem syncer from flushing pages to swap.

  VM pages related to tmpfs are only flushed based on memory
  pressure.

sys/vfs/tmpfs/tmpfs_subr.c
sys/vfs/tmpfs/tmpfs_vfsops.c
sys/vfs/tmpfs/tmpfs_vnops.c

index 3a666b0..9c928a6 100644 (file)
@@ -276,7 +276,7 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
 
        case VREG:
                if (node->tn_reg.tn_aobj != NULL)
-                       vm_pager_deallocate(node->tn_reg.tn_aobj);
+                       vm_object_deallocate(node->tn_reg.tn_aobj);
                node->tn_reg.tn_aobj = NULL;
                pages = node->tn_reg.tn_aobj_pages;
                break;
index 074d34d..b63c349 100644 (file)
@@ -245,6 +245,7 @@ tmpfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
        mp->mnt_kern_flag |= MNTK_RD_MPSAFE | MNTK_WR_MPSAFE | MNTK_GA_MPSAFE  |
                             MNTK_IN_MPSAFE | MNTK_SG_MPSAFE;
 #endif
+       mp->mnt_kern_flag |= MNTK_NOMSYNC;
        mp->mnt_data = (qaddr_t)tmp;
        vfs_getnewfsid(mp);
 
index 42e39d4..e8ba5b1 100644 (file)
@@ -1319,6 +1319,9 @@ tmpfs_inactive(struct vop_inactive_args *v)
        /*
         * Get rid of unreferenced deleted vnodes sooner rather than
         * later so the data memory can be recovered immediately.
+        *
+        * We must truncate the vnode to prevent the normal reclamation
+        * path from flushing the data for the removed file to disk.
         */
        TMPFS_NODE_LOCK(node);
        if ((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0 &&
@@ -1328,6 +1331,8 @@ tmpfs_inactive(struct vop_inactive_args *v)
        {
                node->tn_vpstate = TMPFS_VNODE_DOOMED;
                TMPFS_NODE_UNLOCK(node);
+               if (node->tn_type == VREG)
+                       tmpfs_truncate(vp, 0);
                vrecycle(vp);
        } else {
                TMPFS_NODE_UNLOCK(node);