Skip to content

Commit

Permalink
fs: add file_description_{read_to_end, write_all}
Browse files Browse the repository at this point in the history
  • Loading branch information
mosmeh committed Jun 29, 2024
1 parent 2da4fe0 commit 4dda26e
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 39 deletions.
14 changes: 8 additions & 6 deletions kernel/console/psf.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

static struct font* load_psf1(file_description* desc) {
struct psf1_header header;
if (file_description_read(desc, &header, sizeof(struct psf1_header)) !=
if (file_description_read_to_end(desc, &header,
sizeof(struct psf1_header)) !=
sizeof(struct psf1_header)) {
return ERR_PTR(-EINVAL);
}
Expand All @@ -31,7 +32,7 @@ static struct font* load_psf1(file_description* desc) {
kfree(font);
return ERR_PTR(-ENOMEM);
}
if ((size_t)file_description_read(desc, font->glyphs, buf_size) !=
if ((size_t)file_description_read_to_end(desc, font->glyphs, buf_size) !=
buf_size) {
kfree(font->glyphs);
kfree(font);
Expand All @@ -43,7 +44,7 @@ static struct font* load_psf1(file_description* desc) {
for (size_t i = 0; i < num_glyphs; ++i) {
for (;;) {
uint16_t uc;
if (file_description_read(desc, &uc, sizeof(uint16_t)) !=
if (file_description_read_to_end(desc, &uc, sizeof(uint16_t)) !=
sizeof(uint16_t)) {
kfree(font->glyphs);
kfree(font);
Expand All @@ -65,7 +66,8 @@ static struct font* load_psf1(file_description* desc) {

static struct font* load_psf2(file_description* desc) {
struct psf2_header header;
if (file_description_read(desc, &header, sizeof(struct psf2_header)) !=
if (file_description_read_to_end(desc, &header,
sizeof(struct psf2_header)) !=
sizeof(struct psf2_header))
return ERR_PTR(-EINVAL);
if (header.magic != PSF2_MAGIC || header.version != 0 ||
Expand All @@ -91,7 +93,7 @@ static struct font* load_psf2(file_description* desc) {
kfree(font);
return ERR_PTR(-ENOMEM);
}
if ((size_t)file_description_read(desc, font->glyphs, buf_size) !=
if ((size_t)file_description_read_to_end(desc, font->glyphs, buf_size) !=
buf_size) {
kfree(font->glyphs);
kfree(font);
Expand All @@ -103,7 +105,7 @@ static struct font* load_psf2(file_description* desc) {
for (size_t i = 0; i < header.numglyph; ++i) {
for (;;) {
uint8_t uc;
if (file_description_read(desc, &uc, sizeof(uint8_t)) !=
if (file_description_read_to_end(desc, &uc, sizeof(uint8_t)) !=
sizeof(uint8_t)) {
kfree(font->glyphs);
kfree(font);
Expand Down
3 changes: 2 additions & 1 deletion kernel/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ static int execve(const char* pathname, string_vec* argv, string_vec* envp) {
ret = -ENOMEM;
goto fail_exe;
}
ssize_t nread = file_description_read(desc, exe_buf, stat.st_size);

ssize_t nread = file_description_read_to_end(desc, exe_buf, stat.st_size);
file_description_close(desc);
desc = NULL;
if (IS_ERR(nread)) {
Expand Down
30 changes: 30 additions & 0 deletions kernel/fs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,21 @@ ssize_t file_description_read(file_description* desc, void* buffer,
return inode->fops->read(desc, buffer, count);
}

NODISCARD ssize_t file_description_read_to_end(file_description* desc,
void* buffer, size_t count) {
size_t cursor = 0;
while (cursor < count) {
ssize_t nread = file_description_read(
desc, (unsigned char*)buffer + cursor, count - cursor);
if (IS_ERR(nread))
return nread;
if (nread == 0)
break;
cursor += nread;
}
return cursor;
}

ssize_t file_description_write(file_description* desc, const void* buffer,
size_t count) {
struct inode* inode = desc->inode;
Expand All @@ -188,6 +203,21 @@ ssize_t file_description_write(file_description* desc, const void* buffer,
return inode->fops->write(desc, buffer, count);
}

ssize_t file_description_write_all(file_description* desc, const void* buffer,
size_t count) {
size_t cursor = 0;
while (cursor < count) {
ssize_t nwritten = file_description_write(
desc, (unsigned char*)buffer + cursor, count - cursor);
if (IS_ERR(nwritten))
return nwritten;
if (nwritten == 0)
break;
cursor += nwritten;
}
return cursor;
}

void* file_description_mmap(file_description* desc, size_t length, off_t offset,
int flags) {
struct inode* inode = desc->inode;
Expand Down
4 changes: 4 additions & 0 deletions kernel/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,12 @@ NODISCARD int inode_stat(struct inode*, struct stat* buf);
int file_description_close(file_description*);
NODISCARD ssize_t file_description_read(file_description*, void* buffer,
size_t count);
NODISCARD ssize_t file_description_read_to_end(file_description*, void* buffer,
size_t count);
NODISCARD ssize_t file_description_write(file_description*, const void* buffer,
size_t count);
NODISCARD ssize_t file_description_write_all(file_description*,
const void* buffer, size_t count);
NODISCARD void* file_description_mmap(file_description*, size_t length,
off_t offset, int flags);
NODISCARD int file_description_truncate(file_description*, off_t length);
Expand Down
10 changes: 4 additions & 6 deletions kernel/fs/initrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,10 @@ void initrd_populate_root_fs(uintptr_t phys_addr, size_t size) {
const unsigned char* file_content =
(const unsigned char*)(cursor + sizeof(struct cpio_odc_header) +
name_size);
for (size_t count = 0; count < file_size;) {
ssize_t nwritten = file_description_write(
desc, file_content + count, file_size - count);
ASSERT_OK(nwritten);
count += nwritten;
}
ssize_t nwritten =
file_description_write_all(desc, file_content, file_size);
ASSERT_OK(nwritten);
ASSERT((size_t)nwritten == file_size);

ASSERT_OK(file_description_close(desc));
}
Expand Down
16 changes: 4 additions & 12 deletions kernel/fs/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,11 @@ static struct path* follow_symlink(const struct path* parent,
return ERR_CAST(desc);

char target[SYMLINK_MAX];
size_t target_len = 0;
while (target_len < SYMLINK_MAX) {
ssize_t nread = file_description_read(desc, target + target_len,
SYMLINK_MAX - target_len);
if (IS_ERR(nread)) {
file_description_close(desc);
return ERR_PTR(nread);
}
if (nread == 0)
break;
target_len += nread;
}
ssize_t target_len =
file_description_read_to_end(desc, target, SYMLINK_MAX);
file_description_close(desc);
if (IS_ERR(target_len))
return ERR_PTR(target_len);

char* pathname = kmalloc(target_len + 1 + strlen(rest_pathname) + 1);
if (!pathname)
Expand Down
20 changes: 6 additions & 14 deletions kernel/syscall/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,14 @@ ssize_t sys_readlink(const char* user_pathname, char* user_buf, size_t bufsiz) {
bufsiz = MIN(bufsiz, SYMLINK_MAX);

char buf[SYMLINK_MAX];
size_t buf_len = 0;
while (buf_len < bufsiz) {
ssize_t nread = file_description_read(desc, buf + buf_len, bufsiz);
if (IS_ERR(nread)) {
file_description_close(desc);
return nread;
}
if (nread == 0)
break;
buf_len += nread;
}
ssize_t nread = file_description_read_to_end(desc, buf, bufsiz);
file_description_close(desc);
if (IS_ERR(nread))
return nread;

if (!copy_to_user(user_buf, buf, buf_len))
if (!copy_to_user(user_buf, buf, nread))
return -EFAULT;
return buf_len;
return nread;
}

ssize_t sys_write(int fd, const void* user_buf, size_t count) {
Expand Down Expand Up @@ -169,7 +161,7 @@ int sys_symlink(const char* user_target, const char* user_linkpath) {
file_description* desc = inode_open(inode, O_WRONLY, 0);
if (IS_ERR(desc))
return PTR_ERR(desc);
rc = file_description_write(desc, target, target_len);
rc = file_description_write_all(desc, target, target_len);

file_description_close(desc);
inode_unref(inode);
Expand Down

0 comments on commit 4dda26e

Please sign in to comment.