diff --git a/kernel-src/fs/devfs.c b/kernel-src/fs/devfs.c index 73e4efde..9ec86b36 100644 --- a/kernel-src/fs/devfs.c +++ b/kernel-src/fs/devfs.c @@ -322,7 +322,8 @@ static vops_t vnops = { .munmap = devfs_munmap, .getdents = devfs_getdents, .isatty = devfs_isatty, - .ioctl = devfs_ioctl + .ioctl = devfs_ioctl, + .resize = devfs_enodev }; static void ctor(scache_t *cache, void *obj) { diff --git a/kernel-src/fs/pipefs.c b/kernel-src/fs/pipefs.c index ec074b49..9e619cca 100644 --- a/kernel-src/fs/pipefs.c +++ b/kernel-src/fs/pipefs.c @@ -227,7 +227,8 @@ static vops_t vnops = { .inactive = pipefs_inactive, .mmap = pipefs_enodev, .munmap = pipefs_enodev, - .getdents = pipefs_enodev + .getdents = pipefs_enodev, + .resize = pipefs_enodev }; static void ctor(scache_t *cache, void *obj) { diff --git a/kernel-src/fs/tmpfs.c b/kernel-src/fs/tmpfs.c index c8879d35..d29b2288 100644 --- a/kernel-src/fs/tmpfs.c +++ b/kernel-src/fs/tmpfs.c @@ -32,7 +32,7 @@ static int tmpfs_mount(vfs_t **vfs, vnode_t *mountpoint, vnode_t *backing, void #define DATAMMUFLAGS (ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC) // expects to be called with node locked -static int tmpfs_resize(tmpfsnode_t *node, size_t size) { +static int resize(tmpfsnode_t *node, size_t size) { if (size == node->attr.size || node->vnode.type != V_TYPE_REGULAR) return 0; @@ -264,7 +264,7 @@ static int tmpfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offse VOP_LOCK(node); if (top > tmpnode->attr.size) { - int err = tmpfs_resize(tmpnode, top); + int err = resize(tmpnode, top); if (err) { VOP_UNLOCK(node); return err; @@ -468,6 +468,15 @@ static int tmpfs_inactive(vnode_t *node) { return 0; } +static int tmpfs_resize(vnode_t *node, size_t size, cred_t *) { + VOP_LOCK(node); + + int err = resize((tmpfsnode_t *)node, size); + + VOP_UNLOCK(node); + return err; +} + static vfsops_t vfsops = { .mount = tmpfs_mount, .root = tmpfs_root @@ -491,7 +500,8 @@ static vops_t vnops = { .inactive = tmpfs_inactive, .mmap = tmpfs_mmap, .munmap = tmpfs_munmap, - .getdents = tmpfs_getdents + .getdents = tmpfs_getdents, + .resize = tmpfs_resize }; static tmpfsnode_t *newnode(vfs_t *vfs, int type) { diff --git a/kernel-src/include/kernel/vfs.h b/kernel-src/include/kernel/vfs.h index be3b7367..bd0c390c 100644 --- a/kernel-src/include/kernel/vfs.h +++ b/kernel-src/include/kernel/vfs.h @@ -95,6 +95,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 (*resize)(vnode_t *node, size_t newsize, cred_t *cred); } vops_t; #define VFS_MOUNT(vfs, mp, b, d) (vfs)->ops->mount(vfs, mp, b, d) @@ -124,6 +125,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_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) {\ if (__atomic_sub_fetch(&(v)->refcount, 1, __ATOMIC_SEQ_CST) == 0) {\ diff --git a/kernel-src/sys/syscalls/open.c b/kernel-src/sys/syscalls/open.c index 07f99c7d..8b50b600 100644 --- a/kernel-src/sys/syscalls/open.c +++ b/kernel-src/sys/syscalls/open.c @@ -56,6 +56,12 @@ syscallret_t syscall_openat(context_t *context, int dirfd, const char *path, int if (ret.errno) goto cleanup; + if (vnode->type == V_TYPE_REGULAR && (flags & O_TRUNC)) { + ret.errno = VOP_RESIZE(vnode, 0, &_cpu()->thread->proc->cred); + if (ret.errno) + goto cleanup; + } + // node refcount is already increased by open newfile->vnode = vnode; newfile->flags = flags;