diff --git a/libos/src/sys/libos_file.c b/libos/src/sys/libos_file.c index f4050813d3..70c6a8f0a6 100644 --- a/libos/src/sys/libos_file.c +++ b/libos/src/sys/libos_file.c @@ -347,8 +347,31 @@ static int do_rename(struct libos_dentry* old_dent, struct libos_dentry* new_den if (new_dent->inode) put_inode(new_dent->inode); + new_dent->inode = old_dent->inode; old_dent->inode = NULL; + + /* also update dentry of any potentially open fd pointing to old_dent */ + struct libos_handle_map* handle_map = get_thread_handle_map(NULL); + assert(handle_map != NULL); + rwlock_read_lock(&handle_map->lock); + + for (uint32_t i = 0; handle_map->fd_top != FD_NULL && i <= handle_map->fd_top; i++) { + struct libos_fd_handle* fd_handle = handle_map->map[i]; + if (!HANDLE_ALLOCATED(fd_handle)) + continue; + struct libos_handle* handle = fd_handle->handle; + /* see comment in libos_handle.h on loocking strategy protecting handle->lock */ + assert(locked(&g_dcache_lock)); + lock(&handle->lock); + if ((handle->dentry == old_dent) && (handle->inode == new_dent->inode)) { + handle->dentry = new_dent; + put_dentry(old_dent); + get_dentry(new_dent); + } + unlock(&handle->lock); + } + rwlock_read_unlock(&handle_map->lock); return 0; }