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
This commit is contained in:
Konstantin Belousov 2011-12-23 09:09:42 +00:00
parent 252b52fd58
commit 75ff604a78
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=228838

View File

@ -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);