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 <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
X512
2024-07-23 20:23:19 +00:00
committed by waddlesplash
parent e33e65b36e
commit 65a86bce72
8 changed files with 125 additions and 168 deletions
+4 -4
View File
@@ -26,9 +26,9 @@
struct cache_module_info { struct cache_module_info {
module_info 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); 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); ino_t vnodeID, int32 accessType);
void (*node_launched)(size_t argCount, char * const *args); void (*node_launched)(size_t argCount, char * const *args);
}; };
@@ -37,9 +37,9 @@ struct cache_module_info {
extern "C" { extern "C" {
#endif #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); 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); dev_t mountID, ino_t vnodeID);
extern void cache_node_launched(size_t argCount, char * const *args); 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); extern void cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size);
+1 -19
View File
@@ -15,10 +15,8 @@
extern "C" { extern "C" {
#endif #endif
struct event_queue;
struct file_descriptor; struct file_descriptor;
struct io_context; struct io_context;
struct net_socket;
struct selectsync; struct selectsync;
struct select_info; struct select_info;
@@ -47,15 +45,12 @@ struct fd_ops {
}; };
struct file_descriptor { struct file_descriptor {
int32 type; /* descriptor type */
int32 ref_count; int32 ref_count;
int32 open_count; int32 open_count;
struct fd_ops *ops; struct fd_ops *ops;
union { union {
struct vnode *vnode; struct vnode *vnode;
struct fs_mount *mount; struct fs_mount *mount;
struct net_socket *socket;
struct event_queue *queue;
} u; } u;
void *cookie; void *cookie;
int32 open_mode; 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 // additional open mode - kernel special
#define O_DISCONNECTED 0x80000000 #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 status_t deselect_fd(int32 fd, struct select_info *info, bool kernel);
extern bool fd_is_valid(int fd, bool kernel); extern bool fd_is_valid(int fd, bool kernel);
extern struct vnode *fd_vnode(struct file_descriptor *descriptor); 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 bool fd_close_on_exec(struct io_context *context, int fd);
extern void fd_set_close_on_exec(struct io_context *context, int fd, extern void fd_set_close_on_exec(struct io_context *context, int fd,
@@ -709,7 +709,7 @@ SessionGetter::Stop()
static void 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) ino_t node, const char *name, off_t size)
{ {
if (device < gBootDevice) { if (device < gBootDevice) {
@@ -744,7 +744,7 @@ node_opened(struct vnode *vnode, int32 fdType, dev_t device, ino_t parent,
static void 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) int32 accessType)
{ {
Session *session; Session *session;
+4 -4
View File
@@ -1053,7 +1053,7 @@ cache_prefetch(dev_t mountID, ino_t vnodeID, off_t offset, size_t size)
extern "C" void 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) dev_t mountID, ino_t parentID, ino_t vnodeID, const char* name)
{ {
if (sCacheModule == NULL || sCacheModule->node_opened == NULL) 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; size = cache->virtual_end;
} }
sCacheModule->node_opened(vnode, fdType, mountID, parentID, vnodeID, name, sCacheModule->node_opened(vnode, mountID, parentID, vnodeID, name,
size); size);
} }
extern "C" void 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) dev_t mountID, ino_t vnodeID)
{ {
if (sCacheModule == NULL || sCacheModule->node_closed == NULL) if (sCacheModule == NULL || sCacheModule->node_closed == NULL)
@@ -1083,7 +1083,7 @@ cache_node_closed(struct vnode* vnode, int32 fdType, VMCache* cache,
// ToDo: set accessType // ToDo: set accessType
} }
sCacheModule->node_closed(vnode, fdType, mountID, vnodeID, accessType); sCacheModule->node_closed(vnode, mountID, vnodeID, accessType);
} }
+24 -25
View File
@@ -549,7 +549,7 @@ EventQueue::_GetEvent(int32 object, uint16 type)
static status_t static status_t
event_queue_close(file_descriptor* descriptor) event_queue_close(file_descriptor* descriptor)
{ {
EventQueue* queue = (EventQueue*)descriptor->u.queue; EventQueue* queue = (EventQueue*)descriptor->cookie;
queue->Closed(); queue->Closed();
return B_OK; return B_OK;
} }
@@ -558,30 +558,11 @@ event_queue_close(file_descriptor* descriptor)
static void static void
event_queue_free(file_descriptor* descriptor) event_queue_free(file_descriptor* descriptor)
{ {
EventQueue* queue = (EventQueue*)descriptor->u.queue; EventQueue* queue = (EventQueue*)descriptor->cookie;
put_select_sync(queue); 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) \ #define GET_QUEUE_FD_OR_RETURN(fd, kernel, descriptor) \
do { \ do { \
status_t getError = get_queue_descriptor(fd, kernel, descriptor); \ 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 // #pragma mark - User syscalls
@@ -623,9 +623,8 @@ _user_event_queue_create(int openFlags)
if (descriptor == NULL) if (descriptor == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
descriptor->type = FDTYPE_EVENT_QUEUE;
descriptor->ops = &sEventQueueFDOps; descriptor->ops = &sEventQueueFDOps;
descriptor->u.queue = (struct event_queue*)queue; descriptor->cookie = (struct event_queue*)queue;
descriptor->open_mode = O_RDWR | openFlags; descriptor->open_mode = O_RDWR | openFlags;
io_context* context = get_current_io_context(false); 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); GET_QUEUE_FD_OR_RETURN(queue, false, descriptor);
FileDescriptorPutter _(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) if (user_memcpy(infos, userInfos, sizeof(event_wait_info) * numInfos) != B_OK)
return B_BAD_ADDRESS; 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); GET_QUEUE_FD_OR_RETURN(queue, false, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
EventQueue* eventQueue = (EventQueue*)descriptor->u.queue; EventQueue* eventQueue = (EventQueue*)descriptor->cookie;
ssize_t result = eventQueue->Wait(infos, numInfos, flags, timeout); ssize_t result = eventQueue->Wait(infos, numInfos, flags, timeout);
if (result < 0) if (result < 0)
+2 -17
View File
@@ -205,7 +205,7 @@ void
close_fd(struct io_context* context, struct file_descriptor* descriptor) close_fd(struct io_context* context, struct file_descriptor* descriptor)
{ {
// POSIX advisory locks need to be released when any file descriptor closes // 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); vfs_release_posix_lock(context, descriptor);
if (atomic_add(&descriptor->open_count, -1) == 1) { 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 static ssize_t
common_vector_io(int fd, off_t pos, const iovec* vecs, size_t count, bool write, bool kernel) 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. // for vnodes that have no cache, as the I/O hook bypasses the cache entirely.
struct vnode* vnode = descriptor->u.vnode; struct vnode* vnode = descriptor->u.vnode;
status_t status = B_OK; 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) { && vnode != NULL && vnode->cache == NULL && vnode->ops->io != NULL) {
BStackOrHeapArray<generic_io_vec, 8> iovecs(count); BStackOrHeapArray<generic_io_vec, 8> iovecs(count);
if (!iovecs.IsValid()) if (!iovecs.IsValid())
+45 -46
View File
@@ -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 // #pragma mark - socket file descriptor
@@ -219,7 +200,7 @@ static status_t
socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer, socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer,
size_t *_length) 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, 0);
*_length = bytesRead >= 0 ? bytesRead : 0; *_length = bytesRead >= 0 ? bytesRead : 0;
return bytesRead >= 0 ? B_OK : bytesRead; 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, socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer,
size_t *_length) 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, 0);
*_length = bytesWritten >= 0 ? bytesWritten : 0; *_length = bytesWritten >= 0 ? bytesWritten : 0;
return bytesWritten >= 0 ? B_OK : bytesWritten; return bytesWritten >= 0 ? B_OK : bytesWritten;
@@ -241,7 +222,7 @@ static status_t
socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer, socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer,
size_t length) 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 uint32 op = (flags & O_NONBLOCK) != 0
? B_SET_NONBLOCKING_IO : B_SET_BLOCKING_IO; ? 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, socket_select(struct file_descriptor *descriptor, uint8 event,
struct selectsync *sync) 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, socket_deselect(struct file_descriptor *descriptor, uint8 event,
struct selectsync *sync) 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) socket_read_stat(struct file_descriptor *descriptor, struct stat *st)
{ {
st->st_dev = 0; 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_mode = S_IFSOCK | 0666;
st->st_nlink = 1; st->st_nlink = 1;
st->st_uid = 0; st->st_uid = 0;
@@ -302,14 +283,14 @@ socket_read_stat(struct file_descriptor *descriptor, struct stat *st)
static status_t static status_t
socket_close(struct file_descriptor *descriptor) socket_close(struct file_descriptor *descriptor)
{ {
return sStackInterface->close(descriptor->u.socket); return sStackInterface->close((net_socket*)descriptor->cookie);
} }
static void static void
socket_free(struct file_descriptor *descriptor) socket_free(struct file_descriptor *descriptor)
{ {
sStackInterface->free(descriptor->u.socket); sStackInterface->free((net_socket*)descriptor->cookie);
put_stack_interface_module(); 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 static int
create_socket_fd(net_socket* socket, bool kernel) create_socket_fd(net_socket* socket, bool kernel)
{ {
@@ -349,9 +349,8 @@ create_socket_fd(net_socket* socket, bool kernel)
return B_NO_MEMORY; return B_NO_MEMORY;
// init it // init it
descriptor->type = FDTYPE_SOCKET;
descriptor->ops = &sSocketFDOps; descriptor->ops = &sSocketFDOps;
descriptor->u.socket = socket; descriptor->cookie = socket;
descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0); descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0);
// publish it // 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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->connect(descriptor->u.socket, address, return sStackInterface->connect((net_socket*)descriptor->cookie, address,
addressLength); addressLength);
} }
@@ -437,7 +436,7 @@ common_listen(int fd, int backlog, bool kernel)
GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); FileDescriptorPutter _(descriptor);
net_socket* acceptedSocket; net_socket* acceptedSocket;
status_t error = sStackInterface->accept(descriptor->u.socket, address, status_t error = sStackInterface->accept((net_socket*)descriptor->cookie, address,
_addressLength, &acceptedSocket); _addressLength, &acceptedSocket);
if (error != B_OK) if (error != B_OK)
return error; 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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->recvfrom(descriptor->u.socket, data, length, return sStackInterface->recvfrom((net_socket*)descriptor->cookie, data, length,
flags, address, _addressLength); 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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->sendto(descriptor->u.socket, data, length, flags, return sStackInterface->sendto((net_socket*)descriptor->cookie, data, length, flags,
address, addressLength); 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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->getsockopt(descriptor->u.socket, level, option, return sStackInterface->getsockopt((net_socket*)descriptor->cookie, level, option,
value, _length); 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); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->setsockopt(descriptor->u.socket, level, option, return sStackInterface->setsockopt((net_socket*)descriptor->cookie, level, option,
value, length); value, length);
} }
@@ -573,7 +572,7 @@ common_getpeername(int fd, struct sockaddr *address,
GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->getpeername(descriptor->u.socket, address, return sStackInterface->getpeername((net_socket*)descriptor->cookie, address,
_addressLength); _addressLength);
} }
@@ -586,7 +585,7 @@ common_getsockname(int fd, struct sockaddr *address,
GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->getsockname(descriptor->u.socket, address, return sStackInterface->getsockname((net_socket*)descriptor->cookie, address,
_addressLength); _addressLength);
} }
@@ -598,7 +597,7 @@ common_sockatmark(int fd, bool kernel)
GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor); GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
FileDescriptorPutter _(descriptor); FileDescriptorPutter _(descriptor);
return sStackInterface->sockatmark(descriptor->u.socket); return sStackInterface->sockatmark((net_socket*)descriptor->cookie);
} }
+43 -51
View File
@@ -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 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) void* cookie, int openMode, bool kernel)
{ {
struct file_descriptor* descriptor; 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 // If the vnode is locked, we don't allow creating a new file/directory
// file_descriptor for it // file_descriptor for it
if (vnode && vnode->mandatory_locked_by != NULL if (vnode && vnode->mandatory_locked_by != NULL
&& (type == FDTYPE_FILE || type == FDTYPE_DIR)) && (ops == &sFileOps || ops == &sDirectoryOps))
return B_BUSY; return B_BUSY;
if ((openMode & O_RDWR) != 0 && (openMode & O_WRONLY) != 0) 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->u.mount = mount;
descriptor->cookie = cookie; descriptor->cookie = cookie;
switch (type) { descriptor->ops = ops;
// 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->open_mode = openMode; descriptor->open_mode = openMode;
if (descriptor->ops->fd_seek != NULL) { 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); kprintf(" max fds:\t%" B_PRIu32 "\n", context->table_size);
if (context->num_used_fds) { 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"); B_PRINTF_POINTER_WIDTH, "ops", B_PRINTF_POINTER_WIDTH, "cookie");
} }
@@ -3385,12 +3378,11 @@ dump_io_context(int argc, char** argv)
if (fd == NULL) if (fd == NULL)
continue; 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, 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->pos, fd->cookie,
fd->type >= FDTYPE_INDEX && fd->type <= FDTYPE_QUERY (fd_vnode(fd) != NULL) ? "vnode" : "mount",
? "mount" : "vnode",
fd->u.vnode); fd->u.vnode);
} }
@@ -5361,7 +5353,7 @@ open_vnode(struct vnode* vnode, int openMode, bool kernel)
if (status != B_OK) if (status != B_OK)
return status; 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) { if (fd < 0) {
FS_CALL(vnode, close, cookie); FS_CALL(vnode, close, cookie);
FS_CALL(vnode, free_cookie, 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; 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) { if (fd >= 0) {
vnode.Detach(); vnode.Detach();
return fd; return fd;
@@ -5510,7 +5502,7 @@ open_dir_vnode(struct vnode* vnode, bool kernel)
return status; return status;
// directory is opened, create a fd // 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) if (status >= 0)
return status; return status;
@@ -5537,7 +5529,7 @@ open_attr_dir_vnode(struct vnode* vnode, bool kernel)
return status; return status;
// directory is opened, create a fd // 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); kernel);
if (status >= 0) if (status >= 0)
return status; 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); int newFD = open_vnode(vnode.Get(), openMode, kernel);
if (newFD >= 0) { 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); directoryID, vnode->id, name);
// The vnode reference has been transferred to the FD // 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 // open the vnode
int newFD = open_vnode(vnode.Get(), openMode, kernel); int newFD = open_vnode(vnode.Get(), openMode, kernel);
if (newFD >= 0) { 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); vnode->device, parentID, vnode->id, NULL);
// The vnode reference has been transferred to the FD // 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)); 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); vnode->id);
if (HAS_FS_CALL(vnode, close)) { if (HAS_FS_CALL(vnode, close)) {
status = FS_CALL(vnode, close, descriptor->cookie); 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); int newFD = open_dir_vnode(vnode.Get(), kernel);
if (newFD >= 0) { 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); vnode->id, name);
// The vnode reference has been transferred to the FD // The vnode reference has been transferred to the FD
@@ -5970,7 +5962,7 @@ dir_open(int fd, char* path, bool kernel)
// open the dir // open the dir
int newFD = open_dir_vnode(vnode.Get(), kernel); int newFD = open_dir_vnode(vnode.Get(), kernel);
if (newFD >= 0) { 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); parentID, vnode->id, NULL);
// The vnode reference has been transferred to the FD // 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)); 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); vnode->id);
if (HAS_FS_CALL(vnode, close_dir)) if (HAS_FS_CALL(vnode, close_dir))
return FS_CALL(vnode, close_dir, descriptor->cookie); 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; status_t status = B_OK;
if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) { if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) {
if (descriptor->type != FDTYPE_FILE) if (descriptor->ops != &sFileOps)
status = B_BAD_VALUE; status = B_BAD_VALUE;
else if (kernel) else if (kernel)
memcpy(&flock, (struct flock*)argument, sizeof(struct flock)); 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) if (status != B_OK)
return status; 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) { if (fd >= 0) {
vnode.Detach(); vnode.Detach();
return fd; return fd;
@@ -6822,7 +6814,7 @@ attr_open(int fd, char* path, const char* name, int openMode, bool kernel)
return status; return status;
// now we only need a file descriptor for this attribute and we're done // 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) { if (fd >= 0) {
vnode.Detach(); vnode.Detach();
return fd; return fd;
@@ -7050,7 +7042,7 @@ index_dir_open(dev_t mountID, bool kernel)
// get fd for the index directory // get fd for the index directory
int fd; 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) if (fd >= 0)
return fd; 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 // get fd for the index directory
int fd; 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) if (fd >= 0)
return fd; return fd;
@@ -9223,7 +9215,7 @@ _user_flock(int fd, int operation)
if (!descriptor.IsSet()) if (!descriptor.IsSet())
return B_FILE_ERROR; return B_FILE_ERROR;
if (descriptor->type != FDTYPE_FILE) if (descriptor->ops != &sFileOps)
return B_BAD_VALUE; return B_BAD_VALUE;
struct flock flock; struct flock flock;