diff --git a/kernel-src/fs/ext2.c b/kernel-src/fs/ext2.c index c75426ea..3d12f61c 100644 --- a/kernel-src/fs/ext2.c +++ b/kernel-src/fs/ext2.c @@ -1833,30 +1833,34 @@ static int ext2_rename(vnode_t *sourcedir, vnode_t *source, char *oldname, vnode if (replaced_vnode) { // we are replacing an existing link // do some checks expected by posix - // TODO add these to fatfs and tmpfs if (source->type != V_TYPE_DIR && replaced_vnode->type == V_TYPE_DIR) { + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); return EISDIR; } if (source->type == V_TYPE_DIR && replaced_vnode->type != V_TYPE_DIR) { + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); return ENOTDIR; } if (replaced_vnode->vfsmounted) { + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); return EBUSY; } err = replaced_vnode->type == V_TYPE_DIR ? is_directory_empty(ext2_replaced_node) : 0; if (err) { + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); return err; } if (source == replaced_vnode) { // POSIX says that if both are the same file, rename is a no-op + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); return 0; } @@ -1873,9 +1877,11 @@ static int ext2_rename(vnode_t *sourcedir, vnode_t *source, char *oldname, vnode err = handleinodeunlink(fs, ext2targetdirnode, oldinode, ext2_replaced_node); ext2sourcenode->inode.links += 1; ASSERT_UNCLEAN(fs, writeinode(fs, &ext2sourcenode->inode, ext2sourcenode->id) == 0); + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); } else if (err) { if (replaced_vnode) { + VOP_UNLOCK(replaced_vnode); VOP_RELEASE(replaced_vnode); } } diff --git a/kernel-src/fs/fat/fatfs.c b/kernel-src/fs/fat/fatfs.c index 2e686158..61ff5a56 100644 --- a/kernel-src/fs/fat/fatfs.c +++ b/kernel-src/fs/fat/fatfs.c @@ -731,28 +731,33 @@ static int fatfs_rename(vnode_t *vsource_dir, vnode_t *vsource, char *old_name, // we are replacing an existing link // do some checks expected by posix if (vsource->type != V_TYPE_DIR && vtarget->type == V_TYPE_DIR) { + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return EISDIR; } if (vsource->type == V_TYPE_DIR && vtarget->type != V_TYPE_DIR) { + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return ENOTDIR; } if (vtarget->vfsmounted) { + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return EBUSY; } error = vtarget->type == V_TYPE_DIR ? is_directory_empty(target) : 0; if (error) { + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return error; } if (source == target) { // POSIX says that if both are the same file, rename is a no-op + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return 0; } @@ -782,6 +787,7 @@ static int fatfs_rename(vnode_t *vsource_dir, vnode_t *vsource, char *old_name, size_t written; error = vfs_write(fatfs->backing, &new_dent, sizeof(new_dent), dent_disk_offset, &written, 0); if (error) { + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); return error; } @@ -796,13 +802,17 @@ static int fatfs_rename(vnode_t *vsource_dir, vnode_t *vsource, char *old_name, VOP_RELEASE(vtarget); // table hold __assert(target->parent_dir == target_dir); - VOP_RELEASE(vtarget_dir) + VOP_RELEASE(vtarget_dir); target->parent_dir = NULL; target->dent_disk_offset = 0; + VOP_UNLOCK(vtarget); VOP_RELEASE(vtarget); // lookup hold } else { - VOP_RELEASE(vtarget); + if (vtarget) { + VOP_UNLOCK(vtarget); + VOP_RELEASE(vtarget); + } return error; }