* 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:
parent
6d36996620
commit
731262c6dd
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user