Fix readdir for ext2
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
#include "sys/types.h"
|
||||
#include "sys/dev.h"
|
||||
|
||||
struct vfs_node;
|
||||
|
||||
struct blkdev {
|
||||
void *dev_data;
|
||||
struct dev_entry *ent;
|
||||
@@ -15,6 +17,7 @@ struct blkdev {
|
||||
|
||||
ssize_t blk_read(struct blkdev *blk, void *buf, size_t off, size_t count);
|
||||
ssize_t blk_write(struct blkdev *blk, const void *buf, size_t off, size_t count);
|
||||
int blk_mount_auto(struct vfs_node *at, struct blkdev *blkdev, const char *opt);
|
||||
|
||||
struct blkdev *blk_by_name(const char *name);
|
||||
int blk_enumerate_partitions(struct blkdev *blk);
|
||||
|
||||
@@ -91,6 +91,7 @@ void vfs_node_free(struct vfs_node *n);
|
||||
*/
|
||||
struct vfs_node *vfs_node_create(const char *name, vnode_t *vn);
|
||||
|
||||
int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_name, const char *opt);
|
||||
/**
|
||||
* @brief Create a mountpoint in a filesystem tree so that
|
||||
* a "source" directory actually refers to the root
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "sys/debug.h"
|
||||
#include "sys/heap.h"
|
||||
#include "sys/spin.h"
|
||||
#include "sys/fs/ext2.h"
|
||||
#include "sys/fs/vfs.h"
|
||||
#include "sys/fcntl.h"
|
||||
#include "sys/errno.h"
|
||||
@@ -50,6 +51,7 @@ void init_func(void *arg) {
|
||||
struct ofile fd;
|
||||
struct stat st;
|
||||
int res;
|
||||
ext2_class_init();
|
||||
|
||||
if (root_blk) {
|
||||
if ((res = vfs_mount(&ioctx, "/", root_blk, "ustar", NULL)) != 0) {
|
||||
@@ -61,6 +63,16 @@ void init_func(void *arg) {
|
||||
panic("mount devfs: %s\n", kstrerror(res));
|
||||
}
|
||||
|
||||
// Try to mount /dev/sda1 at /mnt (don't panic on failure, though)
|
||||
struct blkdev *sda1_blk = blk_by_name("sda1");
|
||||
if (sda1_blk) {
|
||||
kinfo("Trying to mount /dev/sda1 -> /mnt\n");
|
||||
|
||||
if ((res = vfs_mount(&ioctx, "/mnt", sda1_blk, "auto", NULL)) != 0) {
|
||||
kwarn("/dev/sda1: %s\n", kstrerror(res));
|
||||
}
|
||||
}
|
||||
|
||||
if ((res = vfs_stat(&ioctx, "/init", &st)) != 0) {
|
||||
panic("/init: %s\n", kstrerror(res));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#include "sys/errno.h"
|
||||
#include "sys/string.h"
|
||||
#include "sys/heap.h"
|
||||
#include "sys/fs/vfs.h"
|
||||
|
||||
// Taken as-is from MBR partition types
|
||||
#define PART_HINT_LINUX 0x83
|
||||
|
||||
ssize_t blk_read(struct blkdev *blk, void *buf, size_t off, size_t lim) {
|
||||
_assert(blk);
|
||||
@@ -48,6 +52,16 @@ struct blk_part {
|
||||
uint64_t lba_size;
|
||||
};
|
||||
|
||||
int blk_mount_auto(struct vfs_node *at, struct blkdev *blk, const char *opt) {
|
||||
int res;
|
||||
|
||||
if ((res = vfs_mount_internal(at, blk, "ext2", opt)) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t blk_part_read(struct blkdev *dev, void *buf, size_t off, size_t count) {
|
||||
struct blk_part *part = (struct blk_part *) dev->dev_data;
|
||||
size_t part_size_bytes = part->lba_size * 512;
|
||||
|
||||
+40
-3
@@ -474,6 +474,7 @@ static int ext2_vnode_readdir(struct ofile *fd) {
|
||||
vnode_t *vn = fd->vnode;
|
||||
struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data;
|
||||
struct ext2_extsb *sb = vn->fs->fs_private;
|
||||
ssize_t res;
|
||||
|
||||
if (fd->pos >= inode->size_lower) {
|
||||
return -1;
|
||||
@@ -482,8 +483,8 @@ static int ext2_vnode_readdir(struct ofile *fd) {
|
||||
size_t block_number = fd->pos / sb->block_size;
|
||||
char block_buffer[sb->block_size];
|
||||
|
||||
if (ext2_read_inode_block(vn->fs, inode, block_number, block_buffer) < 0) {
|
||||
return -EIO;
|
||||
if ((res = ext2_read_inode_block(vn->fs, inode, block_number, block_buffer)) < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t block_offset = fd->pos % sb->block_size;
|
||||
@@ -501,7 +502,43 @@ static int ext2_vnode_readdir(struct ofile *fd) {
|
||||
strncpy(vfsdir->d_name, ext2dir->name, ext2dir->name_len);
|
||||
vfsdir->d_name[ext2dir->name_len] = 0;
|
||||
vfsdir->d_reclen = ext2dir->len;
|
||||
vfsdir->d_type = ext2dir->type_ind;
|
||||
if (sb->required_features & 2 /* Directory entries contain type field */) {
|
||||
switch (ext2dir->type_ind) {
|
||||
case 1:
|
||||
// Regular file
|
||||
vfsdir->d_type = DT_REG;
|
||||
break;
|
||||
case 2:
|
||||
// Directory
|
||||
vfsdir->d_type = DT_DIR;
|
||||
break;
|
||||
// XXX: Don't know if I should have ANY devices in ext2, we have devfs for that
|
||||
// kind of shit
|
||||
case 0:
|
||||
default:
|
||||
vfsdir->d_type = DT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Have to read each fucking inode to sort this mess out
|
||||
struct ext2_inode ent_inode_buf;
|
||||
|
||||
if ((res = ext2_read_inode(vn->fs, &ent_inode_buf, ext2dir->ino)) < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
switch (ent_inode_buf.type_perm & 0xF000) {
|
||||
case EXT2_TYPE_REG:
|
||||
vfsdir->d_type = DT_REG;
|
||||
break;
|
||||
case EXT2_TYPE_DIR:
|
||||
vfsdir->d_type = DT_DIR;
|
||||
break;
|
||||
default:
|
||||
vfsdir->d_type = DT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Not implemented, I guess
|
||||
vfsdir->d_off = 0;
|
||||
|
||||
|
||||
+7
-1
@@ -7,6 +7,7 @@
|
||||
#include "sys/errno.h"
|
||||
#include "sys/panic.h"
|
||||
#include "sys/heap.h"
|
||||
#include "sys/blk.h"
|
||||
#include "sys/chr.h"
|
||||
|
||||
// #include <stddef.h>
|
||||
@@ -393,10 +394,15 @@ void vfs_vnode_path(char *path, vnode_t *vn) {
|
||||
path[0] = 0;
|
||||
}
|
||||
|
||||
static int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_name, const char *opt) {
|
||||
int vfs_mount_internal(struct vfs_node *at, void *blkdev, const char *fs_name, const char *opt) {
|
||||
struct fs_class *fs_class;
|
||||
|
||||
if (!strcmp(fs_name, "auto")) {
|
||||
return blk_mount_auto(at, blkdev, opt);
|
||||
}
|
||||
|
||||
if ((fs_class = fs_class_by_name(fs_name)) == NULL) {
|
||||
kdebug("Unknown filesystem class: %s\n", fs_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ mkdirs:
|
||||
mkdir -p $(DIRS)
|
||||
|
||||
mkstage-etc:
|
||||
mkdir -p $(STAGE)/dev
|
||||
mkdir -p $(STAGE)/dev $(STAGE)/mnt
|
||||
cp -r etc $(STAGE)
|
||||
|
||||
# Application building
|
||||
|
||||
Reference in New Issue
Block a user