vfs: use iovec_iterator for all file read and write, add vfs_read_iovec and vfs_write_iovec

This commit is contained in:
Matheus
2024-09-21 16:56:43 -03:00
parent e8c2f1fbf3
commit f1ee575ed1
13 changed files with 167 additions and 85 deletions
+22 -24
View File
@@ -71,7 +71,7 @@ int devfs_close(vnode_t *node, int flags, cred_t *cred) {
return devnode->devops->close(devnode->attr.rdevminor, flags);
}
int devfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
int devfs_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;
@@ -85,19 +85,10 @@ int devfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int f
if (devnode->devops->read == NULL)
return ENODEV;
// TODO remove this once the whole fs uses iovec
iovec_iterator_t iovec_iterator;
iovec_t iovec = {
.addr = buffer,
.len = size
};
iovec_iterator_init(&iovec_iterator, &iovec, 1);
return devnode->devops->read(devnode->attr.rdevminor, &iovec_iterator, size, offset, flags, readc);
return devnode->devops->read(devnode->attr.rdevminor, iovec_iterator, size, offset, flags, readc);
}
int devfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
int devfs_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;
@@ -111,16 +102,7 @@ int devfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int
if (devnode->devops->write == NULL)
return ENODEV;
// TODO remove this once the whole fs uses iovec
iovec_iterator_t iovec_iterator;
iovec_t iovec = {
.addr = buffer,
.len = size
};
iovec_iterator_init(&iovec_iterator, &iovec, 1);
return devnode->devops->write(devnode->attr.rdevminor, &iovec_iterator, size, offset, flags, writec);
return devnode->devops->write(devnode->attr.rdevminor, iovec_iterator, size, offset, flags, writec);
}
int devfs_lookup(vnode_t *node, char *name, vnode_t **result, cred_t *cred) {
@@ -400,8 +382,16 @@ static int devfs_getdents(vnode_t *node, dent_t *buffer, size_t count, uintmax_t
static int devfs_getpage(vnode_t *node, uintmax_t offset, struct page_t *page) {
// only block devices will have this called
__assert(node->type == V_TYPE_BLKDEV);
iovec_t iovec = {
.addr = MAKE_HHDM(pmm_getpageaddress(page)),
.len = PAGE_SIZE
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
size_t readc;
int error = VOP_READ(node, MAKE_HHDM(pmm_getpageaddress(page)), PAGE_SIZE, offset, 0, &readc, NULL);
int error = VOP_READ(node, &iovec_iterator, PAGE_SIZE, offset, 0, &readc, NULL);
if (readc == 0)
return ENXIO;
@@ -411,8 +401,16 @@ static int devfs_getpage(vnode_t *node, uintmax_t offset, struct page_t *page) {
static int devfs_putpage(vnode_t *node, uintmax_t offset, struct page_t *page) {
// only block devices will have this called
__assert(node->type == V_TYPE_BLKDEV);
iovec_t iovec = {
.addr = MAKE_HHDM(pmm_getpageaddress(page)),
.len = PAGE_SIZE
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
size_t writec;
int error = VOP_WRITE(node, MAKE_HHDM(pmm_getpageaddress(page)), PAGE_SIZE, offset, 0, &writec, NULL);
int error = VOP_WRITE(node, &iovec_iterator, PAGE_SIZE, offset, 0, &writec, NULL);
__assert(writec != 0);
return error;
+45 -23
View File
@@ -749,12 +749,11 @@ static int resizeinode(ext2fs_t *fs, ext2node_t *node, size_t newsize) {
return 0;
}
static int rwblocks(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, uintmax_t index, bool write, bool cache) {
static int rwblocks_iovec(ext2fs_t *fs, ext2node_t *node, iovec_iterator_t *iovec_iterator, size_t count, uintmax_t index, bool write, bool cache) {
for (uintmax_t i = 0; i < count; ++i) {
size_t inodesize = INODE_SIZE(&node->inode);
__assert(index + i < ROUND_UP(inodesize, fs->blocksize) / fs->blocksize);
void *bufferp = (void *)((uintptr_t)buffer + i * fs->blocksize);
blockptr_t block;
int e = getinodeblock(fs, node, index + i, &block);
if (e)
@@ -775,14 +774,14 @@ static int rwblocks(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count,
block = newblock;
} else if (block == 0 && write == false) {
memset(bufferp, 0, fs->blocksize);
iovec_iterator_memset(iovec_iterator, 0, fs->blocksize);
continue;
}
size_t donecount;
e = write ?
vfs_write(fs->backing, bufferp, fs->blocksize, BLOCK_GETDISKOFFSET(fs, block), &donecount, cache ? 0 : V_FFLAGS_NOCACHE) :
vfs_read(fs->backing, bufferp, fs->blocksize, BLOCK_GETDISKOFFSET(fs, block), &donecount, cache ? 0 : V_FFLAGS_NOCACHE);
vfs_write_iovec(fs->backing, iovec_iterator, fs->blocksize, BLOCK_GETDISKOFFSET(fs, block), &donecount, cache ? 0 : V_FFLAGS_NOCACHE) :
vfs_read_iovec(fs->backing, iovec_iterator, fs->blocksize, BLOCK_GETDISKOFFSET(fs, block), &donecount, cache ? 0 : V_FFLAGS_NOCACHE);
if (e)
return e;
@@ -792,7 +791,7 @@ static int rwblocks(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count,
return 0;
}
static int rwblock(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, uintmax_t offset, uintmax_t index, bool write, bool cache) {
static int rwblock_iovec(ext2fs_t *fs, ext2node_t *node, iovec_iterator_t *iovec_iterator, size_t count, uintmax_t offset, uintmax_t index, bool write, bool cache) {
__assert(offset + count <= fs->blocksize);
size_t inodesize = INODE_SIZE(&node->inode);
__assert(index < ROUND_UP(inodesize, fs->blocksize) / fs->blocksize);
@@ -818,14 +817,14 @@ static int rwblock(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, u
block = newblock;
} else if (block == 0 && write == false) {
memset(buffer, 0, count);
iovec_iterator_memset(iovec_iterator, 0, count);
return 0;
}
size_t donecount;
e = write ?
vfs_write(fs->backing, buffer, count, BLOCK_GETDISKOFFSET(fs, block) + offset, &donecount, cache ? 0 : V_FFLAGS_NOCACHE) :
vfs_read(fs->backing, buffer, count, BLOCK_GETDISKOFFSET(fs, block) + offset, &donecount, cache ? 0 : V_FFLAGS_NOCACHE);
vfs_write_iovec(fs->backing, iovec_iterator, count, BLOCK_GETDISKOFFSET(fs, block) + offset, &donecount, cache ? 0 : V_FFLAGS_NOCACHE) :
vfs_read_iovec(fs->backing, iovec_iterator, count, BLOCK_GETDISKOFFSET(fs, block) + offset, &donecount, cache ? 0 : V_FFLAGS_NOCACHE);
if (e)
return e;
@@ -834,7 +833,7 @@ static int rwblock(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, u
return e;
}
static int rwbytes(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, uintmax_t offset, bool write, bool cache) {
static int rwbytes_iovec(ext2fs_t *fs, ext2node_t *node, iovec_iterator_t *iovec_iterator, size_t count, uintmax_t offset, bool write, bool cache) {
uintmax_t index = offset / fs->blocksize;
uintmax_t startoffset = offset % fs->blocksize;
@@ -842,11 +841,10 @@ static int rwbytes(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, u
if (startoffset) {
size_t blockremaining = fs->blocksize - startoffset;
size_t docount = min(blockremaining, count);
int e = rwblock(fs, node, buffer, docount, startoffset, index, write, cache);
int e = rwblock_iovec(fs, node, iovec_iterator, docount, startoffset, index, write, cache);
if (e)
return e;
buffer = (void *)((uintptr_t)buffer + docount);
count -= docount;
index += 1;
}
@@ -854,17 +852,28 @@ static int rwbytes(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, u
// r/w all middle blocks
size_t blocks = count / fs->blocksize;
if (blocks) {
int e = rwblocks(fs, node, buffer, blocks, index, write, cache);
int e = rwblocks_iovec(fs, node, iovec_iterator, blocks, index, write, cache);
if (e)
return e;
count -= blocks * fs->blocksize;
buffer = (void *)((uintptr_t)buffer + blocks * fs->blocksize);
index += blocks;
}
// r/w remaining block if there's any data left and return
return count ? rwblock(fs, node, buffer, count, 0, index, write, cache) : 0;
return count ? rwblock_iovec(fs, node, iovec_iterator, count, 0, index, write, cache) : 0;
}
static int rwbytes(ext2fs_t *fs, ext2node_t *node, void *buffer, size_t count, uintmax_t offset, bool write, bool cache) {
iovec_t iovec = {
.addr = buffer,
.len = count
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
return rwbytes_iovec(fs, node, &iovec_iterator, count, offset, write, cache);
}
#define BUFFER_MAP_FLAGS (ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_NOEXEC)
@@ -1317,9 +1326,7 @@ static int ext2_readlink(vnode_t *vnode, char **link, cred_t *cred) {
return err;
}
// this *should*, by the rules of the vnode ops, accept a user buffer. however, this will never be the case. all I/O will
// go through the page cache
static int ext2_read(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
static int ext2_read(vnode_t *vnode, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
if (vnode->type == V_TYPE_DIR)
return EISDIR;
@@ -1350,7 +1357,7 @@ static int ext2_read(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset
if (size == 0)
goto cleanup;
err = rwbytes(fs, node, buffer, size, offset, false, false);
err = rwbytes_iovec(fs, node, iovec_iterator, size, offset, false, false);
*readc = err ? -1 : size;
@@ -1360,7 +1367,7 @@ static int ext2_read(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset
// this *should*, by the rules of the vnode ops, accept a user buffer. however, this will never be the case. all I/O will
// go through the page cache
int ext2_write(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
int ext2_write(vnode_t *vnode, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
if (vnode->type == V_TYPE_DIR)
return EISDIR;
@@ -1386,7 +1393,7 @@ int ext2_write(vnode_t *vnode, void *buffer, size_t size, uintmax_t offset, int
size = min(endoffset, inodesize) - offset;
}
err = rwbytes(fs, node, buffer, size, offset, true, false);
err = rwbytes(fs, node, iovec_iterator, size, offset, true, false);
*writec = err ? -1 : size;
if (err)
goto cleanup;
@@ -1695,7 +1702,15 @@ static int ext2_getpage(vnode_t *node, uintmax_t offset, struct page_t *page) {
__assert(node->type == V_TYPE_REGULAR);
size_t readc = PAGE_SIZE;
void *addr = MAKE_HHDM(pmm_getpageaddress(page));
int error = VOP_READ(node, addr, PAGE_SIZE, offset, 0, &readc, NULL);
iovec_t iovec = {
.addr = addr,
.len = PAGE_SIZE
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
int error = VOP_READ(node, &iovec_iterator, PAGE_SIZE, offset, 0, &readc, NULL);
if (readc == 0)
return ENXIO;
else if (readc != PAGE_SIZE)
@@ -1708,7 +1723,14 @@ static int ext2_putpage(vnode_t *node, uintmax_t offset, struct page_t *page) {
// only regular files get cached
__assert(node->type == V_TYPE_REGULAR);
size_t writec;
int error = VOP_WRITE(node, MAKE_HHDM(pmm_getpageaddress(page)), PAGE_SIZE, offset, 0, &writec, NULL);
iovec_t iovec = {
.addr = MAKE_HHDM(pmm_getpageaddress(page)),
.len = PAGE_SIZE
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
int error = VOP_WRITE(node, &iovec_iterator, PAGE_SIZE, offset, 0, &writec, NULL);
// its possible that writec is zero here. the condition where this is possible is when
// the file is truncated after the check in the page sync function but before it actually is
+7 -8
View File
@@ -130,8 +130,7 @@ static int internalpoll(vnode_t *node, polldata_t *data, int events) {
return revents;
}
// buffer can possibly be a user address
int pipefs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
int pipefs_read(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
pipenode_t *pipenode = (pipenode_t *)node;
INTERNAL_LOCK(node);
@@ -171,7 +170,7 @@ int pipefs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int
INTERNAL_LOCK(node);
}
*readc = ringbuffer_read(&pipenode->data, buffer, size);
*readc = iovec_iterator_read_from_ringbuffer(iovec_iterator, &pipenode->data, size);
if (*readc == RINGBUFFER_USER_COPY_FAILED)
error = EFAULT;
@@ -184,7 +183,7 @@ int pipefs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int
return error;
}
static int writetopipe(pipenode_t *pipenode, void *buffer, size_t size, size_t *writec) {
static int writetopipe(pipenode_t *pipenode, iovec_iterator_t *iovec_iterator, size_t size, size_t *writec) {
if (pipenode->readers == 0) {
if (current_thread()->proc)
signal_signalproc(current_thread()->proc, SIGPIPE);
@@ -192,7 +191,7 @@ static int writetopipe(pipenode_t *pipenode, void *buffer, size_t size, size_t *
return EPIPE;
}
*writec = ringbuffer_write(&pipenode->data, buffer, size);
*writec = iovec_iterator_write_to_ringbuffer(iovec_iterator, &pipenode->data, size);
if (*writec == RINGBUFFER_USER_COPY_FAILED)
return EFAULT;
@@ -201,7 +200,7 @@ static int writetopipe(pipenode_t *pipenode, void *buffer, size_t size, size_t *
return 0;
}
int pipefs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
int pipefs_write(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
pipenode_t *pipenode = (pipenode_t *)node;
INTERNAL_LOCK(node);
@@ -247,7 +246,7 @@ int pipefs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int
if (nonblock == false && atomic == false && freebytes) {
size_t tmp;
size_t writecount = min(freebytes, size - case3written);
error = writetopipe(pipenode, (void *)((uintptr_t)buffer + case3written), writecount, &tmp);
error = writetopipe(pipenode, iovec_iterator, writecount, &tmp);
if (error)
goto leave;
@@ -290,7 +289,7 @@ int pipefs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int
INTERNAL_LOCK(node);
}
error = writetopipe(pipenode, buffer, size, writec);
error = writetopipe(pipenode, iovec_iterator, size, writec);
leave:
INTERNAL_UNLOCK(node);
+32 -4
View File
@@ -24,14 +24,42 @@ int sockfs_close(vnode_t *node, int flags, cred_t *cred) {
return ENOSYS; // not needed
}
int sockfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
int sockfs_read(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *bytes_read, cred_t *cred) {
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
return socket_read(socket, buffer, size, flags, readc);
sockdesc_t desc = {
.addr = NULL,
.iovec_iterator = iovec_iterator,
.count = size,
.flags = flags,
.donecount = 0,
.ctrl = NULL,
.ctrllen = 0
};
int e = socket->ops->recv(socket, &desc);
*bytes_read = desc.donecount;
return e;
}
int sockfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
int sockfs_write(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *bytes_written, cred_t *cred) {
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
return socket_write(socket, buffer, size, flags, writec);
sockdesc_t desc = {
.addr = NULL,
.iovec_iterator = iovec_iterator,
.count = size,
.flags = flags,
.donecount = 0,
.ctrl = NULL,
.ctrllen = 0
};
int e = socket->ops->send(socket, &desc);
*bytes_written = desc.donecount;
return e;
}
int sockfs_poll(vnode_t *node, polldata_t *data, int events) {
+2 -2
View File
@@ -220,7 +220,7 @@ static int tmpfs_root(vfs_t *vfs, vnode_t **vnode) {
return 0;
}
static int tmpfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred) {
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;
@@ -230,7 +230,7 @@ static int tmpfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset
__assert(!"tmpfs_read is handled by the page cache");
}
static int tmpfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred) {
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;
+32 -9
View File
@@ -229,8 +229,7 @@ static int writenocache(vnode_t *node, page_t *page, uintmax_t pageoffset) {
return e;
}
// buffer can be a user address
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
int vfs_write_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *written, int flags) {
int err = 0;
if (vfs_iscacheable(node)) {
*written = 0;
@@ -292,7 +291,7 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
size_t writesize = min(PAGE_SIZE - startoffset, size);
void *address = MAKE_HHDM(pmm_getpageaddress(page));
err = USERCOPY_POSSIBLY_FROM_USER((void *)((uintptr_t)address + startoffset), buffer, writesize);
err = iovec_iterator_copy_to_buffer(iovec_iterator, (void *)((uintptr_t)address + startoffset), writesize);
if (err) {
pmm_release(FROM_HHDM(address));
goto leave;
@@ -320,7 +319,7 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
size_t writesize = min(PAGE_SIZE, size - *written);
void *address = MAKE_HHDM(pmm_getpageaddress(page));
err = USERCOPY_POSSIBLY_FROM_USER(address, (void *)((uintptr_t)buffer + *written), writesize);
err = iovec_iterator_copy_to_buffer(iovec_iterator, address, writesize);
if (err) {
pmm_release(FROM_HHDM(address));
goto leave;
@@ -343,14 +342,14 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
} else {
// special file, just write as its not being cached
VOP_LOCK(node);
err = VOP_WRITE(node, buffer, size, offset, flags, written, getcred());
err = VOP_WRITE(node, iovec_iterator, size, offset, flags, written, getcred());
VOP_UNLOCK(node);
}
return err;
}
int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *bytesread, int flags) {
int vfs_read_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *bytesread, int flags) {
int err = 0;
if (vfs_iscacheable(node)) {
*bytesread = 0;
@@ -406,7 +405,7 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
size_t readsize = min(PAGE_SIZE - startoffset, size);
void *address = MAKE_HHDM(pmm_getpageaddress(page));
err = USERCOPY_POSSIBLY_TO_USER(buffer, (void *)((uintptr_t)address + startoffset), readsize);
err = iovec_iterator_copy_from_buffer(iovec_iterator, (void *)((uintptr_t)address + startoffset), readsize);
if (err) {
pmm_release(FROM_HHDM(address));
goto leave;
@@ -433,7 +432,7 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
size_t readsize = min(PAGE_SIZE, size - *bytesread);
void *address = MAKE_HHDM(pmm_getpageaddress(page));
err = USERCOPY_POSSIBLY_TO_USER((void *)((uintptr_t)buffer + *bytesread), address, readsize);
err = iovec_iterator_copy_from_buffer(iovec_iterator, address, readsize);
if (err) {
pmm_release(FROM_HHDM(address));
goto leave;
@@ -451,12 +450,36 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
} else {
// special file, just read as size doesn't matter
VOP_LOCK(node);
err = VOP_READ(node, buffer, size, offset, flags, bytesread, getcred());
err = VOP_READ(node, iovec_iterator, size, offset, flags, bytesread, getcred());
VOP_UNLOCK(node);
}
return err;
}
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
iovec_t iovec = {
.addr = buffer,
.len = size
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
return vfs_write_iovec(node, &iovec_iterator, size, offset, written, flags);
}
int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *bytes_read, int flags) {
iovec_t iovec = {
.addr = buffer,
.len = size
};
iovec_iterator_t iovec_iterator;
iovec_iterator_init(&iovec_iterator, &iovec, 1);
return vfs_read_iovec(node, &iovec_iterator, size, offset, bytes_read, flags);
}
// if type is V_TYPE_LINK, a symlink is made
// in that case, destref is ignored, destpath is the link value and attr points to the attributes of the symlink
// if type is V_TYPE_REGULAR, a hardlink is made.
+9 -3
View File
@@ -39,7 +39,7 @@ typedef struct {
typedef struct {
sockaddr_t *addr;
iovec_iterator_t iovec_iterator;
iovec_iterator_t *iovec_iterator;
size_t count;
uintmax_t flags;
size_t donecount;
@@ -80,8 +80,11 @@ typedef struct {
#define SOCKFS_SOCKET_FROM_NODE(nodep) (((socketnode_t *)(nodep))->socket)
static inline int socket_read(socket_t *socket, void *buffer, size_t size, uintmax_t flags, size_t *bytes_read) {
iovec_iterator_t iovec_iterator;
sockdesc_t desc = {
.addr = NULL,
.iovec_iterator = &iovec_iterator,
.count = size,
.flags = flags,
.donecount = 0,
@@ -94,7 +97,7 @@ static inline int socket_read(socket_t *socket, void *buffer, size_t size, uintm
.len = size
};
iovec_iterator_init(&desc.iovec_iterator, &iovec, 1);
iovec_iterator_init(desc.iovec_iterator, &iovec, 1);
int e = socket->ops->recv(socket, &desc);
@@ -104,8 +107,11 @@ static inline int socket_read(socket_t *socket, void *buffer, size_t size, uintm
}
static inline int socket_write(socket_t *socket, void *buffer, size_t size, uintmax_t flags, size_t *bytes_written) {
iovec_iterator_t iovec_iterator;
sockdesc_t desc = {
.addr = NULL,
.iovec_iterator = &iovec_iterator,
.count = size,
.flags = flags,
.donecount = 0,
@@ -118,7 +124,7 @@ static inline int socket_write(socket_t *socket, void *buffer, size_t size, uint
.len = size
};
iovec_iterator_init(&desc.iovec_iterator, &iovec, 1);
iovec_iterator_init(desc.iovec_iterator, &iovec, 1);
int e = socket->ops->send(socket, &desc);
+4 -2
View File
@@ -118,8 +118,8 @@ struct polldata;
typedef struct vops_t {
int (*open)(vnode_t **node, int flags, cred_t *cred);
int (*close)(vnode_t *node, int flags, cred_t *cred);
int (*read)(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred);
int (*write)(vnode_t *node, void *buffer, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred);
int (*read)(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *readc, cred_t *cred);
int (*write)(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, int flags, size_t *writec, cred_t *cred);
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);
@@ -214,6 +214,8 @@ int vfs_register(vfsops_t *vfsops, char *name);
int vfs_open(vnode_t *ref, char *path, int flags, vnode_t **result);
int vfs_close(vnode_t *node, int flags);
int vfs_write_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *written, int flags);
int vfs_read_iovec(vnode_t *node, iovec_iterator_t *iovec_iterator, size_t size, uintmax_t offset, size_t *bytesread, int flags);
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags);
int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *bytesread, int flags);
int vfs_create(vnode_t *ref, char *path, vattr_t *attr, int type, vnode_t **node);
+3 -3
View File
@@ -363,7 +363,7 @@ static int localsock_send(socket_t *socket, sockdesc_t *sockdesc) {
goto leave;
}
sockdesc->donecount = iovec_iterator_write_to_ringbuffer(&sockdesc->iovec_iterator, &peer->ringbuffer, sockdesc->count);
sockdesc->donecount = iovec_iterator_write_to_ringbuffer(sockdesc->iovec_iterator, &peer->ringbuffer, sockdesc->count);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EFAULT;
goto leave;
@@ -467,13 +467,13 @@ static int localsock_recv(socket_t *socket, sockdesc_t *sockdesc) {
}
if (flags & SOCKET_RECV_FLAGS_PEEK) {
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(&sockdesc->iovec_iterator, &localsocket->ringbuffer, 0, recvcount);
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(sockdesc->iovec_iterator, &localsocket->ringbuffer, 0, recvcount);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EFAULT;
goto leave;
}
} else {
sockdesc->donecount = iovec_iterator_read_from_ringbuffer(&sockdesc->iovec_iterator, &localsocket->ringbuffer, recvcount);
sockdesc->donecount = iovec_iterator_read_from_ringbuffer(sockdesc->iovec_iterator, &localsocket->ringbuffer, recvcount);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EPIPE;
goto leave;
+3 -3
View File
@@ -1305,7 +1305,7 @@ static int tcp_send(socket_t *socket, sockdesc_t *sockdesc) {
size_t writesize = min(TCB_RINGBUFFER_SIZE - RINGBUFFER_DATACOUNT(&tcb->transmitbuffer), sockdesc->count);
__assert(writesize);
sockdesc->donecount = iovec_iterator_write_to_ringbuffer(&sockdesc->iovec_iterator, &tcb->transmitbuffer, writesize);
sockdesc->donecount = iovec_iterator_write_to_ringbuffer(sockdesc->iovec_iterator, &tcb->transmitbuffer, writesize);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EFAULT;
goto leave;
@@ -1386,13 +1386,13 @@ static int tcp_recv(socket_t *socket, sockdesc_t *sockdesc) {
size_t copycount = min(RINGBUFFER_DATACOUNT(&tcb->receivebuffer), sockdesc->count);
if (flags & SOCKET_RECV_FLAGS_PEEK) {
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(&sockdesc->iovec_iterator, &tcb->receivebuffer, 0, copycount);
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(sockdesc->iovec_iterator, &tcb->receivebuffer, 0, copycount);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EFAULT;
goto cleanup;
}
} else {
sockdesc->donecount = iovec_iterator_read_from_ringbuffer(&sockdesc->iovec_iterator, &tcb->receivebuffer, copycount);
sockdesc->donecount = iovec_iterator_read_from_ringbuffer(sockdesc->iovec_iterator, &tcb->receivebuffer, copycount);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
error = EFAULT;
goto cleanup;
+2 -2
View File
@@ -203,7 +203,7 @@ static int udp_send(socket_t *socket, sockdesc_t *sockdesc) {
socket->state = SOCKET_STATE_BOUND;
}
e = udp_sendpacket(&sockdesc->iovec_iterator, sockdesc->count, sockdesc->addr ? sockdesc->addr->ipv4addr.addr : udpsocket->peeraddress,
e = udp_sendpacket(sockdesc->iovec_iterator, sockdesc->count, sockdesc->addr ? sockdesc->addr->ipv4addr.addr : udpsocket->peeraddress,
udpsocket->port, sockdesc->addr ? sockdesc->addr->ipv4addr.port : udpsocket->peerport, udpsocket->socket.netdev);
sockdesc->donecount = sockdesc->count;
@@ -274,7 +274,7 @@ static int udp_recv(socket_t *socket, sockdesc_t *sockdesc) {
copycount = min(header.length, sockdesc->count);
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(&sockdesc->iovec_iterator, &udpsocket->ringbuffer, sizeof(header), copycount);
sockdesc->donecount = iovec_iterator_peek_from_ringbuffer(sockdesc->iovec_iterator, &udpsocket->ringbuffer, sizeof(header), copycount);
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
e = EFAULT;
goto cleanup;
+3 -1
View File
@@ -55,8 +55,10 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
if (flags & MSG_WAITALL)
recvflags |= SOCKET_RECV_FLAGS_WAITALL;
iovec_iterator_t iovec_iterator;
sockdesc_t desc = {
.addr = &sockaddr,
.iovec_iterator = &iovec_iterator,
.count = buffersize,
.flags = fileflagstovnodeflags(file->flags) | recvflags,
.donecount = 0,
@@ -65,7 +67,7 @@ syscallret_t syscall_recvmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
.ctrldone = 0
};
iovec_iterator_init(&desc.iovec_iterator, msghdr.iov, msghdr.iovcount);
iovec_iterator_init(desc.iovec_iterator, msghdr.iov, msghdr.iovcount);
ret.errno = socket->ops->recv(socket, &desc);
if (ret.errno)
+3 -1
View File
@@ -49,8 +49,10 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(file->vnode);
iovec_iterator_t iovec_iterator;
sockdesc_t desc = {
.addr = msghdr.addr ? &sockaddr : NULL,
.iovec_iterator = &iovec_iterator,
.count = buffersize,
.flags = fileflagstovnodeflags(file->flags) | ((flags & MSG_NOSIGNAL) ? SOCKET_SEND_FLAGS_NOSIGNAL : 0),
.donecount = 0,
@@ -59,7 +61,7 @@ syscallret_t syscall_sendmsg(context_t *, int fd, msghdr_t *umsghdr, int flags)
.ctrldone = 0
};
iovec_iterator_init(&desc.iovec_iterator, msghdr.iov, msghdr.iovcount);
iovec_iterator_init(desc.iovec_iterator, msghdr.iov, msghdr.iovcount);
ret.errno = socket->ops->send(socket, &desc);
ret.ret = ret.errno ? -1 : desc.donecount;