From fe303aec69078d753d95171e6265943a4aabdd9a Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 9 Sep 2023 00:30:43 -0300 Subject: [PATCH] devfs: maxseek --- kernel-src/fs/devfs.c | 9 ++++++++ kernel-src/include/kernel/devfs.h | 1 + kernel-src/include/kernel/vfs.h | 2 ++ kernel-src/sys/syscalls/seek.c | 35 ++++++++++++++++++++----------- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/kernel-src/fs/devfs.c b/kernel-src/fs/devfs.c index b26ad2e8..ba998ce8 100644 --- a/kernel-src/fs/devfs.c +++ b/kernel-src/fs/devfs.c @@ -201,6 +201,14 @@ int devfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *ret) { return devnode->devops->ioctl ? devnode->devops->ioctl(devnode->attr.rdevminor, request, arg, ret) : ENOTTY; } +int devfs_maxseek(vnode_t *node, size_t *max) { + devnode_t *devnode = (devnode_t *)node; + if (devnode->master) + devnode = devnode->master; + + return devnode->devops->maxseek ? devnode->devops->maxseek(devnode->attr.rdevminor, max) : ENOTTY; +} + int devfs_inactive(vnode_t *node) { VOP_LOCK(node); devnode_t *devnode = (devnode_t *)node; @@ -325,6 +333,7 @@ static vops_t vnops = { .getdents = devfs_getdents, .isatty = devfs_isatty, .ioctl = devfs_ioctl, + .maxseek = devfs_maxseek, .resize = devfs_enodev }; diff --git a/kernel-src/include/kernel/devfs.h b/kernel-src/include/kernel/devfs.h index 88c36e0d..f1c393f9 100644 --- a/kernel-src/include/kernel/devfs.h +++ b/kernel-src/include/kernel/devfs.h @@ -24,6 +24,7 @@ typedef struct { int (*munmap)(int minor, void *addr, uintmax_t offset, int flags); int (*isatty)(int minor); int (*ioctl)(int minor, unsigned long request, void *arg, int *result); + int (*maxseek)(int minor, size_t *max); } devops_t; typedef struct devnode_t { diff --git a/kernel-src/include/kernel/vfs.h b/kernel-src/include/kernel/vfs.h index 0c65a0eb..15a75903 100644 --- a/kernel-src/include/kernel/vfs.h +++ b/kernel-src/include/kernel/vfs.h @@ -96,6 +96,7 @@ typedef struct vops_t { int (*getdents)(vnode_t *node, dent_t *buffer, size_t count, uintmax_t offset, size_t *readcount); int (*isatty)(vnode_t *node); int (*ioctl)(vnode_t *node, unsigned long request, void *arg, int *result); + int (*maxseek)(vnode_t *node, size_t *max); int (*resize)(vnode_t *node, size_t newsize, cred_t *cred); } vops_t; @@ -142,6 +143,7 @@ typedef struct vops_t { #define VOP_POLL(v, d, p) (v)->ops->poll(v, d, p) #define VOP_ISATTY(v) ((v)->ops->isatty ? (v)->ops->isatty(v) : ENOTTY) #define VOP_IOCTL(v, r, a, rp) ((v)->ops->ioctl ? (v)->ops->ioctl(v, r, a, rp) : ENOTTY) +#define VOP_MAXSEEK(v, rp) ((v)->ops->maxseek ? (v)->ops->maxseek(v, rp) : ENOTTY) #define VOP_RESIZE(v, s, c) (v)->ops->resize(v, s, c) #define VOP_HOLD(v) __atomic_add_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST) #define VOP_RELEASE(v) {\ diff --git a/kernel-src/sys/syscalls/seek.c b/kernel-src/sys/syscalls/seek.c index 0cf6b737..71a5edef 100644 --- a/kernel-src/sys/syscalls/seek.c +++ b/kernel-src/sys/syscalls/seek.c @@ -9,7 +9,8 @@ syscallret_t syscall_seek(context_t *context, int fd, off_t offset, int whence) { syscallret_t ret = { - .ret = -1 + .ret = -1, + .errno = 0 }; if (whence > 2) { @@ -28,15 +29,30 @@ syscallret_t syscall_seek(context_t *context, int fd, off_t offset, int whence) goto cleanup; } - // TODO device check seek - + size_t size = -1; uintmax_t curroffset = file->offset; uintmax_t newoffset = 0; + // determine size + + if (file->vnode->type == V_TYPE_CHDEV) { + ret.errno = VOP_MAXSEEK(file->vnode, &size); + if (ret.errno) { + ret.errno = ESPIPE; + goto cleanup; + } + } else { + vattr_t attr; + ret.errno = VOP_GETATTR(file->vnode, &attr, &_cpu()->thread->proc->cred); + if (ret.errno) + goto cleanup; + size = attr.size; + } + switch (whence) { case SEEK_SET: - newoffset = offset; - break; + newoffset = offset; + break; case SEEK_CUR: newoffset = curroffset + offset; if (offset > 0 && newoffset < curroffset) { @@ -48,14 +64,9 @@ syscallret_t syscall_seek(context_t *context, int fd, off_t offset, int whence) goto cleanup; } break; - case SEEK_END: { - vattr_t attr; - ret.errno = VOP_GETATTR(file->vnode, &attr, &_cpu()->thread->proc->cred); - if (ret.errno) - goto cleanup; - newoffset = attr.size; + case SEEK_END: + newoffset = size; break; - } } file->offset = newoffset;