From b40a68f58157bbb6488cd4482e45ee7589df84d7 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Thu, 23 Dec 2004 22:00:00 -0500 Subject: [PATCH] Import backup from 2004-12-23 --- kernel/fs/ext2.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- kernel/fs/ext2.h | 4 +++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index 66af65e..b0c8754 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -87,12 +87,51 @@ int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, voi // TODO: get the block number, read it to block } -// block_index is a relative block number - the block number of the file -// this needs to be transformed into an absolute block number for the entire disk -u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode, u32_t block_index) +// transform open_inode->block (a relative block number) to an absolute block number for the filesystem +u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode) { // TODO: convert block_index to block number using open_inode fields - return 0; + if (open_inode->block < 12) + return open_inode->inode.i_block[open_inode->block]; + ext2_super_block_t *super = mount->super; + int pointersPerBlock = 256 << super->s_log_block_size; + if (open_inode->block_pointers && // there is a block pointers cache block allocated + (open_inode->block >= open_inode->block_pointers_start) && // and the block number is in it + (open_inode->block < (open_inode->block_pointers_start + pointersPerBlock))) + return open_inode->block_pointers[open_inode->block - open_inode->block_pointers_start]; + u32_t rel_block = open_inode->block - 12; + if (!open_inode->block_pointers) + open_inode->block_pointers = kmalloc(pointersPerBlock << 2); + if (rel_block < pointersPerBlock) // indirect block in i_block[12] + { + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[12], super), + 1 << super->s_log_block_size, open_inode->block_pointers); + open_inode->block_pointers_start = 12; + return open_inode->block_pointers[rel_block]; + } + rel_block -= pointersPerBlock; + if (rel_block < (pointersPerBlock * pointersPerBlock)) // double-indirect block in i_block[13] + { + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[13], super), + 1 << super->s_log_block_size, open_inode->block_pointers); + u32_t real_block = open_inode->block_pointers[rel_block / pointersPerBlock]; + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(real_block, super), + 1 << super->s_log_block_size, open_inode->block_pointers); + open_inode->block_pointers_start = 12 + pointersPerBlock + rel_block - (rel_block % pointersPerBlock); + return open_inode->block_pointers[rel_block % pointersPerBlock]; + } + rel_block -= pointersPerBlock * pointersPerBlock; + // TODO: triple-indirect block in i_block[14] + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(open_inode->inode.i_block[14], super), + 1 << super->s_log_block_size, open_inode->block_pointers); + u32_t block_1 = open_inode->block_pointers[rel_block / (pointersPerBlock * pointersPerBlock)]; + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(block_1, super), + 1 << super->s_log_block_size, open_inode->block_pointers); + u32_t block_2 = open_inode->block_pointers[rel_block / (pointersPerBlock * pointersPerBlock)]; + block_read(mount->major, mount->minor, ext2_FSToDiskBlock(block_1, super), + 1 << super->s_log_block_size, open_inode->block_pointers); + open_inode->block_pointers_start = 12 + pointersPerBlock + rel_block - (rel_block % pointersPerBlock); + return open_inode->block_pointers[rel_block % pointersPerBlock]; } int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode) diff --git a/kernel/fs/ext2.h b/kernel/fs/ext2.h index 50a11e7..e98d267 100644 --- a/kernel/fs/ext2.h +++ b/kernel/fs/ext2.h @@ -156,7 +156,9 @@ inline u32_t ext2_FSToDiskBlock(u32_t block, ext2_super_block_t *super); int ext2_stat(vfs_mount_t *mount, char *file, vfs_stat_t *stat); ext2_open_inode_t *ext2_open_inode(vfs_mount_t *mount, u32_t inode_number); int ext2_close_inode(vfs_mount_t *mount, ext2_open_inode_t *open_inode); -int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block_index); +int ext2_read_inode_block(vfs_mount_t *mount, ext2_open_inode_t *open_inode, void *block); +u32_t ext2_block_number(vfs_mount_t *mount, ext2_open_inode_t *open_inode); + void ext2_dump_root(vfs_mount_t *mount);