ext2: add lseek and L2 read support
This commit is contained in:
+25
-6
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user