* Rethought fs_sync(): since we no longer deadlock when calling

vm_cache_write_modified() here anymore since quite some time, it actually
  doesn't make any sense to call the file system's "fsync" method here.
  This should make syncing all file systems much faster when many vnodes are
  in use.
* If a file system doesn't use the file cache, it can still just sync everything
  it needs to in its "sync" method.
* Added a TODO item on how to improve sync speed further, if necessary.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23679 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-01-21 10:28:32 +00:00
parent 6d36996620
commit 731262c6dd
1 changed files with 20 additions and 11 deletions

View File

@ -6025,20 +6025,19 @@ fs_sync(dev_t device)
if (status < B_OK)
return status;
mutex_lock(&sMountMutex);
if (FS_MOUNT_CALL(mount, sync))
status = FS_MOUNT_CALL(mount, sync)(mount->cookie);
mutex_unlock(&sMountMutex);
// First, synchronize all file caches
struct vnode *previousVnode = NULL;
while (true) {
// synchronize access to vnode list
recursive_lock_lock(&mount->rlock);
struct vnode *vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
previousVnode);
struct vnode *vnode = previousVnode;
do {
// TODO: we could track writes (and writable mapped vnodes)
// and have a simple flag that we could test for here
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode);
} while (vnode != NULL && vnode->cache == NULL);
ino_t id = -1;
if (vnode != NULL)
@ -6055,14 +6054,15 @@ fs_sync(dev_t device)
if (previousVnode != NULL)
put_vnode(previousVnode);
if (FS_CALL(vnode, fsync) != NULL)
FS_CALL(vnode, fsync)(vnode->mount->cookie, vnode->private_node);
if (vnode->cache != NULL)
vm_cache_write_modified(vnode->cache, false);
// the next vnode might change until we lock the vnode list again,
// but this vnode won't go away since we keep a reference to it.
previousVnode = vnode;
} else {
dprintf("syncing of mount %ld stopped due to vnode %Ld.\n", mount->id, id);
dprintf("syncing of mount %ld stopped due to vnode %Ld.\n",
mount->id, id);
break;
}
}
@ -6070,6 +6070,15 @@ fs_sync(dev_t device)
if (previousVnode != NULL)
put_vnode(previousVnode);
// And then, let the file systems do their synchronizing work
mutex_lock(&sMountMutex);
if (FS_MOUNT_CALL(mount, sync))
status = FS_MOUNT_CALL(mount, sync)(mount->cookie);
mutex_unlock(&sMountMutex);
put_mount(mount);
return status;
}