aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2017-09-30 18:23:45 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2017-09-30 18:23:45 +0000
commite3e10c39f10f034d4eb6ba74f20cf3d7e37308ca (patch)
tree517d65791e6b02940a1e3d33400e4ca359cc0fe2
parentf3b5058c8ef9351b64b71188748d503ee714f70f (diff)
downloadsrc-e3e10c39f10f034d4eb6ba74f20cf3d7e37308ca.tar.gz
src-e3e10c39f10f034d4eb6ba74f20cf3d7e37308ca.zip
tmpfs: skip zero-sized page count updates
Such updates consisted of vast majority of modificiations, especially in tmpfs_reg_resize. For the case where page count did no change and the size grew we only need to update tn_size. Use this fact to avoid vm object lock/relock. MFC after: 1 week
Notes
Notes: svn path=/head/; revision=324127
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index b04d28ba4055..10acd4b17167 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -350,7 +350,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
case VREG:
uobj = node->tn_reg.tn_aobj;
if (uobj != NULL) {
- atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
+ if (uobj->size != 0)
+ atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
KASSERT((uobj->flags & OBJ_TMPFS) == 0,
("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj));
vm_object_deallocate(uobj);
@@ -1375,6 +1376,12 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
oldpages = OFF_TO_IDX(oldsize + PAGE_MASK);
MPASS(oldpages == uobj->size);
newpages = OFF_TO_IDX(newsize + PAGE_MASK);
+
+ if (__predict_true(newpages == oldpages && newsize >= oldsize)) {
+ node->tn_size = newsize;
+ return (0);
+ }
+
if (newpages > oldpages &&
tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0)
return (ENOSPC);