From 0030a0b21b423c1b81df6674dff195bfe549bf3c Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 27 May 2024 23:05:57 -0300 Subject: [PATCH] vfs: make setattr take in which attributes to change --- kernel-src/fs/devfs.c | 24 +++++++++++++++--------- kernel-src/fs/ext2.c | 22 +++++++++++++++------- kernel-src/fs/pipefs.c | 20 +++++++++++++------- kernel-src/fs/sockfs.c | 20 +++++++++++++------- kernel-src/fs/tmpfs.c | 23 +++++++++++++++-------- kernel-src/include/kernel/vfs.h | 13 +++++++++++-- kernel-src/io/block/vioblk.c | 3 --- kernel-src/mm/vmmcache.c | 8 ++++++++ kernel-src/sys/syscalls/chmod.c | 2 +- kernel-src/sys/syscalls/fchownat.c | 3 +-- kernel-src/sys/syscalls/utime.c | 11 +---------- 11 files changed, 93 insertions(+), 56 deletions(-) diff --git a/kernel-src/fs/devfs.c b/kernel-src/fs/devfs.c index b018c82c..adcb9171 100644 --- a/kernel-src/fs/devfs.c +++ b/kernel-src/fs/devfs.c @@ -130,21 +130,27 @@ int devfs_getattr(vnode_t *node, vattr_t *attr, cred_t *cred) { return 0; } -int devfs_setattr(vnode_t *node, vattr_t *attr, cred_t *cred) { +int devfs_setattr(vnode_t *node, vattr_t *attr, int which, cred_t *cred) { devnode_t *devnode = (devnode_t *)node; if (devnode->physical && devnode->physical != node) { - int err = VOP_SETATTR(devnode->physical, attr, cred); + int err = VOP_SETATTR(devnode->physical, attr, which, cred); return err; } VOP_LOCK(node); - devnode->attr.gid = attr->gid; - devnode->attr.uid = attr->uid; - devnode->attr.mode = attr->mode; - devnode->attr.atime = attr->atime; - devnode->attr.mtime = attr->mtime; - devnode->attr.ctime = attr->ctime; + if (which & V_ATTR_GID) + devnode->attr.gid = attr->gid; + if (which & V_ATTR_UID) + devnode->attr.uid = attr->uid; + if (which & V_ATTR_MODE) + devnode->attr.mode = attr->mode; + if (which & V_ATTR_ATIME) + devnode->attr.atime = attr->atime; + if (which & V_ATTR_MTIME) + devnode->attr.mtime = attr->mtime; + if (which & V_ATTR_CTIME) + devnode->attr.ctime = attr->ctime; VOP_UNLOCK(node); return 0; } @@ -254,7 +260,7 @@ int devfs_create(vnode_t *parent, char *name, vattr_t *attr, int type, vnode_t * tmpattr.ctime = time; tmpattr.mtime = time; tmpattr.size = 0; - __assert(devfs_setattr(&node->vnode, &tmpattr, cred) == 0); + __assert(devfs_setattr(&node->vnode, &tmpattr, V_ATTR_ALL, cred) == 0); node->attr.nlinks = 1; node->attr.rdevmajor = tmpattr.rdevmajor; node->attr.rdevminor = tmpattr.rdevminor; diff --git a/kernel-src/fs/ext2.c b/kernel-src/fs/ext2.c index d9bc177e..e1a8d2f3 100644 --- a/kernel-src/fs/ext2.c +++ b/kernel-src/fs/ext2.c @@ -1063,14 +1063,22 @@ static int ext2_getattr(vnode_t *vnode, vattr_t *attr, cred_t *cred) { return 0; } -static int ext2_setattr(vnode_t *vnode, vattr_t *attr, cred_t *cred) { +static int ext2_setattr(vnode_t *vnode, vattr_t *attr, int which, cred_t *cred) { ext2node_t *node = (ext2node_t *)vnode; VOP_LOCK(vnode); - INODE_TYPEPERM_SETPERM(node->inode.typeperm, attr->mode); - node->inode.gid = attr->gid; - node->inode.uid = attr->uid; - + if (which & V_ATTR_MODE) + INODE_TYPEPERM_SETPERM(node->inode.typeperm, attr->mode); + if (which & V_ATTR_GID) + node->inode.gid = attr->gid; + if (which & V_ATTR_UID) + node->inode.uid = attr->uid; + if (which & V_ATTR_MTIME) + node->inode.mtime = attr->mtime.s; + if (which & V_ATTR_CTIME) + node->inode.ctime = attr->ctime.s; + if (which & V_ATTR_ATIME) + node->inode.atime = attr->atime.s; int e = writeinode((ext2fs_t *)vnode->vfs, &node->inode, node->id); VOP_UNLOCK(vnode); @@ -1283,8 +1291,8 @@ int ext2_write(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset, int if (err) goto cleanup; - node->inode.mtime = timekeeper_time().s; - ASSERT_UNCLEAN(fs, writeinode(fs, &node->inode, node->id) == 0); + //node->inode.mtime = timekeeper_time().s; + //ASSERT_UNCLEAN(fs, writeinode(fs, &node->inode, node->id) == 0); cleanup: VOP_UNLOCK(vnode); diff --git a/kernel-src/fs/pipefs.c b/kernel-src/fs/pipefs.c index 3cbacc8e..aa63da3d 100644 --- a/kernel-src/fs/pipefs.c +++ b/kernel-src/fs/pipefs.c @@ -211,16 +211,22 @@ int pipefs_getattr(vnode_t *node, vattr_t *attr, cred_t *cred) { return 0; } -int pipefs_setattr(vnode_t *node, vattr_t *attr, cred_t *cred) { +int pipefs_setattr(vnode_t *node, vattr_t *attr, int which, cred_t *cred) { pipenode_t *pipenode = (pipenode_t *)node; VOP_LOCK(node); - pipenode->attr.gid = attr->gid; - pipenode->attr.uid = attr->uid; - pipenode->attr.mode = attr->mode; - pipenode->attr.atime = attr->atime; - pipenode->attr.mtime = attr->mtime; - pipenode->attr.ctime = attr->ctime; + if (which & V_ATTR_GID) + pipenode->attr.gid = attr->gid; + if (which & V_ATTR_UID) + pipenode->attr.uid = attr->uid; + if (which & V_ATTR_MODE) + pipenode->attr.mode = attr->mode; + if (which & V_ATTR_ATIME) + pipenode->attr.atime = attr->atime; + if (which & V_ATTR_MTIME) + pipenode->attr.mtime = attr->mtime; + if (which & V_ATTR_CTIME) + pipenode->attr.ctime = attr->ctime; VOP_UNLOCK(node); return 0; } diff --git a/kernel-src/fs/sockfs.c b/kernel-src/fs/sockfs.c index a22633fa..6663f223 100644 --- a/kernel-src/fs/sockfs.c +++ b/kernel-src/fs/sockfs.c @@ -46,16 +46,22 @@ int sockfs_getattr(vnode_t *node, vattr_t *attr, cred_t *cred) { return 0; } -int sockfs_setattr(vnode_t *node, vattr_t *attr, cred_t *cred) { +int sockfs_setattr(vnode_t *node, vattr_t *attr, int which, cred_t *cred) { socketnode_t *socketnode = (socketnode_t *)node; VOP_LOCK(node); - socketnode->attr.gid = attr->gid; - socketnode->attr.uid = attr->uid; - socketnode->attr.mode = attr->mode; - socketnode->attr.atime = attr->atime; - socketnode->attr.mtime = attr->mtime; - socketnode->attr.ctime = attr->ctime; + if (which & V_ATTR_GID) + socketnode->attr.gid = attr->gid; + if (which & V_ATTR_UID) + socketnode->attr.uid = attr->uid; + if (which & V_ATTR_MODE) + socketnode->attr.mode = attr->mode; + if (which & V_ATTR_ATIME) + socketnode->attr.atime = attr->atime; + if (which & V_ATTR_MTIME) + socketnode->attr.mtime = attr->mtime; + if (which & V_ATTR_CTIME) + socketnode->attr.ctime = attr->ctime; VOP_UNLOCK(node); return 0; diff --git a/kernel-src/fs/tmpfs.c b/kernel-src/fs/tmpfs.c index 99ce784c..4077c5cf 100644 --- a/kernel-src/fs/tmpfs.c +++ b/kernel-src/fs/tmpfs.c @@ -41,16 +41,23 @@ static int tmpfs_getattr(vnode_t *node, vattr_t *attr, cred_t *cred) { return 0; } -static int tmpfs_setattr(vnode_t *node, vattr_t *attr, cred_t *cred) { +static int tmpfs_setattr(vnode_t *node, vattr_t *attr, int which, cred_t *cred) { VOP_LOCK(node); tmpfsnode_t *tmpnode = (tmpfsnode_t *)node; - tmpnode->attr.gid = attr->gid; - tmpnode->attr.uid = attr->uid; - tmpnode->attr.mode = attr->mode; - tmpnode->attr.atime = attr->atime; - tmpnode->attr.mtime = attr->mtime; - tmpnode->attr.ctime = attr->ctime; + if (which & V_ATTR_GID) + tmpnode->attr.gid = attr->gid; + if (which & V_ATTR_UID) + tmpnode->attr.uid = attr->uid; + if (which & V_ATTR_MODE) + tmpnode->attr.mode = attr->mode; + if (which & V_ATTR_ATIME) + tmpnode->attr.atime = attr->atime; + if (which & V_ATTR_MTIME) + tmpnode->attr.mtime = attr->mtime; + if (which & V_ATTR_CTIME) + tmpnode->attr.ctime = attr->ctime; + VOP_UNLOCK(node); return 0; } @@ -105,7 +112,7 @@ static int tmpfs_create(vnode_t *parent, char *name, vattr_t *attr, int type, vn tmpattr.mtime = time; tmpattr.size = 0; tmpattr.type = type; - int error = tmpfs_setattr(node, &tmpattr, cred); + int error = tmpfs_setattr(node, &tmpattr, V_ATTR_ALL, cred); tmpnode->attr.nlinks = 1; if (error) { diff --git a/kernel-src/include/kernel/vfs.h b/kernel-src/include/kernel/vfs.h index a0daa853..db2fa950 100644 --- a/kernel-src/include/kernel/vfs.h +++ b/kernel-src/include/kernel/vfs.h @@ -14,6 +14,15 @@ typedef struct { gid_t gid; } cred_t; +#define V_ATTR_MODE 1 +#define V_ATTR_UID 2 +#define V_ATTR_GID 4 +#define V_ATTR_ATIME 8 +#define V_ATTR_MTIME 16 +#define V_ATTR_CTIME 32 + +#define V_ATTR_ALL (V_ATTR_MODE | V_ATTR_UID | V_ATTR_GID | V_ATTR_ATIME | V_ATTR_MTIME | V_ATTR_CTIME) + typedef struct { int type; mode_t mode; @@ -88,7 +97,7 @@ typedef struct vops_t { int (*lookup)(vnode_t *node, char *name, vnode_t **result, cred_t *cred); int (*create)(vnode_t *parent, char *name, vattr_t *attr, int type, vnode_t **result, cred_t *cred); int (*getattr)(vnode_t *node, vattr_t *attr, cred_t *cred); - int (*setattr)(vnode_t *node, vattr_t *attr, cred_t *cred); + int (*setattr)(vnode_t *node, vattr_t *attr, int attrs, cred_t *cred); int (*poll)(vnode_t *node, struct polldata *, int events); int (*access)(vnode_t *node, mode_t mode, cred_t *cred); int (*unlink)(vnode_t *node, char *name, cred_t *cred); @@ -141,7 +150,7 @@ typedef struct vops_t { #define VOP_LOOKUP(v, n, r, c) (v)->ops->lookup(v, n, r, c) #define VOP_CREATE(v, n, a, t, r, c) (v)->ops->create(v, n, a, t, r, c) #define VOP_GETATTR(v, a, c) (v)->ops->getattr(v, a, c) -#define VOP_SETATTR(v, a, c) (v)->ops->setattr(v, a, c) +#define VOP_SETATTR(v, a, w, c) (v)->ops->setattr(v, a, w, c) #define VOP_ACCESS(v, m, c) (v)->ops->access(v, m, c) #define VOP_UNLINK(v, n, c) (v)->ops->unlink(v, n, c) #define VOP_LINK(v, d, n, c) (v)->ops->link(v, d, n, c) diff --git a/kernel-src/io/block/vioblk.c b/kernel-src/io/block/vioblk.c index 44c7a7f5..880c7cff 100644 --- a/kernel-src/io/block/vioblk.c +++ b/kernel-src/io/block/vioblk.c @@ -64,9 +64,6 @@ static void vioblk_irq(isr_t *isr, context_t *context) { // driver and device are physical addresses static void vioblk_enqueue(vioblkdev_t *blkdev, void *driver, size_t driverlen, void *device, size_t devicelen) { - event_t event; - EVENT_INIT(&event); - bool intstatus = interrupt_set(false); semaphore_wait(&blkdev->queuesem, false); diff --git a/kernel-src/mm/vmmcache.c b/kernel-src/mm/vmmcache.c index e9ebe6f4..30155593 100644 --- a/kernel-src/mm/vmmcache.c +++ b/kernel-src/mm/vmmcache.c @@ -3,6 +3,7 @@ #include #include #include +#include #define TABLE_SIZE 4096 #define WRITER_TICK_SECONDS 15 @@ -361,9 +362,11 @@ int vmmcache_sync() { } int vmmcache_makedirty(page_t *page) { + bool madedirty = false; HOLD_LOCK(); if ((page->flags & (PAGE_FLAGS_DIRTY | PAGE_FLAGS_TRUNCATED)) == 0) { + madedirty = true; // page is neither dirty nor truncated, add to dirty list and hold the page and vnode page->flags |= PAGE_FLAGS_DIRTY; @@ -379,6 +382,11 @@ int vmmcache_makedirty(page_t *page) { } RELEASE_LOCK(); + if (madedirty) { + vattr_t attr; + attr.mtime = timekeeper_time(); + VOP_SETATTR(page->backing, &attr, V_ATTR_MTIME, NULL); + } return 0; } diff --git a/kernel-src/sys/syscalls/chmod.c b/kernel-src/sys/syscalls/chmod.c index 125130af..16a61c06 100644 --- a/kernel-src/sys/syscalls/chmod.c +++ b/kernel-src/sys/syscalls/chmod.c @@ -13,7 +13,7 @@ static int dochmod(vnode_t *node, mode_t mode) { attr.mode = UMASK(mode); - return VOP_SETATTR(node, &attr, cred); + return VOP_SETATTR(node, &attr, V_ATTR_MODE, cred); } syscallret_t syscall_fchmodat(context_t *, int dirfd, const char *upath, mode_t mode, int flags) { diff --git a/kernel-src/sys/syscalls/fchownat.c b/kernel-src/sys/syscalls/fchownat.c index a4776155..f4e7d23f 100644 --- a/kernel-src/sys/syscalls/fchownat.c +++ b/kernel-src/sys/syscalls/fchownat.c @@ -42,7 +42,6 @@ syscallret_t syscall_fchownat(context_t *, int fd, const char *upath, uid_t owne goto cleanup; } - // XXX race condition with chmod vattr_t attr; ret.errno = VOP_GETATTR(node, &attr, &_cpu()->thread->proc->cred); if (ret.errno) @@ -51,7 +50,7 @@ syscallret_t syscall_fchownat(context_t *, int fd, const char *upath, uid_t owne attr.uid = owner; attr.gid = group; - ret.errno = VOP_SETATTR(node, &attr, &_cpu()->thread->proc->cred); + ret.errno = VOP_SETATTR(node, &attr, V_ATTR_UID | V_ATTR_GID, &_cpu()->thread->proc->cred); ret.ret = ret.errno ? -1 : 0; cleanup: diff --git a/kernel-src/sys/syscalls/utime.c b/kernel-src/sys/syscalls/utime.c index 6ce92b0a..4f9cde38 100644 --- a/kernel-src/sys/syscalls/utime.c +++ b/kernel-src/sys/syscalls/utime.c @@ -3,18 +3,10 @@ #include syscallret_t syscall_utimensat(context_t *, int fd, char *upath, timespec_t uts[2], int flags) { - // TODO - // uts -> NULL -> current time - // upath -> NULL -> dirfd points to vnode syscallret_t ret = { .ret = -1 }; - if (flags != 0) { - ret.errno = EINVAL; - return ret; - } - timespec_t ts[2]; if (uts == NULL) ts[0] = ts[1] = timekeeper_time(); @@ -55,7 +47,6 @@ syscallret_t syscall_utimensat(context_t *, int fd, char *upath, timespec_t uts[ goto cleanup; } - // XXX race condition with other system calls vattr_t attr; ret.errno = VOP_GETATTR(node, &attr, &_cpu()->thread->proc->cred); if (ret.errno) @@ -64,7 +55,7 @@ syscallret_t syscall_utimensat(context_t *, int fd, char *upath, timespec_t uts[ attr.atime = ts[0]; attr.mtime = ts[1]; - ret.errno = VOP_SETATTR(node, &attr, &_cpu()->thread->proc->cred); + ret.errno = VOP_SETATTR(node, &attr, V_ATTR_ATIME | V_ATTR_MTIME, &_cpu()->thread->proc->cred); ret.ret = ret.errno ? -1 : 0; cleanup: