mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
vfs: root event signaling
This commit is contained in:
+59
-4
@@ -13,6 +13,7 @@
|
|||||||
#include <kernel/auth.h>
|
#include <kernel/auth.h>
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
#include <kernel/slab.h>
|
#include <kernel/slab.h>
|
||||||
|
#include <list.h>
|
||||||
|
|
||||||
#define PATHNAME_MAX 512
|
#define PATHNAME_MAX 512
|
||||||
#define MAXLINKDEPTH 64
|
#define MAXLINKDEPTH 64
|
||||||
@@ -43,6 +44,48 @@ int vfs_pollstub(vnode_t *node, struct polldata *, int events) {
|
|||||||
return revents;
|
return revents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
list_node_t list_node;
|
||||||
|
void (*fn)(void *);
|
||||||
|
void *ctx;
|
||||||
|
} root_event_waiter_t;
|
||||||
|
|
||||||
|
static list_t root_event_list;
|
||||||
|
static bool root_mounted;
|
||||||
|
static mutex_t root_event_mutex;
|
||||||
|
|
||||||
|
void vfs_root_event_signal(void) {
|
||||||
|
MUTEX_ACQUIRE(&root_event_mutex);
|
||||||
|
root_mounted = true;
|
||||||
|
MUTEX_RELEASE(&root_event_mutex);
|
||||||
|
|
||||||
|
list_for_each_safe (&root_event_list, node) {
|
||||||
|
root_event_waiter_t *rew = (root_event_waiter_t *)node;
|
||||||
|
rew->fn(rew->ctx);
|
||||||
|
free(rew);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int vfs_root_event_attach(void (*fn)(void *), void *ctx) {
|
||||||
|
root_event_waiter_t *rew = alloc(sizeof(root_event_waiter_t));
|
||||||
|
if (rew == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
MUTEX_ACQUIRE(&root_event_mutex);
|
||||||
|
if (root_mounted) {
|
||||||
|
MUTEX_RELEASE(&root_event_mutex);
|
||||||
|
free(rew);
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rew->fn = fn;
|
||||||
|
rew->ctx = ctx;
|
||||||
|
list_push_back(&root_event_list, &rew->list_node);
|
||||||
|
|
||||||
|
MUTEX_RELEASE(&root_event_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int noop() {
|
static int noop() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -71,6 +114,8 @@ void vfs_init() {
|
|||||||
vfsroot->ops = &vnops;
|
vfsroot->ops = &vnops;
|
||||||
advlock_cache = slab_newcache(sizeof(advlock_t), 0, advlock_ctor, NULL);
|
advlock_cache = slab_newcache(sizeof(advlock_t), 0, advlock_ctor, NULL);
|
||||||
__assert(advlock_cache);
|
__assert(advlock_cache);
|
||||||
|
list_init(&root_event_list);
|
||||||
|
MUTEX_INIT(&root_event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
INIT_ROUTINE_DEFINE(vfs, INIT_ROUTINE_FLAGS_NONE, vfs_init, abc);
|
INIT_ROUTINE_DEFINE(vfs, INIT_ROUTINE_FLAGS_NONE, vfs_init, abc);
|
||||||
@@ -850,7 +895,7 @@ static vnode_t *lowestnodeinmp(vnode_t *node) {
|
|||||||
// if flags & VFS_LOOKUP_NOLINK, the last component will not be dereferenced if its a symbolic link
|
// if flags & VFS_LOOKUP_NOLINK, the last component will not be dereferenced if its a symbolic link
|
||||||
// if flags & VFS_LOOKUP_INTERNAL, the first byte of flags will be the current count of symlinks transversed
|
// if flags & VFS_LOOKUP_INTERNAL, the first byte of flags will be the current count of symlinks transversed
|
||||||
// this is not an external flag and is meant to be called from inside the function itself
|
// this is not an external flag and is meant to be called from inside the function itself
|
||||||
int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int flags) {
|
int vfs_lookup(vnode_t **result, vnode_t *start, const char *path, char *lastcomp, int flags) {
|
||||||
if ((flags & VFS_LOOKUP_INTERNAL) && (flags & 0xff) > MAXLINKDEPTH)
|
if ((flags & VFS_LOOKUP_INTERNAL) && (flags & 0xff) > MAXLINKDEPTH)
|
||||||
return ELOOP;
|
return ELOOP;
|
||||||
|
|
||||||
@@ -883,6 +928,7 @@ int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int
|
|||||||
|
|
||||||
VOP_HOLD(current);
|
VOP_HOLD(current);
|
||||||
VOP_LOCK(current);
|
VOP_LOCK(current);
|
||||||
|
bool current_locked = true;
|
||||||
|
|
||||||
for (int i = 0; i < pathlen; ++i) {
|
for (int i = 0; i < pathlen; ++i) {
|
||||||
if (compbuffer[i] == '\0')
|
if (compbuffer[i] == '\0')
|
||||||
@@ -943,8 +989,11 @@ int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// if the current node is not the next one and VOP_LOOKUP didn't already by looking up "..", unlock it
|
// if the current node is not the next one and VOP_LOOKUP didn't already by looking up "..", unlock it
|
||||||
if (current != next && isdotdot == false)
|
if (current != next) {
|
||||||
VOP_UNLOCK(current);
|
if (isdotdot == false)
|
||||||
|
VOP_UNLOCK(current);
|
||||||
|
current_locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
vnode_t *r = next;
|
vnode_t *r = next;
|
||||||
error = highestnodeinmp(next, &r);
|
error = highestnodeinmp(next, &r);
|
||||||
@@ -959,6 +1008,8 @@ int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int
|
|||||||
if (r != next) {
|
if (r != next) {
|
||||||
VOP_HOLD(r);
|
VOP_HOLD(r);
|
||||||
VOP_UNLOCK(next);
|
VOP_UNLOCK(next);
|
||||||
|
if (current == next)
|
||||||
|
current_locked = false;
|
||||||
VOP_RELEASE(next);
|
VOP_RELEASE(next);
|
||||||
next = r;
|
next = r;
|
||||||
VOP_LOCK(next);
|
VOP_LOCK(next);
|
||||||
@@ -972,6 +1023,8 @@ int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int
|
|||||||
// next is already returned locked by VOP_LOOKUP
|
// next is already returned locked by VOP_LOOKUP
|
||||||
error = VOP_READLINK(next, &linkderef, getcred());
|
error = VOP_READLINK(next, &linkderef, getcred());
|
||||||
VOP_UNLOCK(next);
|
VOP_UNLOCK(next);
|
||||||
|
if (current == next)
|
||||||
|
current_locked = false;
|
||||||
if (error) {
|
if (error) {
|
||||||
VOP_RELEASE(next);
|
VOP_RELEASE(next);
|
||||||
break;
|
break;
|
||||||
@@ -1011,11 +1064,13 @@ int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int
|
|||||||
|
|
||||||
VOP_RELEASE(current);
|
VOP_RELEASE(current);
|
||||||
current = next;
|
current = next;
|
||||||
|
current_locked = true;
|
||||||
i += complen;
|
i += complen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
VOP_UNLOCK(current);
|
if (current_locked)
|
||||||
|
VOP_UNLOCK(current);
|
||||||
VOP_RELEASE(current);
|
VOP_RELEASE(current);
|
||||||
} else {
|
} else {
|
||||||
// result is already locked here
|
// result is already locked here
|
||||||
|
|||||||
@@ -260,6 +260,9 @@ void vfs_init();
|
|||||||
int vfs_mount(vnode_t *backing, vnode_t *pathref, char *path, char *name, void *data);
|
int vfs_mount(vnode_t *backing, vnode_t *pathref, char *path, char *name, void *data);
|
||||||
int vfs_register(vfsops_t *vfsops, char *name);
|
int vfs_register(vfsops_t *vfsops, char *name);
|
||||||
|
|
||||||
|
void vfs_root_event_signal(void);
|
||||||
|
int vfs_root_event_attach(void (*fn)(void *), void *ctx);
|
||||||
|
|
||||||
int vfs_open(vnode_t *ref, char *path, int flags, vnode_t **result);
|
int vfs_open(vnode_t *ref, char *path, int flags, vnode_t **result);
|
||||||
int vfs_close(vnode_t *node, int flags);
|
int vfs_close(vnode_t *node, int flags);
|
||||||
int vfs_write_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *written, int flags);
|
int vfs_write_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *written, int flags);
|
||||||
@@ -277,7 +280,7 @@ void vfs_inactive(vnode_t *node);
|
|||||||
#define VFS_LOOKUP_PARENT 0x20000000
|
#define VFS_LOOKUP_PARENT 0x20000000
|
||||||
#define VFS_LOOKUP_NOLINK 0x40000000
|
#define VFS_LOOKUP_NOLINK 0x40000000
|
||||||
#define VFS_LOOKUP_INTERNAL 0x80000000
|
#define VFS_LOOKUP_INTERNAL 0x80000000
|
||||||
int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int flags);
|
int vfs_lookup(vnode_t **result, vnode_t *start, const char *path, char *lastcomp, int flags);
|
||||||
|
|
||||||
static inline mode_t vfs_getposixtype(int type) {
|
static inline mode_t vfs_getposixtype(int type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|||||||
Reference in New Issue
Block a user