#include <uk/config.h>
#include <uk/init.h>
+#include <uk/posix-fdtab-legacy.h>
+
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
if (unlikely(flags & ~EPOLL_CLOEXEC))
return -EINVAL;
- /* Reserve a file descriptor number */
- vfs_fd = vfscore_alloc_fd();
- if (unlikely(vfs_fd < 0)) {
- ret = -ENFILE;
- goto ERR_EXIT;
- }
-
/* Allocate file, vfs_file, and vnode */
ep = uk_malloc(a, sizeof(struct eventpoll));
if (unlikely(!ep)) {
}
/* Initialize data structures */
- vfs_file->fd = vfs_fd;
vfs_file->f_flags = 0;
vfs_file->f_count = 1;
vfs_file->f_data = ep;
eventpoll_init(ep, a);
/* Store within the vfs structure */
- ret = vfscore_install_fd(vfs_fd, vfs_file);
- if (unlikely(ret))
+ vfs_fd = uk_fdtab_legacy_open(vfs_file);
+ if (unlikely(vfs_fd < 0)) {
+ ret = vfs_fd;
goto ERR_VFS_INSTALL;
+ }
/* Only the dentry should hold a reference; release ours */
vput(vfs_vnode);
ERR_MALLOC_VFS_FILE:
uk_free(a, ep);
ERR_MALLOC_FILE:
- vfscore_put_fd(vfs_fd);
-ERR_EXIT:
UK_ASSERT(ret < 0);
return ret;
}
struct eventpoll *ep;
int ret;
- epf = vfscore_get_file(epfd);
+ epf = uk_fdtab_legacy_get(epfd);
if (unlikely(!epf)) {
ret = -EBADF;
goto EXIT;
}
- fp = vfscore_get_file(fd);
+ fp = uk_fdtab_legacy_get(fd);
if (unlikely(!fp)) {
ret = -EBADF;
goto ERR_PUT_EPF;
struct eventpoll *ep;
int ret;
- epf = vfscore_get_file(epfd);
+ epf = uk_fdtab_legacy_get(epfd);
if (unlikely(!epf)) {
ret = -EBADF;
goto EXIT;
#include <uk/config.h>
#include <uk/init.h>
+#include <uk/posix-fdtab-legacy.h>
+
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <inttypes.h>
if (unlikely(flags & ~(EFD_CLOEXEC | EFD_SEMAPHORE | EFD_NONBLOCK)))
return -EINVAL;
- /* Reserve a file descriptor number */
- vfs_fd = vfscore_alloc_fd();
- if (unlikely(vfs_fd < 0)) {
- ret = -ENFILE;
- goto ERR_EXIT;
- }
-
/* Allocate file, vfs_file, and vnode */
efd = uk_malloc(a, sizeof(struct eventfd));
if (unlikely(!efd)) {
}
/* Initialize data structures */
- vfs_file->fd = vfs_fd;
vfs_file->f_flags = UK_FREAD | UK_FWRITE;
vfs_file->f_count = 1;
vfs_file->f_data = efd;
eventfd_init(efd, initval, flags);
/* Store within the vfs structure */
- ret = vfscore_install_fd(vfs_fd, vfs_file);
- if (unlikely(ret))
+ vfs_fd = uk_fdtab_legacy_open(vfs_file);
+ if (unlikely(vfs_fd < 0)) {
+ ret = vfs_fd;
goto ERR_VFS_INSTALL;
+ }
/* Only the dentry should hold a reference; release ours */
vput(vfs_vnode);
ERR_MALLOC_VFS_FILE:
uk_free(a, efd);
ERR_MALLOC_FILE:
- vfscore_put_fd(vfs_fd);
-ERR_EXIT:
UK_ASSERT(ret < 0);
return ret;
}
CXXINCLUDES-$(CONFIG_LIBPOSIX_FDTAB) += -I$(LIBPOSIX_FDTAB_BASE)/include
LIBPOSIX_FDTAB_SRCS-y += $(LIBPOSIX_FDTAB_BASE)/fdtab.c
+
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDTAB) += close-1
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDTAB) += dup-1
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDTAB) += dup3-3
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBPOSIX_FDTAB) += dup2-2
#include <uk/assert.h>
#include <uk/config.h>
#include <uk/init.h>
+#include <uk/syscall.h>
#include <uk/posix-fdtab.h>
{
return uk_sys_dup_min(oldfd, 0, 0);
}
+
+/* Userspace Syscalls */
+
+UK_SYSCALL_R_DEFINE(int, close, int, fd)
+{
+ return uk_sys_close(fd);
+}
+
+UK_SYSCALL_R_DEFINE(int, dup, int, oldfd)
+{
+ return uk_sys_dup(oldfd);
+}
+
+UK_SYSCALL_R_DEFINE(int, dup2, int, oldfd, int, newfd)
+{
+ return uk_sys_dup2(oldfd, newfd);
+}
+
+UK_SYSCALL_R_DEFINE(int, dup3, int, oldfd, int, newfd, int, flags)
+{
+ return uk_sys_dup3(oldfd, newfd, flags);
+}
#include <string.h>
#include <stdlib.h>
+#include <uk/posix-fdtab-legacy.h>
+
static struct mount posix_socket_mount;
static uint64_t s_inode;
{
struct vfscore_file *fos;
- fos = vfscore_get_file(sock_fd);
+ fos = uk_fdtab_legacy_get(sock_fd);
if (unlikely(!fos))
return ERR2PTR(-ENOENT);
struct dentry *vfs_dentry;
struct vnode *vfs_vnode;
- /* Reserve file descriptor number */
- vfs_fd = vfscore_alloc_fd();
- if (unlikely(vfs_fd < 0)) {
- ret = -ENFILE;
- goto ERR_EXIT;
- }
-
/* Allocate file, vfs_file, and vnode */
sock = uk_calloc(d->allocator, 1, sizeof(*sock));
if (unlikely(!sock)) {
}
/* Put things together, and fill out necessary fields */
- vfs_file->fd = vfs_fd;
vfs_file->f_flags = UK_FWRITE | UK_FREAD;
vfs_file->f_count = 1;
vfs_file->f_data = sock;
sock->type = type;
/* Store within the vfs structure */
- ret = vfscore_install_fd(vfs_fd, vfs_file);
- if (unlikely(ret))
+ vfs_fd = uk_fdtab_legacy_open(vfs_file);
+ if (unlikely(vfs_fd < 0)) {
+ ret = vfs_fd;
goto ERR_VFS_INSTALL;
+ }
/* Only the dentry should hold a reference; release ours */
vput(vfs_vnode);
ERR_MALLOC_VFS_FILE:
uk_free(d->allocator, sock);
ERR_MALLOC_FILE:
- vfscore_put_fd(vfs_fd);
-ERR_EXIT:
UK_ASSERT(ret < 0);
return ret;
}
select LIBUKDEBUG
select LIBUKLOCK
select LIBPOSIX_TIME
+ select LIBPOSIX_FDTAB
+ select LIBPOSIX_FDTAB_LEGACY_SHIM
if LIBVFSCORE
config LIBVFSCORE_PIPE_SIZE_ORDER
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fstat-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fcntl-3
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += readlink-3
-UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += close-1
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += lseek-3
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += link-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += ftruncate-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fchdir-1
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += chmod-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fchmod-2
-UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += dup-1
-UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += dup3-3
-UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += dup2-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += pwritev-4
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += utime-2
UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += utimes-2
uk_syscall_e_write
uk_syscall_r_write
close
-uk_syscall_e_close
-uk_syscall_r_close
read
uk_syscall_e_read
uk_syscall_r_read
#include <uk/process.h>
#endif /* CONFIG_LIBPOSIX_PROCESS_CLONE */
-int init_stdio(void);
-
-struct fdtable {
- unsigned long bitmap[UK_BITS_TO_LONGS(FDTABLE_MAX_FILES)];
- uint32_t fd_start;
- struct vfscore_file *files[FDTABLE_MAX_FILES];
-};
-struct fdtable fdtable;
-
-int vfscore_alloc_fd(void)
-{
- unsigned long flags;
- int ret;
-
- flags = ukplat_lcpu_save_irqf();
- ret = uk_find_next_zero_bit(fdtable.bitmap, FDTABLE_MAX_FILES, 0);
-
- if (ret == FDTABLE_MAX_FILES) {
- ret = -ENFILE;
- goto exit;
- }
-
- uk_bitmap_set(fdtable.bitmap, ret, 1);
-
-exit:
- ukplat_lcpu_restore_irqf(flags);
- return ret;
-}
-
-int vfscore_reserve_fd(int fd)
-{
- unsigned long flags;
- int ret = 0;
-
- flags = ukplat_lcpu_save_irqf();
- if (uk_test_bit(fd, fdtable.bitmap)) {
- ret = -EBUSY;
- goto exit;
- }
-
- uk_bitmap_set(fdtable.bitmap, fd, 1);
-
-exit:
- ukplat_lcpu_restore_irqf(flags);
- return ret;
-}
-
-int vfscore_put_fd(int fd)
-{
- struct vfscore_file *fp;
- unsigned long flags;
-
- UK_ASSERT(fd < (int) FDTABLE_MAX_FILES);
-
- /* FIXME Currently it is not allowed to free std(in|out|err):
- * if (fd <= 2) return -EBUSY;
- *
- * However, returning -EBUSY in this case breaks dup2 with stdin, out,
- * err. Ignoring this should be fine as long as those are not fdrop-ed
- * twice, in which case the static fp would be freed, and here be
- * dragons.
- */
-
- flags = ukplat_lcpu_save_irqf();
- uk_bitmap_clear(fdtable.bitmap, fd, 1);
- fp = fdtable.files[fd];
- fdtable.files[fd] = NULL;
- ukplat_lcpu_restore_irqf(flags);
-
- /*
- * Since we can alloc a fd without assigning a
- * vfsfile we must protect against NULL ptr
- */
- if (fp)
- fdrop(fp);
-
- return 0;
-}
-
-int vfscore_install_fd(int fd, struct vfscore_file *file)
-{
- unsigned long flags;
- struct vfscore_file *orig;
-
- if ((fd >= (int) FDTABLE_MAX_FILES) || (!file))
- return -EBADF;
-
- fhold(file);
-
- file->fd = fd;
+#include <uk/posix-fdtab-legacy.h>
- flags = ukplat_lcpu_save_irqf();
- orig = fdtable.files[fd];
- fdtable.files[fd] = file;
- ukplat_lcpu_restore_irqf(flags);
-
- fdrop(file);
-
- if (orig)
- fdrop(orig);
+int init_stdio(void);
- return 0;
-}
struct vfscore_file *vfscore_get_file(int fd)
{
- unsigned long flags;
- struct vfscore_file *ret = NULL;
-
- UK_ASSERT(fd < (int) FDTABLE_MAX_FILES);
-
- flags = ukplat_lcpu_save_irqf();
- if (!uk_test_bit(fd, fdtable.bitmap))
- goto exit;
- ret = fdtable.files[fd];
- fhold(ret);
-
-exit:
- ukplat_lcpu_restore_irqf(flags);
- return ret;
+ return uk_fdtab_legacy_get(fd);
}
void vfscore_put_file(struct vfscore_file *file)
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;
+ return EBADF;
+ *out_fp = fp;
+ return 0;
}
int fdalloc(struct vfscore_file *fp, int *newfd)
{
- int fd, ret = 0;
-
- fd = vfscore_alloc_fd();
- if (fd < 0) {
- ret = fd;
- goto exit;
- }
-
- fhold(fp);
-
- ret = vfscore_install_fd(fd, fp);
- if (ret)
- fdrop(fp);
- else
- *newfd = fd;
-
-exit:
- return ret;
+ int r = uk_fdtab_legacy_open(fp);
+ if (r < 0)
+ return r;
+ *newfd = r;
+ return 0;
}
static int fdtable_init(void)
{
- memset(&fdtable, 0, sizeof(fdtable));
-
return init_stdio();
}
-uk_early_initcall_prio(fdtable_init, UK_PRIO_EARLIEST);
+uk_early_initcall(fdtable_init);
#if CONFIG_LIBPOSIX_PROCESS_CLONE
static int uk_posix_clone_files(const struct clone_args *cl_args,
#define FD_LOCK(fp) uk_mutex_lock(&(fp->f_lock))
#define FD_UNLOCK(fp) uk_mutex_unlock(&(fp->f_lock))
-int vfscore_alloc_fd(void);
-int vfscore_reserve_fd(int fd);
-int vfscore_put_fd(int fd);
-int vfscore_install_fd(int fd, struct vfscore_file *file);
struct vfscore_file *vfscore_get_file(int fd);
void vfscore_put_file(struct vfscore_file *file);
LFS64(creat);
-UK_TRACEPOINT(trace_vfs_close, "%d", int);
-UK_TRACEPOINT(trace_vfs_close_ret, "");
-UK_TRACEPOINT(trace_vfs_close_err, "%d", int);
-
-int fdclose(int fd)
-{
- struct vfscore_file *fp;
- int error;
-
- fp = vfscore_get_file(fd);
- if (!fp)
- return EBADF;
-
- error = vfscore_put_fd(fd);
- if (!error)
- fdrop(fp);
-
- return error;
-}
-
-UK_SYSCALL_R_DEFINE(int, close, int, fd)
-{
- int error;
-
- trace_vfs_close(fd);
- error = fdclose(fd);
- if (error)
- goto out_error;
-
- trace_vfs_close_ret();
- return 0;
-
- out_error:
- trace_vfs_close_err(error);
- return -error;
-}
UK_TRACEPOINT(trace_vfs_mknod, "\"%s\" 0%0o %#x", const char*, mode_t, dev_t);
UK_TRACEPOINT(trace_vfs_mknod_ret, "");
return ERR2PTR(-error);
}
-UK_TRACEPOINT(trace_vfs_dup, "%d", int);
-UK_TRACEPOINT(trace_vfs_dup_ret, "\"%s\"", int);
-UK_TRACEPOINT(trace_vfs_dup_err, "%d", int);
-/*
- * Duplicate a file descriptor
- */
-UK_SYSCALL_R_DEFINE(int, dup, int, oldfd)
-{
- struct vfscore_file *fp;
- int newfd;
- int error;
-
- trace_vfs_dup(oldfd);
- error = fget(oldfd, &fp);
- if (error)
- goto out_error;
-
- error = fdalloc(fp, &newfd);
- if (error)
- goto out_fdrop;
-
- fdrop(fp);
- trace_vfs_dup_ret(newfd);
- return newfd;
-
- out_fdrop:
- fdrop(fp);
-
- out_error:
- trace_vfs_dup_err(error);
- if (error > 0)
- return -error;
- return error;
-}
-
-UK_TRACEPOINT(trace_vfs_dup3, "%d %d %#x", int, int, int);
-UK_TRACEPOINT(trace_vfs_dup3_ret, "%d", int);
-UK_TRACEPOINT(trace_vfs_dup3_err, "%d", int);
-/*
- * Duplicate a file descriptor to a particular value.
- */
-UK_SYSCALL_R_DEFINE(int, dup3, int, oldfd, int, newfd, int, flags)
-{
- struct vfscore_file *fp;
- int error;
-
- trace_vfs_dup3(oldfd, newfd, flags);
- /*
- * Don't allow any argument but O_CLOEXEC. But we even ignore
- * that as we don't support exec() and thus don't care.
- */
- if ((flags & ~O_CLOEXEC) != 0) {
- error = EINVAL;
- goto out_error;
- }
-
- if (oldfd == newfd) {
- error = EINVAL;
- goto out_error;
- }
-
- error = fget(oldfd, &fp);
- if (error)
- goto out_error;
-
- /* BUG: The close and reserve operation must be atomic */
- error = uk_syscall_r_close(newfd);
- if (error && error != -EBADF)
- goto out_error_drop;
-
- error = vfscore_reserve_fd(newfd);
- if (error)
- goto out_error_drop;
-
- error = vfscore_install_fd(newfd, fp);
- if (error)
- goto out_error_drop;
-
- trace_vfs_dup3_ret(newfd);
- return newfd;
-
-out_error_drop:
- fdrop(fp);
-out_error:
- trace_vfs_dup3_err(error);
- return (error > 0) ? -error : error;
-}
-
-UK_SYSCALL_R_DEFINE(int, dup2, int, oldfd, int, newfd)
-{
- struct vfscore_file *fp;
- int error;
-
- if (unlikely(oldfd == newfd)) {
- error = fget(oldfd, &fp);
- if (unlikely(error))
- return -error;
-
- fdrop(fp);
- return newfd;
- }
-
- return uk_syscall_r_dup3(oldfd, newfd, 0);
-}
/*
* The file control system call.
#include <uk/syscall.h>
#include <uk/init.h>
+#include <uk/posix-fdtab-legacy.h>
+
/* We use the default size in Linux kernel */
#define PIPE_MAX_SIZE (1 << CONFIG_LIBVFSCORE_PIPE_SIZE_ORDER)
struct dentry *p_dentry;
struct vnode *p_vnode;
- /* Reserve file descriptor number */
- vfs_fd = vfscore_alloc_fd();
- if (vfs_fd < 0) {
- ret = -ENFILE;
- goto ERR_EXIT;
- }
-
/* Allocate file, dentry, and vnode */
vfs_file = calloc(1, sizeof(*vfs_file));
if (!vfs_file) {
}
/* Fill out necessary fields. */
- vfs_file->fd = vfs_fd;
vfs_file->f_flags = flags;
- vfs_file->f_count = 1;
+ vfs_file->f_count = 0;
vfs_file->f_data = pipe_file;
vfs_file->f_dentry = p_dentry;
vfs_file->f_vfs_flags = UK_VFSCORE_NOPOS;
p_vnode->v_type = VFIFO;
/* Assign the file descriptors to the corresponding vfs_file. */
- ret = vfscore_install_fd(vfs_fd, vfs_file);
- if (ret)
+ vfs_fd = uk_fdtab_legacy_open(vfs_file);
+ if (vfs_fd < 0) {
+ ret = vfs_fd;
goto ERR_VFS_INSTALL;
+ }
/* Only the dentry should hold a reference; release ours */
vrele(p_vnode);
ERR_ALLOC_VNODE:
free(vfs_file);
ERR_MALLOC_VFS_FILE:
- vfscore_put_fd(vfs_fd);
-ERR_EXIT:
UK_ASSERT(ret < 0);
return ret;
}
return ret;
ERR_W_FD:
- vfscore_put_fd(r_fd);
+ uk_syscall_r_close(r_fd);
ERR_VFS_INSTALL:
pipe_file_free(pipe_file);
ERR_EXIT:
#include <vfscore/mount.h>
#include <errno.h>
+#include <uk/posix-fdtab-legacy.h>
+
/*
* When the syscall_shim library is not part of the build, there is warning
* of implicit declaration of uk_syscall_r_dup2.
{
int fd;
- fd = vfscore_alloc_fd();
+ fd = uk_fdtab_legacy_open(&stdio_file);
if (fd != 0) {
- uk_pr_crit("failed to allocate fd for stdin (fd=0)\n");
+ uk_pr_crit("failed to allocate fd for stdin (fd=%d)\n", fd);
return (fd < 0) ? fd : -EBADF;
}
- vfscore_install_fd(0, &stdio_file);
fd = uk_syscall_r_dup3(0, 1, 0);
if (fd != 1) {