From 65a86bce722ae67274a1b3b07db84e2482f0fcc7 Mon Sep 17 00:00:00 2001 From: X512 Date: Sat, 13 Jul 2024 07:14:34 +0900 Subject: [PATCH] kernel/fd: use function table to identify file descriptor type It allows introducing new file descriptor types without editing enumeration every time. Anonymous FDs will be needed for Mesa OpenGL/Vulkan drivers to reference GPU memory buffers and other driver objects that can be referenced as FDs from userland. This change breaks private VFS API compatibility. No behavior changes intended. Change-Id: Iac109aad420b0b6aae704b38619436e01dcf4969 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7838 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- headers/private/kernel/file_cache.h | 8 +- headers/private/kernel/fs/fd.h | 20 +--- .../kernel/file_cache/launch_speedup.cpp | 4 +- src/system/kernel/cache/file_cache.cpp | 8 +- src/system/kernel/events/event_queue.cpp | 49 +++++----- src/system/kernel/fs/fd.cpp | 19 +--- src/system/kernel/fs/socket.cpp | 91 +++++++++--------- src/system/kernel/fs/vfs.cpp | 94 +++++++++---------- 8 files changed, 125 insertions(+), 168 deletions(-) diff --git a/headers/private/kernel/file_cache.h b/headers/private/kernel/file_cache.h index 3e8fee2af6..36198ec255 100644 --- a/headers/private/kernel/file_cache.h +++ b/headers/private/kernel/file_cache.h @@ -26,9 +26,9 @@ struct cache_module_info { module_info info; - void (*node_opened)(struct vnode *vnode, int32 fdType, dev_t mountID, + void (*node_opened)(struct vnode *vnode, dev_t mountID, ino_t parentID, ino_t vnodeID, const char *name, off_t size); - void (*node_closed)(struct vnode *vnode, int32 fdType, dev_t mountID, + void (*node_closed)(struct vnode *vnode, dev_t mountID, ino_t vnodeID, int32 accessType); void (*node_launched)(size_t argCount, char * const *args); }; @@ -37,9 +37,9 @@ struct cache_module_info { extern "C" { #endif -extern void cache_node_opened(struct vnode *vnode, int32 fdType, VMCache *cache, +extern void cache_node_opened(struct vnode *vnode, VMCache *cache, dev_t mountID, ino_t parentID, ino_t vnodeID, const char *name); -extern void cache_node_closed(struct vnode *vnode, int32 fdType, VMCache *cache, +extern void cache_node_closed(struct vnode *vnode, VMCache *cache, dev_t mountID, ino_t vnodeID); extern void cache_node_launched(size_t argCount, char * const *args); extern void cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size); diff --git a/headers/private/kernel/fs/fd.h b/headers/private/kernel/fs/fd.h index d8d2777f8f..52133f6d17 100644 --- a/headers/private/kernel/fs/fd.h +++ b/headers/private/kernel/fs/fd.h @@ -15,10 +15,8 @@ extern "C" { #endif -struct event_queue; struct file_descriptor; struct io_context; -struct net_socket; struct selectsync; struct select_info; @@ -47,15 +45,12 @@ struct fd_ops { }; struct file_descriptor { - int32 type; /* descriptor type */ int32 ref_count; int32 open_count; struct fd_ops *ops; union { struct vnode *vnode; struct fs_mount *mount; - struct net_socket *socket; - struct event_queue *queue; } u; void *cookie; int32 open_mode; @@ -63,20 +58,6 @@ struct file_descriptor { }; -/* Types of file descriptors we can create */ - -enum fd_types { - FDTYPE_FILE = 1, - FDTYPE_ATTR, - FDTYPE_DIR, - FDTYPE_ATTR_DIR, - FDTYPE_INDEX, - FDTYPE_INDEX_DIR, - FDTYPE_QUERY, - FDTYPE_SOCKET, - FDTYPE_EVENT_QUEUE -}; - // additional open mode - kernel special #define O_DISCONNECTED 0x80000000 @@ -99,6 +80,7 @@ extern status_t select_fd(int32 fd, struct select_info *info, bool kernel); extern status_t deselect_fd(int32 fd, struct select_info *info, bool kernel); extern bool fd_is_valid(int fd, bool kernel); extern struct vnode *fd_vnode(struct file_descriptor *descriptor); +extern bool fd_is_file(struct file_descriptor* descriptor); extern bool fd_close_on_exec(struct io_context *context, int fd); extern void fd_set_close_on_exec(struct io_context *context, int fd, diff --git a/src/add-ons/kernel/file_cache/launch_speedup.cpp b/src/add-ons/kernel/file_cache/launch_speedup.cpp index 90d3d511ef..8d53c3f14d 100644 --- a/src/add-ons/kernel/file_cache/launch_speedup.cpp +++ b/src/add-ons/kernel/file_cache/launch_speedup.cpp @@ -709,7 +709,7 @@ SessionGetter::Stop() static void -node_opened(struct vnode *vnode, int32 fdType, dev_t device, ino_t parent, +node_opened(struct vnode *vnode, dev_t device, ino_t parent, ino_t node, const char *name, off_t size) { if (device < gBootDevice) { @@ -744,7 +744,7 @@ node_opened(struct vnode *vnode, int32 fdType, dev_t device, ino_t parent, static void -node_closed(struct vnode *vnode, int32 fdType, dev_t device, ino_t node, +node_closed(struct vnode *vnode, dev_t device, ino_t node, int32 accessType) { Session *session; diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 98a4f3c2a6..a0b80a9922 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -1053,7 +1053,7 @@ cache_prefetch(dev_t mountID, ino_t vnodeID, off_t offset, size_t size) extern "C" void -cache_node_opened(struct vnode* vnode, int32 fdType, VMCache* cache, +cache_node_opened(struct vnode* vnode, VMCache* cache, dev_t mountID, ino_t parentID, ino_t vnodeID, const char* name) { if (sCacheModule == NULL || sCacheModule->node_opened == NULL) @@ -1066,13 +1066,13 @@ cache_node_opened(struct vnode* vnode, int32 fdType, VMCache* cache, size = cache->virtual_end; } - sCacheModule->node_opened(vnode, fdType, mountID, parentID, vnodeID, name, + sCacheModule->node_opened(vnode, mountID, parentID, vnodeID, name, size); } extern "C" void -cache_node_closed(struct vnode* vnode, int32 fdType, VMCache* cache, +cache_node_closed(struct vnode* vnode, VMCache* cache, dev_t mountID, ino_t vnodeID) { if (sCacheModule == NULL || sCacheModule->node_closed == NULL) @@ -1083,7 +1083,7 @@ cache_node_closed(struct vnode* vnode, int32 fdType, VMCache* cache, // ToDo: set accessType } - sCacheModule->node_closed(vnode, fdType, mountID, vnodeID, accessType); + sCacheModule->node_closed(vnode, mountID, vnodeID, accessType); } diff --git a/src/system/kernel/events/event_queue.cpp b/src/system/kernel/events/event_queue.cpp index f6658dea8b..0aef35d0d1 100644 --- a/src/system/kernel/events/event_queue.cpp +++ b/src/system/kernel/events/event_queue.cpp @@ -549,7 +549,7 @@ EventQueue::_GetEvent(int32 object, uint16 type) static status_t event_queue_close(file_descriptor* descriptor) { - EventQueue* queue = (EventQueue*)descriptor->u.queue; + EventQueue* queue = (EventQueue*)descriptor->cookie; queue->Closed(); return B_OK; } @@ -558,30 +558,11 @@ event_queue_close(file_descriptor* descriptor) static void event_queue_free(file_descriptor* descriptor) { - EventQueue* queue = (EventQueue*)descriptor->u.queue; + EventQueue* queue = (EventQueue*)descriptor->cookie; put_select_sync(queue); } -static status_t -get_queue_descriptor(int fd, bool kernel, file_descriptor*& descriptor) -{ - if (fd < 0) - return B_FILE_ERROR; - - descriptor = get_fd(get_current_io_context(kernel), fd); - if (descriptor == NULL) - return B_FILE_ERROR; - - if (descriptor->type != FDTYPE_EVENT_QUEUE) { - put_fd(descriptor); - return B_BAD_VALUE; - } - - return B_OK; -} - - #define GET_QUEUE_FD_OR_RETURN(fd, kernel, descriptor) \ do { \ status_t getError = get_queue_descriptor(fd, kernel, descriptor); \ @@ -607,6 +588,25 @@ static struct fd_ops sEventQueueFDOps = { }; +static status_t +get_queue_descriptor(int fd, bool kernel, file_descriptor*& descriptor) +{ + if (fd < 0) + return B_FILE_ERROR; + + descriptor = get_fd(get_current_io_context(kernel), fd); + if (descriptor == NULL) + return B_FILE_ERROR; + + if (descriptor->ops != &sEventQueueFDOps) { + put_fd(descriptor); + return B_BAD_VALUE; + } + + return B_OK; +} + + // #pragma mark - User syscalls @@ -623,9 +623,8 @@ _user_event_queue_create(int openFlags) if (descriptor == NULL) return B_NO_MEMORY; - descriptor->type = FDTYPE_EVENT_QUEUE; descriptor->ops = &sEventQueueFDOps; - descriptor->u.queue = (struct event_queue*)queue; + descriptor->cookie = (struct event_queue*)queue; descriptor->open_mode = O_RDWR | openFlags; io_context* context = get_current_io_context(false); @@ -660,7 +659,7 @@ _user_event_queue_select(int queue, event_wait_info* userInfos, int numInfos) GET_QUEUE_FD_OR_RETURN(queue, false, descriptor); FileDescriptorPutter _(descriptor); - EventQueue* eventQueue = (EventQueue*)descriptor->u.queue; + EventQueue* eventQueue = (EventQueue*)descriptor->cookie; if (user_memcpy(infos, userInfos, sizeof(event_wait_info) * numInfos) != B_OK) return B_BAD_ADDRESS; @@ -713,7 +712,7 @@ _user_event_queue_wait(int queue, event_wait_info* userInfos, int numInfos, GET_QUEUE_FD_OR_RETURN(queue, false, descriptor); FileDescriptorPutter _(descriptor); - EventQueue* eventQueue = (EventQueue*)descriptor->u.queue; + EventQueue* eventQueue = (EventQueue*)descriptor->cookie; ssize_t result = eventQueue->Wait(infos, numInfos, flags, timeout); if (result < 0) diff --git a/src/system/kernel/fs/fd.cpp b/src/system/kernel/fs/fd.cpp index edfe26af3a..3a660e60f6 100644 --- a/src/system/kernel/fs/fd.cpp +++ b/src/system/kernel/fs/fd.cpp @@ -205,7 +205,7 @@ void close_fd(struct io_context* context, struct file_descriptor* descriptor) { // POSIX advisory locks need to be released when any file descriptor closes - if (descriptor->type == FDTYPE_FILE) + if (fd_is_file(descriptor)) vfs_release_posix_lock(context, descriptor); if (atomic_add(&descriptor->open_count, -1) == 1) { @@ -683,21 +683,6 @@ fd_is_valid(int fd, bool kernel) } -struct vnode* -fd_vnode(struct file_descriptor* descriptor) -{ - switch (descriptor->type) { - case FDTYPE_FILE: - case FDTYPE_DIR: - case FDTYPE_ATTR_DIR: - case FDTYPE_ATTR: - return descriptor->u.vnode; - } - - return NULL; -} - - static ssize_t common_vector_io(int fd, off_t pos, const iovec* vecs, size_t count, bool write, bool kernel) { @@ -728,7 +713,7 @@ common_vector_io(int fd, off_t pos, const iovec* vecs, size_t count, bool write, // for vnodes that have no cache, as the I/O hook bypasses the cache entirely. struct vnode* vnode = descriptor->u.vnode; status_t status = B_OK; - if (!movePosition && pos != -1 && count > 1 && descriptor->type == FDTYPE_FILE + if (!movePosition && pos != -1 && count > 1 && fd_is_file(descriptor.Get()) && vnode != NULL && vnode->cache == NULL && vnode->ops->io != NULL) { BStackOrHeapArray iovecs(count); if (!iovecs.IsValid()) diff --git a/src/system/kernel/fs/socket.cpp b/src/system/kernel/fs/socket.cpp index 7f8b3484bc..32278b0585 100644 --- a/src/system/kernel/fs/socket.cpp +++ b/src/system/kernel/fs/socket.cpp @@ -193,25 +193,6 @@ prepare_userland_msghdr(const msghdr* userMessage, msghdr& message, } -static status_t -get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor) -{ - if (fd < 0) - return EBADF; - - descriptor = get_fd(get_current_io_context(kernel), fd); - if (descriptor == NULL) - return EBADF; - - if (descriptor->type != FDTYPE_SOCKET) { - put_fd(descriptor); - return ENOTSOCK; - } - - return B_OK; -} - - // #pragma mark - socket file descriptor @@ -219,7 +200,7 @@ static status_t socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer, size_t *_length) { - ssize_t bytesRead = sStackInterface->recv(descriptor->u.socket, buffer, + ssize_t bytesRead = sStackInterface->recv((net_socket*)descriptor->cookie, buffer, *_length, 0); *_length = bytesRead >= 0 ? bytesRead : 0; return bytesRead >= 0 ? B_OK : bytesRead; @@ -230,7 +211,7 @@ static status_t socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer, size_t *_length) { - ssize_t bytesWritten = sStackInterface->send(descriptor->u.socket, buffer, + ssize_t bytesWritten = sStackInterface->send((net_socket*)descriptor->cookie, buffer, *_length, 0); *_length = bytesWritten >= 0 ? bytesWritten : 0; return bytesWritten >= 0 ? B_OK : bytesWritten; @@ -241,7 +222,7 @@ static status_t socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, size_t length) { - return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length); + return sStackInterface->ioctl((net_socket*)descriptor->cookie, op, buffer, length); } @@ -252,7 +233,7 @@ socket_set_flags(struct file_descriptor *descriptor, int flags) uint32 op = (flags & O_NONBLOCK) != 0 ? B_SET_NONBLOCKING_IO : B_SET_BLOCKING_IO; - return sStackInterface->ioctl(descriptor->u.socket, op, NULL, 0); + return sStackInterface->ioctl((net_socket*)descriptor->cookie, op, NULL, 0); } @@ -260,7 +241,7 @@ static status_t socket_select(struct file_descriptor *descriptor, uint8 event, struct selectsync *sync) { - return sStackInterface->select(descriptor->u.socket, event, sync); + return sStackInterface->select((net_socket*)descriptor->cookie, event, sync); } @@ -268,7 +249,7 @@ static status_t socket_deselect(struct file_descriptor *descriptor, uint8 event, struct selectsync *sync) { - return sStackInterface->deselect(descriptor->u.socket, event, sync); + return sStackInterface->deselect((net_socket*)descriptor->cookie, event, sync); } @@ -276,7 +257,7 @@ static status_t socket_read_stat(struct file_descriptor *descriptor, struct stat *st) { st->st_dev = 0; - st->st_ino = (addr_t)descriptor->u.socket; + st->st_ino = (addr_t)descriptor->cookie; st->st_mode = S_IFSOCK | 0666; st->st_nlink = 1; st->st_uid = 0; @@ -302,14 +283,14 @@ socket_read_stat(struct file_descriptor *descriptor, struct stat *st) static status_t socket_close(struct file_descriptor *descriptor) { - return sStackInterface->close(descriptor->u.socket); + return sStackInterface->close((net_socket*)descriptor->cookie); } static void socket_free(struct file_descriptor *descriptor) { - sStackInterface->free(descriptor->u.socket); + sStackInterface->free((net_socket*)descriptor->cookie); put_stack_interface_module(); } @@ -331,6 +312,25 @@ static struct fd_ops sSocketFDOps = { }; +static status_t +get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor) +{ + if (fd < 0) + return EBADF; + + descriptor = get_fd(get_current_io_context(kernel), fd); + if (descriptor == NULL) + return EBADF; + + if (descriptor->ops != &sSocketFDOps) { + put_fd(descriptor); + return ENOTSOCK; + } + + return B_OK; +} + + static int create_socket_fd(net_socket* socket, bool kernel) { @@ -349,9 +349,8 @@ create_socket_fd(net_socket* socket, bool kernel) return B_NO_MEMORY; // init it - descriptor->type = FDTYPE_SOCKET; descriptor->ops = &sSocketFDOps; - descriptor->u.socket = socket; + descriptor->cookie = socket; descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0); // publish it @@ -402,7 +401,7 @@ common_bind(int fd, const struct sockaddr *address, socklen_t addressLength, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->bind(descriptor->u.socket, address, addressLength); + return sStackInterface->bind((net_socket*)descriptor->cookie, address, addressLength); } @@ -413,7 +412,7 @@ common_shutdown(int fd, int how, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->shutdown(descriptor->u.socket, how); + return sStackInterface->shutdown((net_socket*)descriptor->cookie, how); } @@ -425,7 +424,7 @@ common_connect(int fd, const struct sockaddr *address, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->connect(descriptor->u.socket, address, + return sStackInterface->connect((net_socket*)descriptor->cookie, address, addressLength); } @@ -437,7 +436,7 @@ common_listen(int fd, int backlog, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->listen(descriptor->u.socket, backlog); + return sStackInterface->listen((net_socket*)descriptor->cookie, backlog); } @@ -450,7 +449,7 @@ common_accept(int fd, struct sockaddr *address, socklen_t *_addressLength, FileDescriptorPutter _(descriptor); net_socket* acceptedSocket; - status_t error = sStackInterface->accept(descriptor->u.socket, address, + status_t error = sStackInterface->accept((net_socket*)descriptor->cookie, address, _addressLength, &acceptedSocket); if (error != B_OK) return error; @@ -476,7 +475,7 @@ common_recv(int fd, void *data, size_t length, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->recv(descriptor->u.socket, data, length, flags); + return sStackInterface->recv((net_socket*)descriptor->cookie, data, length, flags); } @@ -488,7 +487,7 @@ common_recvfrom(int fd, void *data, size_t length, int flags, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->recvfrom(descriptor->u.socket, data, length, + return sStackInterface->recvfrom((net_socket*)descriptor->cookie, data, length, flags, address, _addressLength); } @@ -500,7 +499,7 @@ common_recvmsg(int fd, struct msghdr *message, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->recvmsg(descriptor->u.socket, message, flags); + return sStackInterface->recvmsg((net_socket*)descriptor->cookie, message, flags); } @@ -511,7 +510,7 @@ common_send(int fd, const void *data, size_t length, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->send(descriptor->u.socket, data, length, flags); + return sStackInterface->send((net_socket*)descriptor->cookie, data, length, flags); } @@ -523,7 +522,7 @@ common_sendto(int fd, const void *data, size_t length, int flags, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->sendto(descriptor->u.socket, data, length, flags, + return sStackInterface->sendto((net_socket*)descriptor->cookie, data, length, flags, address, addressLength); } @@ -535,7 +534,7 @@ common_sendmsg(int fd, const struct msghdr *message, int flags, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->sendmsg(descriptor->u.socket, message, flags); + return sStackInterface->sendmsg((net_socket*)descriptor->cookie, message, flags); } @@ -547,7 +546,7 @@ common_getsockopt(int fd, int level, int option, void *value, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->getsockopt(descriptor->u.socket, level, option, + return sStackInterface->getsockopt((net_socket*)descriptor->cookie, level, option, value, _length); } @@ -560,7 +559,7 @@ common_setsockopt(int fd, int level, int option, const void *value, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->setsockopt(descriptor->u.socket, level, option, + return sStackInterface->setsockopt((net_socket*)descriptor->cookie, level, option, value, length); } @@ -573,7 +572,7 @@ common_getpeername(int fd, struct sockaddr *address, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->getpeername(descriptor->u.socket, address, + return sStackInterface->getpeername((net_socket*)descriptor->cookie, address, _addressLength); } @@ -586,7 +585,7 @@ common_getsockname(int fd, struct sockaddr *address, GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->getsockname(descriptor->u.socket, address, + return sStackInterface->getsockname((net_socket*)descriptor->cookie, address, _addressLength); } @@ -598,7 +597,7 @@ common_sockatmark(int fd, bool kernel) GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); FileDescriptorPutter _(descriptor); - return sStackInterface->sockatmark(descriptor->u.socket); + return sStackInterface->sockatmark((net_socket*)descriptor->cookie); } diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index f2b4919f72..eeb08ea9b5 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -2785,8 +2785,28 @@ fd_and_path_to_vnode(int fd, char* path, bool traverseLeafLink, } +struct vnode* +fd_vnode(struct file_descriptor* descriptor) +{ + if (descriptor->ops == &sFileOps + || descriptor->ops == &sDirectoryOps + || descriptor->ops == &sAttributeOps + || descriptor->ops == &sAttributeDirectoryOps) + return descriptor->u.vnode; + + return NULL; +} + + +bool +fd_is_file(struct file_descriptor* descriptor) +{ + return descriptor->ops == &sFileOps; +} + + static int -get_new_fd(int type, struct fs_mount* mount, struct vnode* vnode, +get_new_fd(struct fd_ops* ops, struct fs_mount* mount, struct vnode* vnode, void* cookie, int openMode, bool kernel) { struct file_descriptor* descriptor; @@ -2795,7 +2815,7 @@ get_new_fd(int type, struct fs_mount* mount, struct vnode* vnode, // If the vnode is locked, we don't allow creating a new file/directory // file_descriptor for it if (vnode && vnode->mandatory_locked_by != NULL - && (type == FDTYPE_FILE || type == FDTYPE_DIR)) + && (ops == &sFileOps || ops == &sDirectoryOps)) return B_BUSY; if ((openMode & O_RDWR) != 0 && (openMode & O_WRONLY) != 0) @@ -2811,34 +2831,7 @@ get_new_fd(int type, struct fs_mount* mount, struct vnode* vnode, descriptor->u.mount = mount; descriptor->cookie = cookie; - switch (type) { - // vnode types - case FDTYPE_FILE: - descriptor->ops = &sFileOps; - break; - case FDTYPE_DIR: - descriptor->ops = &sDirectoryOps; - break; - case FDTYPE_ATTR: - descriptor->ops = &sAttributeOps; - break; - case FDTYPE_ATTR_DIR: - descriptor->ops = &sAttributeDirectoryOps; - break; - - // mount types - case FDTYPE_INDEX_DIR: - descriptor->ops = &sIndexDirectoryOps; - break; - case FDTYPE_QUERY: - descriptor->ops = &sQueryOps; - break; - - default: - panic("get_new_fd() called with unknown type %d\n", type); - break; - } - descriptor->type = type; + descriptor->ops = ops; descriptor->open_mode = openMode; if (descriptor->ops->fd_seek != NULL) { @@ -3376,7 +3369,7 @@ dump_io_context(int argc, char** argv) kprintf(" max fds:\t%" B_PRIu32 "\n", context->table_size); if (context->num_used_fds) { - kprintf(" no. type %*s ref open mode pos %*s\n", + kprintf(" no. %*s ref open mode pos %*s\n", B_PRINTF_POINTER_WIDTH, "ops", B_PRINTF_POINTER_WIDTH, "cookie"); } @@ -3385,12 +3378,11 @@ dump_io_context(int argc, char** argv) if (fd == NULL) continue; - kprintf(" %3" B_PRIu32 ": %4" B_PRId32 " %p %3" B_PRId32 " %4" + kprintf(" %3" B_PRIu32 ": %p %3" B_PRId32 " %4" B_PRIu32 " %4" B_PRIx32 " %10" B_PRIdOFF " %p %s %p\n", i, - fd->type, fd->ops, fd->ref_count, fd->open_count, fd->open_mode, + fd->ops, fd->ref_count, fd->open_count, fd->open_mode, fd->pos, fd->cookie, - fd->type >= FDTYPE_INDEX && fd->type <= FDTYPE_QUERY - ? "mount" : "vnode", + (fd_vnode(fd) != NULL) ? "vnode" : "mount", fd->u.vnode); } @@ -5361,7 +5353,7 @@ open_vnode(struct vnode* vnode, int openMode, bool kernel) if (status != B_OK) return status; - int fd = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel); + int fd = get_new_fd(&sFileOps, NULL, vnode, cookie, openMode, kernel); if (fd < 0) { FS_CALL(vnode, close, cookie); FS_CALL(vnode, free_cookie, cookie); @@ -5476,7 +5468,7 @@ create_vnode(struct vnode* directory, const char* name, int openMode, return B_BAD_VALUE; } - int fd = get_new_fd(FDTYPE_FILE, NULL, vnode.Get(), cookie, openMode, kernel); + int fd = get_new_fd(&sFileOps, NULL, vnode.Get(), cookie, openMode, kernel); if (fd >= 0) { vnode.Detach(); return fd; @@ -5510,7 +5502,7 @@ open_dir_vnode(struct vnode* vnode, bool kernel) return status; // directory is opened, create a fd - status = get_new_fd(FDTYPE_DIR, NULL, vnode, cookie, O_CLOEXEC, kernel); + status = get_new_fd(&sDirectoryOps, NULL, vnode, cookie, O_CLOEXEC, kernel); if (status >= 0) return status; @@ -5537,7 +5529,7 @@ open_attr_dir_vnode(struct vnode* vnode, bool kernel) return status; // directory is opened, create a fd - status = get_new_fd(FDTYPE_ATTR_DIR, NULL, vnode, cookie, O_CLOEXEC, + status = get_new_fd(&sAttributeDirectoryOps, NULL, vnode, cookie, O_CLOEXEC, kernel); if (status >= 0) return status; @@ -5611,7 +5603,7 @@ file_open_entry_ref(dev_t mountID, ino_t directoryID, const char* name, int newFD = open_vnode(vnode.Get(), openMode, kernel); if (newFD >= 0) { - cache_node_opened(vnode.Get(), FDTYPE_FILE, vnode->cache, mountID, + cache_node_opened(vnode.Get(), vnode->cache, mountID, directoryID, vnode->id, name); // The vnode reference has been transferred to the FD @@ -5644,7 +5636,7 @@ file_open(int fd, char* path, int openMode, bool kernel) // open the vnode int newFD = open_vnode(vnode.Get(), openMode, kernel); if (newFD >= 0) { - cache_node_opened(vnode.Get(), FDTYPE_FILE, vnode->cache, + cache_node_opened(vnode.Get(), vnode->cache, vnode->device, parentID, vnode->id, NULL); // The vnode reference has been transferred to the FD @@ -5663,7 +5655,7 @@ file_close(struct file_descriptor* descriptor) FUNCTION(("file_close(descriptor = %p)\n", descriptor)); - cache_node_closed(vnode, FDTYPE_FILE, vnode->cache, vnode->device, + cache_node_closed(vnode, vnode->cache, vnode->device, vnode->id); if (HAS_FS_CALL(vnode, close)) { status = FS_CALL(vnode, close, descriptor->cookie); @@ -5942,7 +5934,7 @@ dir_open_entry_ref(dev_t mountID, ino_t parentID, const char* name, bool kernel) int newFD = open_dir_vnode(vnode.Get(), kernel); if (newFD >= 0) { - cache_node_opened(vnode.Get(), FDTYPE_DIR, vnode->cache, mountID, parentID, + cache_node_opened(vnode.Get(), vnode->cache, mountID, parentID, vnode->id, name); // The vnode reference has been transferred to the FD @@ -5970,7 +5962,7 @@ dir_open(int fd, char* path, bool kernel) // open the dir int newFD = open_dir_vnode(vnode.Get(), kernel); if (newFD >= 0) { - cache_node_opened(vnode.Get(), FDTYPE_DIR, vnode->cache, vnode->device, + cache_node_opened(vnode.Get(), vnode->cache, vnode->device, parentID, vnode->id, NULL); // The vnode reference has been transferred to the FD @@ -5988,7 +5980,7 @@ dir_close(struct file_descriptor* descriptor) FUNCTION(("dir_close(descriptor = %p)\n", descriptor)); - cache_node_closed(vnode, FDTYPE_DIR, vnode->cache, vnode->device, + cache_node_closed(vnode, vnode->cache, vnode->device, vnode->id); if (HAS_FS_CALL(vnode, close_dir)) return FS_CALL(vnode, close_dir, descriptor->cookie); @@ -6166,7 +6158,7 @@ common_fcntl(int fd, int op, size_t argument, bool kernel) status_t status = B_OK; if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) { - if (descriptor->type != FDTYPE_FILE) + if (descriptor->ops != &sFileOps) status = B_BAD_VALUE; else if (kernel) memcpy(&flock, (struct flock*)argument, sizeof(struct flock)); @@ -6780,7 +6772,7 @@ attr_create(int fd, char* path, const char* name, uint32 type, if (status != B_OK) return status; - fd = get_new_fd(FDTYPE_ATTR, NULL, vnode.Get(), cookie, openMode, kernel); + fd = get_new_fd(&sAttributeOps, NULL, vnode.Get(), cookie, openMode, kernel); if (fd >= 0) { vnode.Detach(); return fd; @@ -6822,7 +6814,7 @@ attr_open(int fd, char* path, const char* name, int openMode, bool kernel) return status; // now we only need a file descriptor for this attribute and we're done - fd = get_new_fd(FDTYPE_ATTR, NULL, vnode.Get(), cookie, openMode, kernel); + fd = get_new_fd(&sAttributeOps, NULL, vnode.Get(), cookie, openMode, kernel); if (fd >= 0) { vnode.Detach(); return fd; @@ -7050,7 +7042,7 @@ index_dir_open(dev_t mountID, bool kernel) // get fd for the index directory int fd; - fd = get_new_fd(FDTYPE_INDEX_DIR, mount, NULL, cookie, O_CLOEXEC, kernel); + fd = get_new_fd(&sIndexDirectoryOps, mount, NULL, cookie, O_CLOEXEC, kernel); if (fd >= 0) return fd; @@ -7253,7 +7245,7 @@ query_open(dev_t device, const char* query, uint32 flags, port_id port, // get fd for the index directory int fd; - fd = get_new_fd(FDTYPE_QUERY, mount, NULL, cookie, O_CLOEXEC, kernel); + fd = get_new_fd(&sQueryOps, mount, NULL, cookie, O_CLOEXEC, kernel); if (fd >= 0) return fd; @@ -9223,7 +9215,7 @@ _user_flock(int fd, int operation) if (!descriptor.IsSet()) return B_FILE_ERROR; - if (descriptor->type != FDTYPE_FILE) + if (descriptor->ops != &sFileOps) return B_BAD_VALUE; struct flock flock;