From 9391dd214dd0aadcc0360c83839c24185d2c8967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 18 Mar 2005 01:24:11 +0000 Subject: [PATCH] Fixed broken handling of the new file_descriptor::open_count across team boundaries; if you didn't actually call close() from within the application, the close-hook of the file system was never called. Also, you could close files of other teams (ie. invoke close on a shared file descriptor). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11892 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/fd.h | 6 +++--- headers/private/kernel/vfs.h | 2 +- src/kernel/core/fs/fd.c | 18 ++++++++++++------ src/kernel/core/fs/vfs.cpp | 21 +++++++++++++-------- 4 files changed, 29 insertions(+), 18 deletions(-) diff --git a/headers/private/kernel/fd.h b/headers/private/kernel/fd.h index 27a71bd2cc..f0efb3775a 100644 --- a/headers/private/kernel/fd.h +++ b/headers/private/kernel/fd.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ #ifndef _FD_H @@ -68,8 +68,8 @@ extern struct file_descriptor *alloc_fd(void); extern int new_fd_etc(struct io_context *, struct file_descriptor *, int firstIndex); extern int new_fd(struct io_context *, struct file_descriptor *); extern struct file_descriptor *get_fd(struct io_context *, int); -extern void put_fd(struct file_descriptor *); -extern void free_fd(struct file_descriptor *); +extern void close_fd(struct file_descriptor *descriptor); +extern void put_fd(struct file_descriptor *descriptor); extern status_t select_fd(int fd, uint8 event, uint32 ref, struct select_sync *sync, bool kernel); extern status_t deselect_fd(int fd, uint8 event, struct select_sync *sync, bool kernel); extern bool fd_is_valid(int fd, bool kernel); diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 9554a67cb4..44ba220115 100755 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -58,7 +58,7 @@ status_t vfs_bootstrap_file_systems(void); status_t vfs_mount_boot_file_system(struct kernel_args *args); void vfs_exec_io_context(void *context); void *vfs_new_io_context(void *parentContext); -int vfs_free_io_context(void *context); +status_t vfs_free_io_context(void *context); struct rlimit; int vfs_getrlimit(int resource, struct rlimit * rlp); diff --git a/src/kernel/core/fs/fd.c b/src/kernel/core/fs/fd.c index 3ccdf9e401..8e1dbe4c90 100644 --- a/src/kernel/core/fs/fd.c +++ b/src/kernel/core/fs/fd.c @@ -1,6 +1,6 @@ /* Operations on file descriptors * - * Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -118,6 +118,16 @@ put_fd(struct file_descriptor *descriptor) } +void +close_fd(struct file_descriptor *descriptor) +{ + if (atomic_add(&descriptor->open_count, -1) == 1) { + if (descriptor->ops->fd_close) + descriptor->ops->fd_close(descriptor); + } +} + + struct file_descriptor * get_fd(struct io_context *context, int fd) { @@ -313,11 +323,7 @@ common_close(int fd, bool kernel) TRACE(("_user_close(descriptor = %p)\n", descriptor)); #endif - if (atomic_add(&descriptor->open_count, -1) == 1) { - if (descriptor->ops->fd_close) - descriptor->ops->fd_close(descriptor); - } - + close_fd(descriptor); put_fd(descriptor); // the reference associated with the slot diff --git a/src/kernel/core/fs/vfs.cpp b/src/kernel/core/fs/vfs.cpp index a55732704a..08454bd3d1 100644 --- a/src/kernel/core/fs/vfs.cpp +++ b/src/kernel/core/fs/vfs.cpp @@ -2531,9 +2531,12 @@ vfs_new_io_context(void *_parentContext) inc_vnode_ref_count(context->cwd); for (i = 0; i < tableSize; i++) { - if (parentContext->fds[i] && (parentContext->fds[i]->open_mode & O_CLOEXEC) == 0) { - context->fds[i] = parentContext->fds[i]; - atomic_add(&context->fds[i]->ref_count, 1); + struct file_descriptor *descriptor = parentContext->fds[i]; + + if (descriptor != NULL && (descriptor->open_mode & O_CLOEXEC) == 0) { + context->fds[i] = descriptor; + atomic_add(&descriptor->ref_count, 1); + atomic_add(&descriptor->open_count, 1); } } @@ -2554,7 +2557,7 @@ vfs_new_io_context(void *_parentContext) } -int +status_t vfs_free_io_context(void *_ioContext) { struct io_context *context = (struct io_context *)_ioContext; @@ -2566,8 +2569,10 @@ vfs_free_io_context(void *_ioContext) mutex_lock(&context->io_mutex); for (i = 0; i < context->table_size; i++) { - if (context->fds[i]) - put_fd(context->fds[i]); + if (struct file_descriptor *descriptor = context->fds[i]) { + close_fd(descriptor); + put_fd(descriptor); + } } mutex_unlock(&context->io_mutex); @@ -2578,11 +2583,11 @@ vfs_free_io_context(void *_ioContext) free(context->fds); free(context); - return 0; + return B_OK; } -static int +static status_t vfs_resize_fd_table(struct io_context *context, const int newSize) { void *fds;