* fs_sync() now holds the sVnodeMutex while iterating over the mount list.
* This has the advantage that we no longer need to call get_vnode(), and instead can use lookup_vnode(). * This means at least most of the "corrupted BFS inode" messages should be gone; they were produced when fs_sync() tried to get already deleted vnodes. This was actually harmless, but doesn't really help in trusting your system :-) * Also, it no longer tries to write back removed vnodes. * And finally, it now uses a marker vnode when iterating over the list, so that it doesn't need to break out of the loop anymore, and can always sync all willing vnodes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28212 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -7142,50 +7142,62 @@ fs_sync(dev_t device)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
struct vnode marker;
|
||||||
|
marker.remove = true;
|
||||||
|
|
||||||
// First, synchronize all file caches
|
// First, synchronize all file caches
|
||||||
|
|
||||||
struct vnode *previousVnode = NULL;
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
MutexLocker locker(sVnodeMutex);
|
||||||
|
|
||||||
// synchronize access to vnode list
|
// synchronize access to vnode list
|
||||||
recursive_lock_lock(&mount->rlock);
|
recursive_lock_lock(&mount->rlock);
|
||||||
|
|
||||||
struct vnode *vnode = previousVnode;
|
struct vnode *vnode;
|
||||||
do {
|
if (!marker.remove) {
|
||||||
|
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, &marker);
|
||||||
|
list_remove_item(&mount->vnodes, &marker);
|
||||||
|
marker.remove = true;
|
||||||
|
} else
|
||||||
|
vnode = (struct vnode *)list_get_first_item(&mount->vnodes);
|
||||||
|
|
||||||
|
while (vnode != NULL && (vnode->cache == NULL
|
||||||
|
|| vnode->remove || vnode->busy)) {
|
||||||
// TODO: we could track writes (and writable mapped vnodes)
|
// TODO: we could track writes (and writable mapped vnodes)
|
||||||
// and have a simple flag that we could test for here
|
// and have a simple flag that we could test for here
|
||||||
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode);
|
vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode);
|
||||||
} while (vnode != NULL && vnode->cache == NULL);
|
}
|
||||||
|
|
||||||
ino_t id = -1;
|
if (vnode != NULL) {
|
||||||
if (vnode != NULL)
|
// insert marker vnode again
|
||||||
id = vnode->id;
|
list_insert_item_before(&mount->vnodes,
|
||||||
|
list_get_next_item(&mount->vnodes, vnode), &marker);
|
||||||
|
marker.remove = false;
|
||||||
|
}
|
||||||
|
|
||||||
recursive_lock_unlock(&mount->rlock);
|
recursive_lock_unlock(&mount->rlock);
|
||||||
|
|
||||||
if (vnode == NULL)
|
if (vnode == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// acquire a reference to the vnode
|
vnode = lookup_vnode(mount->id, vnode->id);
|
||||||
|
if (vnode == NULL || vnode->busy)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (get_vnode(mount->id, id, &vnode, true, false) == B_OK) {
|
if (vnode->ref_count == 0) {
|
||||||
if (previousVnode != NULL)
|
// this vnode has been unused before
|
||||||
put_vnode(previousVnode);
|
list_remove_item(&sUnusedVnodeList, vnode);
|
||||||
|
sUnusedVnodes--;
|
||||||
if (vnode->cache != NULL)
|
|
||||||
vnode->cache->WriteModified();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
inc_vnode_ref_count(vnode);
|
||||||
|
|
||||||
if (previousVnode != NULL)
|
locker.Unlock();
|
||||||
put_vnode(previousVnode);
|
|
||||||
|
if (vnode->cache != NULL && !vnode->remove)
|
||||||
|
vnode->cache->WriteModified();
|
||||||
|
|
||||||
|
put_vnode(vnode);
|
||||||
|
}
|
||||||
|
|
||||||
// And then, let the file systems do their synchronizing work
|
// And then, let the file systems do their synchronizing work
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user