ext2: add lseek and L2 read support

This commit is contained in:
Mark
2020-08-23 13:26:24 +03:00
parent b6e47c5154
commit 76ee873cb4
2 changed files with 55 additions and 7 deletions
+25 -6
View File
@@ -126,21 +126,40 @@ uint32_t ext2_inode_get_index(struct fs *ext2, struct ext2_inode *inode, uint32_
_assert(data);
uint32_t p = data->block_size / sizeof(uint32_t);
uint32_t a, b, c, d, e, f, g;
uint32_t ptrs[p];
if (index < EXT2_DIRECT_BLOCKS) {
return inode->direct_blocks[index];
} else if (index < EXT2_DIRECT_BLOCKS + p) {
}
// Fits in L1?
index -= EXT2_DIRECT_BLOCKS;
if (index < p) {
if (!inode->indirect_block_l1) {
panic("Read beyond end of file\n");
panic("Read beyond end of file (L1.1)\n");
}
_assert(ext2_read_block(ext2, ptrs, inode->indirect_block_l1) == 0);
return ptrs[index - EXT2_DIRECT_BLOCKS];
} else {
panic("TODO L2+\n");
return ptrs[index];
}
// Fits in L2?
index -= p;
if (index < p * p) {
uint32_t index_l1 = index / p;
uint32_t index_l0 = index % p;
if (!inode->indirect_block_l2) {
panic("Read beyond end of the file (L2.2)\n");
}
_assert(ext2_read_block(ext2, ptrs, inode->indirect_block_l2) == 0);
if (!ptrs[index_l1]) {
panic("Read beyond end of the file (L2.1)\n");
}
_assert(ext2_read_block(ext2, ptrs, ptrs[index_l1]) == 0);
return ptrs[index_l0];
}
panic("TODO: L3 support\n");
}
int ext2_inode_set_index(struct fs *ext2, struct ext2_inode *inode, uint32_t ino, uint32_t index, uint32_t value) {
+30 -1
View File
@@ -18,6 +18,7 @@
static int ext2_vnode_find(struct vnode *at, const char *name, struct vnode **res);
static ssize_t ext2_vnode_read(struct ofile *fd, void *buf, size_t count);
static ssize_t ext2_vnode_write(struct ofile *fd, const void *buf, size_t count);
static off_t ext2_vnode_lseek(struct ofile *fd, off_t pos, int whence);
static int ext2_vnode_open(struct ofile *fd, int opt);
static int ext2_vnode_opendir(struct ofile *fd);
static int ext2_vnode_chmod(struct vnode *vn, mode_t new_mode);
@@ -48,7 +49,8 @@ struct vnode_operations g_ext2_vnode_ops = {
.open = ext2_vnode_open,
.read = ext2_vnode_read,
.write = ext2_vnode_write,
.truncate = ext2_vnode_truncate
.truncate = ext2_vnode_truncate,
.lseek = ext2_vnode_lseek,
};
////
@@ -168,6 +170,33 @@ static ssize_t ext2_vnode_read(struct ofile *fd, void *buf, size_t count) {
return bread;
}
static off_t ext2_vnode_lseek(struct ofile *fd, off_t pos, int whence) {
off_t calc;
struct vnode *node = fd->file.vnode;
_assert(node);
struct ext2_inode *inode = node->fs_data;
_assert(inode);
switch (whence) {
case SEEK_SET:
calc = pos;
break;
case SEEK_CUR:
calc = pos + fd->file.pos;
break;
default:
panic("Invalid seek whence: %d\n", whence);
}
if (calc < 0 || calc >= inode->size_lower) {
return (off_t) -ESPIPE;
}
fd->file.pos = calc;
return fd->file.pos;
}
static int ext2_vnode_opendir(struct ofile *fd) {
_assert(fd && fd->file.vnode);
_assert(fd->file.vnode->type == VN_DIR);