tmpfs: propery O_DIRECT semantics

This commit is contained in:
Matheus
2026-08-20 23:34:52 -03:00
parent d2253833b8
commit 27c8881679
+5 -47
View File
@@ -165,6 +165,9 @@ static int tmpfs_open(vnode_t **nodep, int flags, cred_t *cred) {
if (node->type == V_TYPE_SOCKET)
return ENXIO;
if (node->type == V_TYPE_REGULAR && (flags & V_FFLAGS_NOCACHE))
return EINVAL;
if (node->type == V_TYPE_CHDEV || node->type == V_TYPE_BLKDEV) {
vnode_t *devnode;
error = devfs_getnode(node, tmpnode->attr.rdevmajor, tmpnode->attr.rdevminor, &devnode);
@@ -224,63 +227,18 @@ static int tmpfs_root(vfs_t *vfs, vnode_t **vnode) {
return 0;
}
static int tmpfs_rw(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *done, bool write) {
*done = 0;
while (*done < size) {
uintmax_t current_offset = offset + *done;
uintmax_t page_offset = current_offset / PAGE_SIZE * PAGE_SIZE;
size_t page_start = current_offset % PAGE_SIZE;
size_t copy_size = min(PAGE_SIZE - page_start, size - *done);
page_t *page;
int error = mm_cache_get_page(node, page_offset, 0, &page);
if (error)
return error;
void *address = MAKE_HHDM(mm_get_page_address(page));
if (write)
error = iovec_iterator_copy_to_buffer(iovec_iterator, (void *)((uintptr_t)address + page_start), copy_size);
else
error = iovec_iterator_copy_from_buffer(iovec_iterator, (void *)((uintptr_t)address + page_start), copy_size);
mm_release_page(FROM_HHDM(address));
if (error)
return error;
*done += copy_size;
}
if (write && *done)
((tmpfsnode_t *)node)->attr.mtime = timekeeper_time();
return 0;
}
static int tmpfs_read(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
if (node->type == V_TYPE_DIR)
return EISDIR;
if (node->type != V_TYPE_REGULAR)
return EINVAL;
tmpfsnode_t *tmpfsnode = (tmpfsnode_t *)node;
if (offset >= tmpfsnode->attr.size) {
*readc = 0;
return 0;
}
size = min(size, tmpfsnode->attr.size - offset);
return tmpfs_rw(node, iovec_iterator, size, offset, readc, false);
return EINVAL;
}
static int tmpfs_write(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
if (node->type == V_TYPE_DIR)
return EISDIR;
if (node->type != V_TYPE_REGULAR)
return EINVAL;
if (size + offset < offset)
return EOVERFLOW;
__assert(size + offset <= ((tmpfsnode_t *)node)->attr.size);
return tmpfs_rw(node, iovec_iterator, size, offset, writec, true);
return EINVAL;
}
static int tmpfs_access(vnode_t *vnode, mode_t mode, cred_t *cred) {