[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v4 13/22] lib/vfscore: introduce fget, fdrop, fdalloc
These functions are used in the imported code, which is not enabled yet. This required to expand functionality of vfscore_install_fd and friends with locking and reference counting. Signed-off-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx> --- lib/vfscore/fd.c | 71 ++++++++++++++++++++++++++++-- lib/vfscore/file.c | 22 ++++++++- lib/vfscore/include/vfscore/file.h | 9 +++- 3 files changed, 96 insertions(+), 6 deletions(-) diff --git a/lib/vfscore/fd.c b/lib/vfscore/fd.c index 6c220428..5abed969 100644 --- a/lib/vfscore/fd.c +++ b/lib/vfscore/fd.c @@ -74,20 +74,45 @@ exit: void vfscore_put_fd(int fd) { + struct vfscore_file *fp; + unsigned long flags; + UK_ASSERT(fd < (int) FDTABLE_MAX_FILES); /* Currently it is not allowed to free std(in|out|err) */ UK_ASSERT(fd > 2); - __uk_clear_bit(fd, &fdtable.bitmap); + flags = ukplat_lcpu_save_irqf(); + __uk_clear_bit(fd, &fdtable.bitmap);\ + fp = fdtable.files[fd]; + fdtable.files[fd] = NULL; + ukplat_lcpu_restore_irqf(flags); + + fdrop(fp); } -void vfscore_install_fd(int fd, struct vfscore_file *file) +int vfscore_install_fd(int fd, struct vfscore_file *file) { - UK_ASSERT(fd < (int) FDTABLE_MAX_FILES); - UK_ASSERT(file); + unsigned long flags; + struct vfscore_file *orig; + + if ((fd >= (int) FDTABLE_MAX_FILES) || (!file)) + return -EBADF; + + fhold(file); file->fd = fd; + + flags = ukplat_lcpu_save_irqf(); + orig = fdtable.files[fd]; fdtable.files[fd] = file; + ukplat_lcpu_restore_irqf(flags); + + fdrop(file); + + if (orig) + fdrop(orig); + + return 0; } struct vfscore_file *vfscore_get_file(int fd) @@ -101,12 +126,50 @@ struct vfscore_file *vfscore_get_file(int fd) if (!(fdtable.bitmap & ((uint64_t) 1 << fd))) goto exit; ret = fdtable.files[fd]; + fhold(ret); exit: ukplat_lcpu_restore_irqf(flags); return ret; } +int fget(int fd, struct vfscore_file **out_fp) +{ + int ret = 0; + struct vfscore_file *fp = vfscore_get_file(fd); + + if (!fp) + ret = EBADF; + else + *out_fp = fp; + + return ret; +} + +int fdalloc(struct vfscore_file *fp, int *newfd) +{ + int fd, ret = 0; + + fhold(fp); + + fd = vfscore_alloc_fd(); + if (fd < 0) { + ret = fd; + goto exit; + } + + ret = vfscore_install_fd(fd, fp); + if (ret) + fdrop(fp); + else + *newfd = fd; + +exit: + return ret; +} + + +/* TODO: move this constructor to main.c */ __constructor static void fdtable_init(void) { memset(&fdtable, 0, sizeof(fdtable)); diff --git a/lib/vfscore/file.c b/lib/vfscore/file.c index e7adf1a3..0f6dfa93 100644 --- a/lib/vfscore/file.c +++ b/lib/vfscore/file.c @@ -38,7 +38,7 @@ #include <uk/print.h> #include <vfscore/file.h> #include <uk/assert.h> - +#include <uk/arch/atomic.h> int close(int fd) { @@ -95,3 +95,23 @@ ssize_t read(int fd, void *buf, size_t count) return file->fops->read(file, buf, count); } + +/* TODO: remove stub */ +#define vfs_close(fp) (0) + +int fdrop(struct vfscore_file *fp) +{ + int ret = 0; + int prev = ukarch_dec(&fp->f_count); + + if (prev == 0) + UK_CRASH("Unbalanced fhold/fdrop"); + + if (prev == 1) + ret = vfs_close(fp); + return ret; +} +void fhold(struct vfscore_file *fp) +{ + ukarch_inc(&fp->f_count); +} diff --git a/lib/vfscore/include/vfscore/file.h b/lib/vfscore/include/vfscore/file.h index 3d8d667f..84eb35d7 100644 --- a/lib/vfscore/include/vfscore/file.h +++ b/lib/vfscore/include/vfscore/file.h @@ -53,14 +53,21 @@ struct vfscore_fops { struct vfscore_file { int fd; + int f_count; /* reference count */ const struct vfscore_fops *fops; }; int vfscore_alloc_fd(void); void vfscore_put_fd(int fd); -void vfscore_install_fd(int fd, struct vfscore_file *file); +int vfscore_install_fd(int fd, struct vfscore_file *file); struct vfscore_file *vfscore_get_file(int fd); +/* + * File descriptors reference count + */ +void fhold(struct vfscore_file* fp); +int fdrop(struct vfscore_file* fp); + #define FOF_OFFSET 0x0800 /* Use the offset in uio argument */ #ifdef __cplusplus -- 2.19.2 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |