vfs: make setattr take in which attributes to change

This commit is contained in:
Matheus
2024-05-27 23:05:57 -03:00
parent 04d8431b32
commit 0030a0b21b
11 changed files with 93 additions and 56 deletions
+15 -9
View File
@@ -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;
+15 -7
View File
@@ -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);
+13 -7
View File
@@ -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;
}
+13 -7
View File
@@ -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;
+15 -8
View File
@@ -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) {
+11 -2
View File
@@ -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)
-3
View File
@@ -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);
+8
View File
@@ -3,6 +3,7 @@
#include <util.h>
#include <logging.h>
#include <kernel/poll.h>
#include <kernel/timekeeper.h>
#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;
}
+1 -1
View File
@@ -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) {
+1 -2
View File
@@ -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:
+1 -10
View File
@@ -3,18 +3,10 @@
#include <kernel/timekeeper.h>
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: