summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-12-23 09:09:42 +0000
committerkib <kib@FreeBSD.org>2011-12-23 09:09:42 +0000
commitc2a7f1025365e002b4b0640500da172643227fb5 (patch)
treeaf24cd87039958ebef984fd0db3750b95269b464 /sys/vm
parent557be54d6324f110c3b92f5ee4916cf23409d5ed (diff)
downloadFreeBSD-src-c2a7f1025365e002b4b0640500da172643227fb5.zip
FreeBSD-src-c2a7f1025365e002b4b0640500da172643227fb5.tar.gz
Optimize the common case of msyncing the whole file mapping with
MS_SYNC flag. The system must guarantee that all writes are finished before syscalls returned. Schedule the writes in async mode, which is much faster and allows the clustering to occur. Wait for writes using VOP_FSYNC(), since we are syncing the whole file mapping. Potentially, the restriction to only apply the optimization can be relaxed by not requiring that the mapping cover whole file, as it is done by other OSes. Reported and tested by: az Reviewed by: alc MFC after: 2 weeks
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_object.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 250b769..a9de554 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -938,7 +938,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
vm_object_t backing_object;
struct vnode *vp;
struct mount *mp;
- int flags;
+ int flags, fsync_after;
if (object == NULL)
return;
@@ -971,11 +971,26 @@ vm_object_sync(vm_object_t object, vm_ooffset_t offset, vm_size_t size,
(void) vn_start_write(vp, &mp, V_WAIT);
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- flags = (syncio || invalidate) ? OBJPC_SYNC : 0;
- flags |= invalidate ? OBJPC_INVAL : 0;
+ if (syncio && !invalidate && offset == 0 &&
+ OFF_TO_IDX(size) == object->size) {
+ /*
+ * If syncing the whole mapping of the file,
+ * it is faster to schedule all the writes in
+ * async mode, also allowing the clustering,
+ * and then wait for i/o to complete.
+ */
+ flags = 0;
+ fsync_after = TRUE;
+ } else {
+ flags = (syncio || invalidate) ? OBJPC_SYNC : 0;
+ flags |= invalidate ? (OBJPC_SYNC | OBJPC_INVAL) : 0;
+ fsync_after = FALSE;
+ }
VM_OBJECT_LOCK(object);
vm_object_page_clean(object, offset, offset + size, flags);
VM_OBJECT_UNLOCK(object);
+ if (fsync_after)
+ (void) VOP_FSYNC(vp, MNT_WAIT, curthread);
VOP_UNLOCK(vp, 0);
VFS_UNLOCK_GIANT(vfslocked);
vn_finished_write(mp);
OpenPOWER on IntegriCloud