From 731262c6dd0752b72ee2353d678edde643bf9daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 21 Jan 2008 10:28:32 +0000 Subject: [PATCH] * 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 --- src/system/kernel/fs/vfs.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 04659f1fbb..bd9f06b4d1 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -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; }