Nucleus
Barry System headers (remove libc dependency) 18495cf (3 years, 2 months ago)
#include <sys/errno.h>
#include <nucleus/lib.h>
#include <nucleus/vfs.h>
#include "ext2fs.h"
size_t ext2fs_read(File *file, char *buf, size_t size, off_t offset);
int ext2fs_readdir(File *file, struct dirent *dent, off_t index);
int ext2fs_open(File *file);
FileOps ext2fsFileOps = {
.read = ext2fs_read,
.readdir = ext2fs_readdir,
.open = ext2fs_open,
};
/* Read an ext2fs file */
size_t
ext2fs_read(File *file, char *buf, size_t size, off_t offset)
{
SuperBlock *sb = file->inode->super;
struct Ext2Inode inode;
uint16_t min, indent = offset % PAGE_SIZE;
size_t count = 0, i = offset / PAGE_SIZE;
uint32_t blk;
char ebuf[PAGE_SIZE];
ext2fs_read_inode(sb, file->inode->ino, &inode);
if (offset > inode.lsize)
return 0;
if (size + offset > inode.lsize)
size = inode.lsize - offset;
while (size) {
min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
blk = ext2fs_get_data_addr(sb, &inode, i);
ext2fs_read_block(sb, blk, ebuf);
memcpy(buf + count, ebuf + indent, min);
size -= min;
count += min;
indent = 0;
i++;
}
return count;
}
/* Read an ext2fs directory entry */
int
ext2fs_readdir(File *file, struct dirent *dent, off_t index)
{
char buf[PAGE_SIZE];
uint32_t block, blk = 0;
struct Ext2DirEntry *de;
struct Ext2Inode inode;
SuperBlock *sb = file->inode->super;
ext2fs_read_inode(sb, file->inode->ino, &inode);
for (blk = 0; blk < 0xFFFF; blk++) {
block = ext2fs_get_data_addr(sb, &inode, blk);
if (!block)
return -ENOENT;
ext2fs_read_block(sb, block, buf);
for (de = (struct Ext2DirEntry *) buf;
index && de < (struct Ext2DirEntry *) (buf + PAGE_SIZE);
de = (void *) de + de->size, index--);
if (de >= (struct Ext2DirEntry *) (buf + PAGE_SIZE))
return -ENOENT;
if (!index)
break;
}
if (!de->ino)
return -ENOENT;
dent->d_ino = de->ino;
dent->d_type = de->type;
dent->d_namelen = de->namelen + 1;
strncpy(dent->d_name, de->name, de->size);
return 0;
}
/* Open an ext2fs file */
int
ext2fs_open(File *file)
{
return 0;
}