svn commit: r218640 - head/sys/fs/tmpfs

Alan Cox alc at FreeBSD.org
Sun Feb 13 14:46:40 UTC 2011


Author: alc
Date: Sun Feb 13 14:46:39 2011
New Revision: 218640
URL: http://svn.freebsd.org/changeset/base/218640

Log:
  Eliminate tn_reg.tn_aobj_pages.  Instead, correctly maintain the vm
  object's size field.  Previously, that field was always zero, even
  when the object tn_reg.tn_aobj contained numerous pages.
  
  Apply style fixes to tmpfs_reg_resize().
  
  In collaboration with:	kib

Modified:
  head/sys/fs/tmpfs/tmpfs.h
  head/sys/fs/tmpfs/tmpfs_subr.c

Modified: head/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs.h	Sun Feb 13 13:53:28 2011	(r218639)
+++ head/sys/fs/tmpfs/tmpfs.h	Sun Feb 13 14:46:39 2011	(r218640)
@@ -283,7 +283,6 @@ struct tmpfs_node {
 			 * issue the required page ins or page outs whenever
 			 * a position within the file is accessed. */
 			vm_object_t		tn_aobj;
-			size_t			tn_aobj_pages;
 
 		}tn_reg;
 

Modified: head/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c	Sun Feb 13 13:53:28 2011	(r218639)
+++ head/sys/fs/tmpfs/tmpfs_subr.c	Sun Feb 13 14:46:39 2011	(r218640)
@@ -146,7 +146,6 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp
 		nnode->tn_reg.tn_aobj =
 		    vm_pager_allocate(OBJT_SWAP, NULL, 0, VM_PROT_DEFAULT, 0,
 			NULL /* XXXKIB - tmpfs needs swap reservation */);
-		nnode->tn_reg.tn_aobj_pages = 0;
 		break;
 
 	default:
@@ -184,7 +183,7 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp
 void
 tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
 {
-	size_t pages = 0;
+	vm_object_t uobj;
 
 #ifdef INVARIANTS
 	TMPFS_NODE_LOCK(node);
@@ -220,9 +219,13 @@ tmpfs_free_node(struct tmpfs_mount *tmp,
 		break;
 
 	case VREG:
-		if (node->tn_reg.tn_aobj != NULL)
-			vm_object_deallocate(node->tn_reg.tn_aobj);
-		pages = node->tn_reg.tn_aobj_pages;
+		uobj = node->tn_reg.tn_aobj;
+		if (uobj != NULL) {
+			TMPFS_LOCK(tmp);
+			tmp->tm_pages_used -= uobj->size;
+			TMPFS_UNLOCK(tmp);
+			vm_object_deallocate(uobj);
+		}
 		break;
 
 	default:
@@ -231,10 +234,6 @@ tmpfs_free_node(struct tmpfs_mount *tmp,
 
 	free_unr(tmp->tm_ino_unr, node->tn_id);
 	uma_zfree(tmp->tm_node_pool, node);
-
-	TMPFS_LOCK(tmp);
-	tmp->tm_pages_used -= pages;
-	TMPFS_UNLOCK(tmp);
 }
 
 /* --------------------------------------------------------------------- */
@@ -884,16 +883,20 @@ tmpfs_dir_whiteout_remove(struct vnode *
 int
 tmpfs_reg_resize(struct vnode *vp, off_t newsize)
 {
-	int error;
-	size_t newpages, oldpages;
 	struct tmpfs_mount *tmp;
 	struct tmpfs_node *node;
+	vm_object_t uobj;
+	vm_page_t m;
+	vm_pindex_t newpages, oldpages;
 	off_t oldsize;
+	size_t zerolen;
+	int error;
 
 	MPASS(vp->v_type == VREG);
 	MPASS(newsize >= 0);
 
 	node = VP_TO_TMPFS_NODE(vp);
+	uobj = node->tn_reg.tn_aobj;
 	tmp = VFS_TO_TMPFS(vp->v_mount);
 
 	/* Convert the old and new sizes to the number of pages needed to
@@ -901,9 +904,9 @@ tmpfs_reg_resize(struct vnode *vp, off_t
 	 * because the last allocated page can accommodate the change on
 	 * its own. */
 	oldsize = node->tn_size;
-	oldpages = round_page(oldsize) / PAGE_SIZE;
-	MPASS(oldpages == node->tn_reg.tn_aobj_pages);
-	newpages = round_page(newsize) / PAGE_SIZE;
+	oldpages = OFF_TO_IDX(oldsize + PAGE_MASK);
+	MPASS(oldpages == uobj->size);
+	newpages = OFF_TO_IDX(newsize + PAGE_MASK);
 
 	if (newpages > oldpages &&
 	    newpages - oldpages > TMPFS_PAGES_AVAIL(tmp)) {
@@ -911,48 +914,39 @@ tmpfs_reg_resize(struct vnode *vp, off_t
 		goto out;
 	}
 
-	node->tn_reg.tn_aobj_pages = newpages;
-
 	TMPFS_LOCK(tmp);
 	tmp->tm_pages_used += (newpages - oldpages);
 	TMPFS_UNLOCK(tmp);
 
 	node->tn_size = newsize;
 	vnode_pager_setsize(vp, newsize);
+	VM_OBJECT_LOCK(uobj);
 	if (newsize < oldsize) {
-		size_t zerolen = round_page(newsize) - newsize;
-		vm_object_t uobj = node->tn_reg.tn_aobj;
-		vm_page_t m;
-
 		/*
 		 * free "backing store"
 		 */
-		VM_OBJECT_LOCK(uobj);
 		if (newpages < oldpages) {
-			swap_pager_freespace(uobj,
-						newpages, oldpages - newpages);
-			vm_object_page_remove(uobj,
-				OFF_TO_IDX(newsize + PAGE_MASK), 0, FALSE);
+			swap_pager_freespace(uobj, newpages, oldpages -
+			    newpages);
+			vm_object_page_remove(uobj, newpages, 0, FALSE);
 		}
 
 		/*
 		 * zero out the truncated part of the last page.
 		 */
-
+		zerolen = round_page(newsize) - newsize;
 		if (zerolen > 0) {
 			m = vm_page_grab(uobj, OFF_TO_IDX(newsize),
 			    VM_ALLOC_NOBUSY | VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
-			pmap_zero_page_area(m, PAGE_SIZE - zerolen,
-				zerolen);
+			pmap_zero_page_area(m, PAGE_SIZE - zerolen, zerolen);
 		}
-		VM_OBJECT_UNLOCK(uobj);
-
 	}
-
+	uobj->size = newpages;
+	VM_OBJECT_UNLOCK(uobj);
 	error = 0;
 
 out:
-	return error;
+	return (error);
 }
 
 /* --------------------------------------------------------------------- */


More information about the svn-src-all mailing list