mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 07:18:40 +01:00
BFS: Keep references to vnodes during asynchronous I/O.
IORequest notifications begin by notifying the "finished" condition, then invoking the request callback, then invoking the parent callback. vfs_{read|write}_pages wait on the "finished" condition and then return at once, potentially releasing their references to the vnode in question, before the request callback is even invoked. The request callback is what (eventually) invokes iterative_io_finished_hook, which meant that we were accessing the Inode object after our reference to it had already been released. We can't really change IORequest notification order, as any one of the notifications could delete the request, and indeed the first one does here. So the solution is just to acquire another reference to the vnode and release it in the finished hook. Fixes #19122 and #8405.
This commit is contained in:
parent
138d92635d
commit
551a9b9a01
@ -113,6 +113,7 @@ iterative_io_finished_hook(void* cookie, io_request* request, status_t status,
|
|||||||
{
|
{
|
||||||
Inode* inode = (Inode*)cookie;
|
Inode* inode = (Inode*)cookie;
|
||||||
rw_lock_read_unlock(&inode->Lock());
|
rw_lock_read_unlock(&inode->Lock());
|
||||||
|
put_vnode(inode->GetVolume()->FSVolume(), inode->ID());
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,6 +523,12 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
|
|||||||
// We lock the node here and will unlock it in the "finished" hook.
|
// We lock the node here and will unlock it in the "finished" hook.
|
||||||
rw_lock_read_lock(&inode->Lock());
|
rw_lock_read_lock(&inode->Lock());
|
||||||
|
|
||||||
|
// Due to how I/O request notifications work, it is possible that
|
||||||
|
// some other thread could be notified that the request completed
|
||||||
|
// before we have a chance to release the read lock. We thus need
|
||||||
|
// our own reference to the vnode.
|
||||||
|
acquire_vnode(_volume, inode->ID());
|
||||||
|
|
||||||
return do_iterative_fd_io(volume->Device(), request,
|
return do_iterative_fd_io(volume->Device(), request,
|
||||||
iterative_io_get_vecs_hook, iterative_io_finished_hook, inode);
|
iterative_io_get_vecs_hook, iterative_io_finished_hook, inode);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user