fs: Avoid deadlock when renaming

This commit is contained in:
2026-11-02 21:51:22 +01:00
committed by Marvin Friedrich
parent 7c04530681
commit 54f279a9e6
+7 -4
View File
@@ -131,8 +131,11 @@ void vfs_entry_replace_children(struct vfs_entry* dst, struct vfs_entry* src) {
tailq_head(struct vfs_entry) stale; tailq_head(struct vfs_entry) stale;
tailq_init(&stale); tailq_init(&stale);
mutex_lock(&src->lock); // Avoid a potential deadlock when this function is called with (a, b) and (b, a) at the same time.
mutex_lock(&dst->lock); 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; struct vfs_entry* child;
while ((child = tailq_first(&dst->children))) { while ((child = tailq_first(&dst->children))) {
tailq_remove(&dst->children, child, child_link); 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); vfs_entry_unref(src);
tailq_insert_tail(&dst->children, child, child_link); tailq_insert_tail(&dst->children, child, child_link);
} }
mutex_unlock(&dst->lock); mutex_unlock(&second->lock);
mutex_unlock(&src->lock); mutex_unlock(&first->lock);
while ((child = tailq_first(&stale))) { while ((child = tailq_first(&stale))) {
tailq_remove(&stale, child, child_link); tailq_remove(&stale, child, child_link);