fs: Avoid deadlock when renaming
This commit is contained in:
@@ -131,8 +131,11 @@ void vfs_entry_replace_children(struct vfs_entry* dst, struct vfs_entry* src) {
|
||||
tailq_head(struct vfs_entry) stale;
|
||||
tailq_init(&stale);
|
||||
|
||||
mutex_lock(&src->lock);
|
||||
mutex_lock(&dst->lock);
|
||||
// Avoid a potential deadlock when this function is called with (a, b) and (b, a) at the same time.
|
||||
struct vfs_entry* first = src < dst ? src : dst;
|
||||
struct vfs_entry* second = src < dst ? dst : src;
|
||||
mutex_lock(&first->lock);
|
||||
mutex_lock(&second->lock);
|
||||
struct vfs_entry* child;
|
||||
while ((child = tailq_first(&dst->children))) {
|
||||
tailq_remove(&dst->children, child, child_link);
|
||||
@@ -145,8 +148,8 @@ void vfs_entry_replace_children(struct vfs_entry* dst, struct vfs_entry* src) {
|
||||
vfs_entry_unref(src);
|
||||
tailq_insert_tail(&dst->children, child, child_link);
|
||||
}
|
||||
mutex_unlock(&dst->lock);
|
||||
mutex_unlock(&src->lock);
|
||||
mutex_unlock(&second->lock);
|
||||
mutex_unlock(&first->lock);
|
||||
|
||||
while ((child = tailq_first(&stale))) {
|
||||
tailq_remove(&stale, child, child_link);
|
||||
|
||||
Reference in New Issue
Block a user