diff options
Diffstat (limited to 'qemu/roms/openbios/fs/ext2/ext2_utils.c')
-rw-r--r-- | qemu/roms/openbios/fs/ext2/ext2_utils.c | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/qemu/roms/openbios/fs/ext2/ext2_utils.c b/qemu/roms/openbios/fs/ext2/ext2_utils.c deleted file mode 100644 index 64563c826..000000000 --- a/qemu/roms/openbios/fs/ext2/ext2_utils.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * - * (c) 2008-2009 Laurent Vivier <Laurent@lvivier.info> - * - * This file has been copied from EMILE, http://emile.sf.net - * - */ - -#include "libext2.h" -#include "ext2_utils.h" -#include "libopenbios/bindings.h" -#include "libc/diskio.h" -#include "libc/byteorder.h" - -int ext2_probe(int fd, long long offset) -{ - struct ext2_super_block *super; - - super = (struct ext2_super_block*)malloc(sizeof(struct ext2_super_block)); - seek_io(fd, 2 * 512 + offset); - read_io(fd, super, sizeof (*super)); - - if (__le16_to_cpu(super->s_magic) != EXT2_SUPER_MAGIC) { - free(super); - return 0; - } - - free(super); - return -1; -} - -void ext2_get_super(int fd, struct ext2_super_block *super) -{ - seek_io(fd, 2 * 512); - read_io(fd, super, sizeof (*super)); - - super->s_inodes_count = __le32_to_cpu(super->s_inodes_count); - super->s_blocks_count = __le32_to_cpu(super->s_blocks_count); - super->s_r_blocks_count = __le32_to_cpu(super->s_r_blocks_count); - super->s_free_blocks_count = __le32_to_cpu(super->s_free_blocks_count); - super->s_free_inodes_count = __le32_to_cpu(super->s_free_inodes_count); - super->s_first_data_block = __le32_to_cpu(super->s_first_data_block); - super->s_log_block_size = __le32_to_cpu(super->s_log_block_size); - super->s_log_frag_size = __le32_to_cpu(super->s_log_frag_size); - super->s_blocks_per_group = __le32_to_cpu(super->s_blocks_per_group); - super->s_frags_per_group = __le32_to_cpu(super->s_frags_per_group); - super->s_inodes_per_group = __le32_to_cpu(super->s_inodes_per_group); - super->s_mtime = __le32_to_cpu(super->s_mtime); - super->s_wtime = __le32_to_cpu(super->s_wtime); - super->s_mnt_count = __le16_to_cpu(super->s_mnt_count); - super->s_max_mnt_count = __le16_to_cpu(super->s_max_mnt_count); - super->s_magic = __le16_to_cpu(super->s_magic); - super->s_state = __le16_to_cpu(super->s_state); - super->s_errors = __le16_to_cpu(super->s_errors); - super->s_minor_rev_level = __le16_to_cpu(super->s_minor_rev_level); - super->s_lastcheck = __le32_to_cpu(super->s_lastcheck); - super->s_checkinterval = __le32_to_cpu(super->s_checkinterval); - super->s_creator_os = __le32_to_cpu(super->s_creator_os); - super->s_rev_level = __le32_to_cpu(super->s_rev_level); - super->s_def_resuid = __le16_to_cpu(super->s_def_resuid); - super->s_def_resgid = __le16_to_cpu(super->s_def_resgid); - super->s_first_ino = __le32_to_cpu(super->s_first_ino); - super->s_inode_size = __le16_to_cpu(super->s_inode_size); - super->s_block_group_nr = __le16_to_cpu(super->s_block_group_nr); - super->s_feature_compat = __le32_to_cpu(super->s_feature_compat); - super->s_feature_incompat = __le32_to_cpu(super->s_feature_incompat); - super->s_feature_ro_compat = __le32_to_cpu(super->s_feature_ro_compat); - super->s_algorithm_usage_bitmap = - __le32_to_cpu(super->s_algorithm_usage_bitmap); - super->s_journal_inum = __le32_to_cpu(super->s_journal_inum); - super->s_journal_dev = __le32_to_cpu(super->s_journal_dev); - super->s_last_orphan = __le32_to_cpu(super->s_last_orphan); - super->s_hash_seed[0] = __le32_to_cpu(super->s_hash_seed[0]); - super->s_hash_seed[1] = __le32_to_cpu(super->s_hash_seed[1]); - super->s_hash_seed[2] = __le32_to_cpu(super->s_hash_seed[2]); - super->s_hash_seed[3] = __le32_to_cpu(super->s_hash_seed[3]); - super->s_default_mount_opts = - __le32_to_cpu(super->s_default_mount_opts); - super->s_first_meta_bg = __le32_to_cpu(super->s_first_meta_bg); -} - -void ext2_read_block(ext2_VOLUME* volume, unsigned int fsblock) -{ - long long offset; - - if (fsblock == volume->current) - return; - - volume->current = fsblock; - offset = fsblock * EXT2_BLOCK_SIZE(volume->super); - - seek_io(volume->fd, offset); - read_io(volume->fd, volume->buffer, EXT2_BLOCK_SIZE(volume->super)); -} - -void ext2_get_group_desc(ext2_VOLUME* volume, - int group_id, struct ext2_group_desc *gdp) -{ - unsigned int block, offset; - struct ext2_group_desc *le_gdp; - - block = 1 + volume->super->s_first_data_block; - block += group_id / EXT2_DESC_PER_BLOCK(volume->super); - ext2_read_block(volume, block); - - offset = group_id % EXT2_DESC_PER_BLOCK(volume->super); - offset *= sizeof(*gdp); - - le_gdp = (struct ext2_group_desc *)(volume->buffer + offset); - - gdp->bg_block_bitmap = __le32_to_cpu(le_gdp->bg_block_bitmap); - gdp->bg_inode_bitmap = __le32_to_cpu(le_gdp->bg_inode_bitmap); - gdp->bg_inode_table = __le32_to_cpu(le_gdp->bg_inode_table); - gdp->bg_free_blocks_count = __le16_to_cpu(le_gdp->bg_free_blocks_count); - gdp->bg_free_inodes_count = __le16_to_cpu(le_gdp->bg_free_inodes_count); - gdp->bg_used_dirs_count = __le16_to_cpu(le_gdp->bg_used_dirs_count); -} - -int ext2_get_inode(ext2_VOLUME* volume, - unsigned int ino, struct ext2_inode *inode) -{ - struct ext2_group_desc desc; - unsigned int block; - unsigned int group_id; - unsigned int offset; - struct ext2_inode *le_inode; - int i; - - ino--; - - group_id = ino / EXT2_INODES_PER_GROUP(volume->super); - ext2_get_group_desc(volume, group_id, &desc); - - ino %= EXT2_INODES_PER_GROUP(volume->super); - - block = desc.bg_inode_table; - block += ino / (EXT2_BLOCK_SIZE(volume->super) / - EXT2_INODE_SIZE(volume->super)); - ext2_read_block(volume, block); - - offset = ino % (EXT2_BLOCK_SIZE(volume->super) / - EXT2_INODE_SIZE(volume->super)); - offset *= EXT2_INODE_SIZE(volume->super); - - le_inode = (struct ext2_inode *)(volume->buffer + offset); - - inode->i_mode = __le16_to_cpu(le_inode->i_mode); - inode->i_uid = __le16_to_cpu(le_inode->i_uid); - inode->i_size = __le32_to_cpu(le_inode->i_size); - inode->i_atime = __le32_to_cpu(le_inode->i_atime); - inode->i_ctime = __le32_to_cpu(le_inode->i_ctime); - inode->i_mtime = __le32_to_cpu(le_inode->i_mtime); - inode->i_dtime = __le32_to_cpu(le_inode->i_dtime); - inode->i_gid = __le16_to_cpu(le_inode->i_gid); - inode->i_links_count = __le16_to_cpu(le_inode->i_links_count); - inode->i_blocks = __le32_to_cpu(le_inode->i_blocks); - inode->i_flags = __le32_to_cpu(le_inode->i_flags); - if (S_ISLNK(inode->i_mode)) { - memcpy(inode->i_block, le_inode->i_block, EXT2_N_BLOCKS * 4); - } else { - for (i = 0; i < EXT2_N_BLOCKS; i++) - inode->i_block[i] = __le32_to_cpu(le_inode->i_block[i]); - } - inode->i_generation = __le32_to_cpu(le_inode->i_generation); - inode->i_file_acl = __le32_to_cpu(le_inode->i_file_acl); - inode->i_dir_acl = __le32_to_cpu(le_inode->i_dir_acl); - inode->i_faddr = __le32_to_cpu(le_inode->i_faddr); - inode->osd2.linux2.l_i_frag = le_inode->osd2.linux2.l_i_frag; - inode->osd2.linux2.l_i_fsize = le_inode->osd2.linux2.l_i_fsize; - inode->osd2.linux2.l_i_uid_high = - __le16_to_cpu(le_inode->osd2.linux2.l_i_uid_high); - inode->osd2.linux2.l_i_gid_high = - __le16_to_cpu(le_inode->osd2.linux2.l_i_gid_high); - return 0; -} - -unsigned int ext2_get_block_addr(ext2_VOLUME* volume, struct ext2_inode *inode, - unsigned int logical) -{ - unsigned int physical; - unsigned int addr_per_block; - - /* direct */ - - if (logical < EXT2_NDIR_BLOCKS) { - physical = inode->i_block[logical]; - return physical; - } - - /* indirect */ - - logical -= EXT2_NDIR_BLOCKS; - - addr_per_block = EXT2_ADDR_PER_BLOCK (volume->super); - if (logical < addr_per_block) { - ext2_read_block(volume, inode->i_block[EXT2_IND_BLOCK]); - physical = __le32_to_cpu(((unsigned int *)volume->buffer)[logical]); - return physical; - } - - /* double indirect */ - - logical -= addr_per_block; - - if (logical < addr_per_block * addr_per_block) { - ext2_read_block(volume, inode->i_block[EXT2_DIND_BLOCK]); - physical = __le32_to_cpu(((unsigned int *)volume->buffer) - [logical / addr_per_block]); - ext2_read_block(volume, physical); - physical = __le32_to_cpu(((unsigned int *)volume->buffer) - [logical % addr_per_block]); - return physical; - } - - /* triple indirect */ - - logical -= addr_per_block * addr_per_block; - ext2_read_block(volume, inode->i_block[EXT2_DIND_BLOCK]); - physical = __le32_to_cpu(((unsigned int *)volume->buffer) - [logical / (addr_per_block * addr_per_block)]); - ext2_read_block(volume, physical); - logical = logical % (addr_per_block * addr_per_block); - physical = __le32_to_cpu(((unsigned int *)volume->buffer)[logical / addr_per_block]); - ext2_read_block(volume, physical); - physical = __le32_to_cpu(((unsigned int *)volume->buffer)[logical % addr_per_block]); - return physical; -} - -int ext2_read_data(ext2_VOLUME* volume, struct ext2_inode *inode, - off_t offset, char *buffer, size_t length) -{ - unsigned int logical, physical; - int blocksize = EXT2_BLOCK_SIZE(volume->super); - int shift; - size_t read; - - if (offset >= inode->i_size) - return -1; - - if (offset + length >= inode->i_size) - length = inode->i_size - offset; - - read = 0; - logical = offset / blocksize; - shift = offset % blocksize; - - if (shift) { - physical = ext2_get_block_addr(volume, inode, logical); - ext2_read_block(volume, physical); - - if (length < blocksize - shift) { - memcpy(buffer, volume->buffer + shift, length); - return length; - } - read += blocksize - shift; - memcpy(buffer, volume->buffer + shift, read); - - buffer += read; - length -= read; - logical++; - } - - while (length) { - physical = ext2_get_block_addr(volume, inode, logical); - ext2_read_block(volume, physical); - - if (length < blocksize) { - memcpy(buffer, volume->buffer, length); - read += length; - return read; - } - memcpy(buffer, volume->buffer, blocksize); - - buffer += blocksize; - length -= blocksize; - read += blocksize; - logical++; - } - - return read; -} - -off_t ext2_dir_entry(ext2_VOLUME *volume, struct ext2_inode *inode, - off_t index, struct ext2_dir_entry_2 *entry) -{ - int ret; - - ret = ext2_read_data(volume, inode, index, - (char*)entry, sizeof(*entry)); - if (ret == -1) - return -1; - - entry->inode = __le32_to_cpu(entry->inode); - entry->rec_len = __le16_to_cpu(entry->rec_len); - return index + entry->rec_len; -} - -unsigned int ext2_seek_name(ext2_VOLUME *volume, const char *name) -{ - struct ext2_inode inode; - int ret; - unsigned int ino; - off_t index; - struct ext2_dir_entry_2 entry; - - ino = EXT2_ROOT_INO; - while(1) { - while (*name == '\\') - name++; - if (!*name) - break; - ret = ext2_get_inode(volume, ino, &inode); - if (ret == -1) - return 0; - index = 0; - while (1) { - index = ext2_dir_entry(volume, &inode, index, &entry); - if (index == -1) - return 0; - ret = strncmp(name, entry.name, entry.name_len); - if (ret == 0 && - (name[entry.name_len] == 0 || - name[entry.name_len] == '\\')) { - ino = entry.inode; - break; - } - } - name += entry.name_len; - } - - return ino; -} |