diff --git a/fs/ext2.c b/fs/ext2.c index 184b973..8e35f8d 100644 --- a/fs/ext2.c +++ b/fs/ext2.c @@ -241,8 +241,6 @@ struct grub_ext2_data grub_disk_t disk; struct grub_ext2_inode *inode; struct grub_fshelp_node diropen; - struct grub_fshelp_node logfile; - grub_fshelp_journal_t journal; }; #ifndef GRUB_UTIL @@ -257,11 +255,11 @@ inline static grub_err_t grub_ext2_blockgroup (struct grub_ext2_data *data, int group, struct grub_ext2_block_group *blkgrp) { - return grub_fshelp_read (data->disk, data->journal, - grub_le_to_cpu32 (data->sblock.first_data_block) + 1, - group * sizeof (struct grub_ext2_block_group), - sizeof (struct grub_ext2_block_group), - (char *) blkgrp, LOG2_EXT2_BLOCK_SIZE (data)); + return grub_disk_read (data->disk, + ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1) + << LOG2_EXT2_BLOCK_SIZE (data)), + group * sizeof (struct grub_ext2_block_group), + sizeof (struct grub_ext2_block_group), (char *) blkgrp); } @@ -282,9 +280,10 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) { grub_uint32_t indir[blksz / 4]; - if (grub_fshelp_read (data->disk, data->journal, - grub_le_to_cpu32 (inode->blocks.indir_block), - 0, blksz, (char *) indir, log2_blksz)) + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (inode->blocks.indir_block) + << log2_blksz, + 0, blksz, (char *) indir)) return grub_errno; blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]); @@ -297,14 +296,16 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) + blksz / 4); grub_uint32_t indir[blksz / 4]; - if (grub_fshelp_read (data->disk, data->journal, - grub_le_to_cpu32 (inode->blocks.double_indir_block), - 0, blksz, (char *) indir, log2_blksz)) + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (inode->blocks.double_indir_block) + << log2_blksz, + 0, blksz, (char *) indir)) return grub_errno; - if (grub_fshelp_read (data->disk, data->journal, - grub_le_to_cpu32 (indir[rblock / perblock]), - 0, blksz, (char *) indir, log2_blksz)) + if (grub_disk_read (data->disk, + grub_le_to_cpu32 (indir[rblock / perblock]) + << log2_blksz, + 0, blksz, (char *) indir)) return grub_errno; @@ -318,7 +319,7 @@ grub_ext2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) blknr = -1; } - return grub_fshelp_map_block (data->journal, blknr); + return blknr; } /* Read LEN bytes from the file described by DATA starting with byte @@ -344,6 +345,8 @@ grub_ext2_read_inode (struct grub_ext2_data *data, { struct grub_ext2_block_group blkgrp; struct grub_ext2_sblock *sblock = &data->sblock; + int inodes_per_block; + unsigned int blkno; unsigned int blkoff; /* It is easier to calculate if the first inode is 0. */ @@ -355,184 +358,23 @@ grub_ext2_read_inode (struct grub_ext2_data *data, if (grub_errno) return grub_errno; - blkoff = ino % grub_le_to_cpu32 (sblock->inodes_per_group); + inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data); + blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + / inodes_per_block; + blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group)) + % inodes_per_block; /* Read the inode. */ - if (grub_fshelp_read (data->disk, data->journal, - grub_le_to_cpu32 (blkgrp.inode_table_id), - EXT2_INODE_SIZE (data) * blkoff, - sizeof (struct grub_ext2_inode), (char *) inode, - LOG2_EXT2_BLOCK_SIZE (data))) + if (grub_disk_read (data->disk, + ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno) + << LOG2_EXT2_BLOCK_SIZE (data)), + EXT2_INODE_SIZE (data) * blkoff, + sizeof (struct grub_ext2_inode), (char *) inode)) return grub_errno; return 0; } -static void -grub_ext3_get_journal (struct grub_ext2_data *data) -{ - char buf[1 << LOG2_BLOCK_SIZE (data)]; - struct grub_ext3_journal_sblock *jsb; - grub_fshelp_journal_t log; - int last_num, num, block, log2bs; - grub_uint32_t seq; - - auto void next_block (void); - void next_block (void) - { - block++; - if (block >= log->last_block) - block = log->first_block; - } - - data->journal = 0; - - if (! (data->sblock.feature_compatibility & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - return; - - if (! data->sblock.journal_inum) - return; - - data->logfile.data = data; - data->logfile.ino = data->sblock.journal_inum; - data->logfile.inode_read = 1; - - if (grub_ext2_read_inode (data, data->logfile.ino, &data->logfile.inode)) - return; - - log2bs = LOG2_EXT2_BLOCK_SIZE (data); - if (grub_fshelp_read_file (data->disk, &data->logfile, 0, - 0, sizeof (struct grub_ext3_journal_sblock), - buf, grub_ext2_read_block, - sizeof (buf), log2bs) != - sizeof (struct grub_ext3_journal_sblock)) - return; - - jsb = (struct grub_ext3_journal_sblock *) &buf[0]; - if (grub_be_to_cpu32 (jsb->header.magic) != EXT3_JOURNAL_MAGIC_NUMBER) - return; - - /* Empty journal. */ - if (! jsb->start) - return; - - log = grub_malloc (sizeof (struct grub_fshelp_journal) + - grub_be_to_cpu32 (jsb->maxlen) * sizeof (grub_disk_addr_t)); - if (! log) - return; - - log->type = GRUB_FSHELP_JOURNAL_TYPE_FILE; - log->node = &data->logfile; - log->get_block = grub_ext2_read_block; - log->first_block = grub_be_to_cpu32 (jsb->first); - log->last_block = grub_be_to_cpu32 (jsb->maxlen); - log->start_block = grub_be_to_cpu32 (jsb->start); - - last_num = num = 0; - block = log->start_block; - seq = grub_be_to_cpu32 (jsb->sequence); - - while (1) - { - struct grub_ext3_journal_header *jh; - - grub_fshelp_read_file (data->disk, &data->logfile, 0, - block << (log2bs + 9), sizeof (buf), - buf, grub_ext2_read_block, - log->last_block << (log2bs + 9), - log2bs); - if (grub_errno) - break; - - jh = (struct grub_ext3_journal_header *) &buf[0]; - if (grub_be_to_cpu32 (jh->magic) != EXT3_JOURNAL_MAGIC_NUMBER) - break; - - if (grub_be_to_cpu32 (jh->sequence) != seq) - break; - - log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING; - next_block(); - - switch (grub_be_to_cpu32 (jh->block_type)) - { - case EXT3_JOURNAL_DESCRIPTOR_BLOCK: - { - struct grub_ext3_journal_block_tag *tag; - int ofs, flags; - - ofs = sizeof (struct grub_ext3_journal_header); - - do - { - tag = (struct grub_ext3_journal_block_tag *) &buf[ofs]; - ofs += sizeof (struct grub_ext3_journal_block_tag); - - if (ofs > (int) sizeof (buf)) - break; - - flags = grub_be_to_cpu32 (tag->flags); - if (! (flags & EXT3_JOURNAL_FLAG_SAME_UUID)) - ofs += 16; - - log->mapping[num++] = grub_be_to_cpu32 (tag->block); - next_block(); - } - while (! (flags & EXT3_JOURNAL_FLAG_LAST_TAG)); - - continue; - } - - case EXT3_JOURNAL_COMMIT_BLOCK: - { - seq++; - last_num = num - 1; - continue; - } - - case EXT3_JOURNAL_REVOKE_BLOCK: - { - struct grub_ext3_journal_revoke_header *jrh; - grub_uint32_t i, cnt; - - jrh = (struct grub_ext3_journal_revoke_header *) jh; - cnt = (grub_be_to_cpu32 (jrh->count) - - sizeof (struct grub_ext3_journal_revoke_header)) >> 2; - - for (i = 0; i < cnt; i++) - { - int j; - grub_uint32_t map; - - map = grub_be_to_cpu32 (jrh->data[i]); - for (j = 0; j < num; j++) - if (log->mapping[j] == map) - log->mapping[j] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING; - } - - continue; - } - default: - last_num = 0; - goto quit; - } - } - -quit: - if (! last_num) - grub_free (log); - else - { - int size; - - size = sizeof (struct grub_fshelp_journal) + - last_num * sizeof (grub_disk_addr_t); - - log->num_mappings = last_num; - data->journal = grub_realloc (log, size); - } -} - static struct grub_ext2_data * grub_ext2_mount (grub_disk_t disk) { @@ -553,7 +395,6 @@ grub_ext2_mount (grub_disk_t disk) goto fail; data->disk = disk; - grub_ext3_get_journal (data); data->diropen.data = data; data->diropen.ino = 2; @@ -758,11 +599,7 @@ grub_ext2_open (struct grub_file *file, const char *name) static grub_err_t grub_ext2_close (grub_file_t file) { - if (file->data) - { - grub_free (((struct grub_ext2_data *) file->data)->journal); - grub_free (file->data); - } + grub_free (file->data); #ifndef GRUB_UTIL grub_dl_unref (my_mod); diff --git a/fs/fshelp.c b/fs/fshelp.c index 2fae065..2bf1939 100644 --- a/fs/fshelp.c +++ b/fs/fshelp.c @@ -214,46 +214,6 @@ grub_fshelp_find_file (const char *path, grub_fshelp_node_t rootnode, return 0; } - -/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF, - beginning with the block POS. Apply mappings from LOG. The blocks - have a size of LOG2BLOCKSIZE (in log2). */ -grub_err_t grub_fshelp_read (grub_disk_t disk, grub_fshelp_journal_t log, - grub_disk_addr_t block, grub_off_t pos, - grub_size_t len, char *buf, int log2blocksize) -{ - grub_off_t relblk; - - relblk = pos >> (log2blocksize + GRUB_DISK_SECTOR_BITS); - block += relblk; - pos -= relblk << (log2blocksize + GRUB_DISK_SECTOR_BITS); - - while (len > 0) - { - grub_err_t ret; - grub_size_t size; - - size = (GRUB_DISK_SECTOR_SIZE << log2blocksize) - pos; - if (size > len) - size = len; - - ret = grub_disk_read (disk, - grub_fshelp_map_block (log, block) << log2blocksize, - pos, size, buf); - - if (ret) - return ret; - - block++; - pos = 0; - buf += size; - len -= size; - } - - return 0; -} - - /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, beginning with the block POS. READ_HOOK should be set before reading a block from the file. GET_BLOCK is used to translate file @@ -350,30 +310,3 @@ grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow) return GRUB_ERR_NONE; } - -grub_disk_addr_t -grub_fshelp_map_block (grub_fshelp_journal_t log, grub_disk_addr_t block) -{ - int map_block; - - if ((! log) || (! block)) - return block; - - for (map_block = log->num_mappings - 1; map_block >= 0; map_block--) - { - if (log->mapping[map_block] == block) - break; - } - - if (map_block < 0) - return block; - - map_block += log->start_block; - if (map_block >= log->last_block) - map_block -= log->last_block - log->first_block; - - if (log->type == GRUB_FSHELP_JOURNAL_TYPE_BLOCK) - return log->blkno + map_block; - else - return log->get_block (log->node, map_block); -} diff --git a/fs/reiserfs.c b/fs/reiserfs.c index 9a059e3..9bde6d2 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -234,7 +234,6 @@ struct grub_reiserfs_data { struct grub_reiserfs_superblock superblock; grub_disk_t disk; - grub_fshelp_journal_t journal; }; /* Internal-only functions. Not to be used outside of this file. */ @@ -511,8 +510,7 @@ grub_reiserfs_get_item (struct grub_reiserfs_data *data, do { grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), (((grub_off_t) block_number * block_size) & (GRUB_DISK_SECTOR_SIZE - 1)), block_size, (char *) block_header); @@ -662,8 +660,7 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node) block_size = grub_le_to_cpu16 (node->data->superblock.block_size); len = grub_le_to_cpu16 (found.header.item_size); - block = (grub_fshelp_map_block (node->data->journal, found.block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS)); + block = found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS); offset = grub_le_to_cpu16 (found.header.item_location); symlink_buffer = grub_malloc (len + 1); @@ -682,124 +679,6 @@ grub_reiserfs_read_symlink (grub_fshelp_node_t node) return 0; } -static void -grub_reiserfs_get_journal (struct grub_reiserfs_data *data) -{ - int block_size = grub_le_to_cpu16 (data->superblock.block_size); - char buf[block_size]; - struct grub_reiserfs_journal_header *jh; - grub_fshelp_journal_t log; - grub_uint32_t seq_id, mount_id; - int num_blocks = grub_le_to_cpu32 (data->superblock.journal_original_size); - int base_block = grub_le_to_cpu32 (data->superblock.journal_block); - int last_num, num, block; - - data->journal = 0; - - if (! data->superblock.journal_block) - return; - - if (grub_disk_read (data->disk, - (base_block + num_blocks) - * (block_size >> GRUB_DISK_SECTOR_BITS), - 0, sizeof (struct grub_reiserfs_journal_header), - buf)) - return; - - log = grub_malloc (sizeof (struct grub_fshelp_journal) + - num_blocks * sizeof (grub_disk_addr_t)); - if (! log) - return; - - jh = (struct grub_reiserfs_journal_header *) &buf[0]; - - log->type = GRUB_FSHELP_JOURNAL_TYPE_BLOCK; - log->blkno = base_block; - log->first_block = 0; - log->last_block = num_blocks; - log->start_block = grub_le_to_cpu32 (jh->unflushed_offset); - - seq_id = grub_le_to_cpu32 (jh->last_flush_uid); - mount_id = grub_le_to_cpu32 (jh->mount_id); - - last_num = num = 0; - block = log->start_block; - - while (1) - { - struct grub_reiserfs_description_block *db; - struct grub_reiserfs_commit_block *cb; - grub_uint32_t i, len, half_len, id, mid; - - if (grub_disk_read (data->disk, - (base_block + block) - * (block_size >> GRUB_DISK_SECTOR_BITS), - 0, sizeof (buf), buf)) - break; - - if (grub_memcmp (&buf[block_size - REISERFS_MAGIC_LEN], - REISERFS_MAGIC_DESC_BLOCK, - sizeof (REISERFS_MAGIC_DESC_BLOCK) - 1)) - break; - - db = (struct grub_reiserfs_description_block *) &buf[0]; - id = grub_le_to_cpu32 (db->id); - len = grub_le_to_cpu32 (db->len); - mid = grub_le_to_cpu32 (db->mount_id); - if ((id <= seq_id) && (mid <= mount_id)) - break; - - log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING; - half_len = ((block_size - 24) >> 2); - if (half_len > len) - half_len = len; - - for (i = 0; i < half_len; i++) - log->mapping[num++] = db->real_blocks[i]; - - block += grub_le_to_cpu32 (db->len) + 1; - if (block >= log->last_block) - block -= log->last_block; - - if (grub_disk_read (data->disk, - (base_block + block) - * (block_size >> GRUB_DISK_SECTOR_BITS), - 0, sizeof (buf), buf)) - break; - - cb = (struct grub_reiserfs_commit_block *) &buf[0]; - if ((grub_le_to_cpu32 (cb->id) != id) || - (grub_le_to_cpu32 (cb->len) != len)) - break; - - for (i = 0; i < len - half_len; i++) - log->mapping[num++] = cb->real_blocks[i]; - - last_num = num; - log->mapping[num++] = GRUB_FSHELP_JOURNAL_UNUSED_MAPPING; - - block++; - if (block >= log->last_block) - block -= log->last_block; - - seq_id = id; - mount_id = mid; - }; - - if (! last_num) - grub_free (log); - else - { - int size; - - size = sizeof (struct grub_fshelp_journal) + - last_num * sizeof (grub_disk_addr_t); - - log->num_mappings = last_num; - data->journal = grub_realloc (log, size); - } -} - /* Fill the mounted filesystem structure and return it. */ static struct grub_reiserfs_data * grub_reiserfs_mount (grub_disk_t disk) @@ -819,7 +698,6 @@ grub_reiserfs_mount (grub_disk_t disk) goto fail; } data->disk = disk; - grub_reiserfs_get_journal (data); return data; fail: @@ -867,8 +745,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, struct grub_reiserfs_item_header *item_headers; grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), (((grub_off_t) block_number * block_size) & (GRUB_DISK_SECTOR_SIZE - 1)), block_size, (char *) block_header); @@ -962,8 +839,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, { struct grub_reiserfs_stat_item_v1 entry_v1_stat; grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, entry_block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), grub_le_to_cpu16 (entry_item->header.item_location), sizeof (entry_v1_stat), (char *) &entry_v1_stat); @@ -1005,8 +881,7 @@ grub_reiserfs_iterate_dir (grub_fshelp_node_t item, { struct grub_reiserfs_stat_item_v2 entry_v2_stat; grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, entry_block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + entry_block_number * (block_size >> GRUB_DISK_SECTOR_BITS), grub_le_to_cpu16 (entry_item->header.item_location), sizeof (entry_v2_stat), (char *) &entry_v2_stat); @@ -1154,8 +1029,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name) { struct grub_reiserfs_stat_item_v1 entry_v1_stat; grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), entry_location + (((grub_off_t) block_number * block_size) & (GRUB_DISK_SECTOR_SIZE - 1)), @@ -1168,8 +1042,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name) { struct grub_reiserfs_stat_item_v2 entry_v2_stat; grub_disk_read (data->disk, - grub_fshelp_map_block (data->journal, block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + block_number * (block_size >> GRUB_DISK_SECTOR_BITS), entry_location + (((grub_off_t) block_number * block_size) & (GRUB_DISK_SECTOR_SIZE - 1)), @@ -1237,8 +1110,7 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) switch (found.type) { case GRUB_REISERFS_DIRECT: - block = (grub_fshelp_map_block (data->journal, found.block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS)); + block = found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS); grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block); if (initial_position < current_position + item_size) { @@ -1270,8 +1142,7 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) if (! indirect_block_ptr) goto fail; grub_disk_read (found.data->disk, - grub_fshelp_map_block (data->journal, found.block_number) * - (block_size >> GRUB_DISK_SECTOR_BITS), + found.block_number * (block_size >> GRUB_DISK_SECTOR_BITS), grub_le_to_cpu16 (found.header.item_location), item_size, (char *) indirect_block_ptr); if (grub_errno) @@ -1282,9 +1153,8 @@ grub_reiserfs_read (grub_file_t file, char *buf, grub_size_t len) && current_position < final_position; indirect_block++) { - block = (grub_fshelp_map_block (data->journal, - grub_le_to_cpu32 (indirect_block_ptr[indirect_block])) * - (block_size >> GRUB_DISK_SECTOR_BITS)); + block = grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * + (block_size >> GRUB_DISK_SECTOR_BITS); grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block); if (current_position + block_size >= initial_position) { @@ -1383,7 +1253,6 @@ grub_reiserfs_close (grub_file_t file) struct grub_fshelp_node *node = file->data; struct grub_reiserfs_data *data = node->data; - grub_free (data->journal); grub_free (data); grub_free (node); #ifndef GRUB_UTIL diff --git a/include/grub/fshelp.h b/include/grub/fshelp.h index 847f78e..698c7aa 100644 --- a/include/grub/fshelp.h +++ b/include/grub/fshelp.h @@ -34,34 +34,6 @@ enum grub_fshelp_filetype GRUB_FSHELP_SYMLINK }; -enum grub_fshelp_journal_type - { - GRUB_FSHELP_JOURNAL_TYPE_BLOCK, - GRUB_FSHELP_JOURNAL_TYPE_FILE - }; - -#define GRUB_FSHELP_JOURNAL_UNUSED_MAPPING (grub_disk_addr_t) -1 - -struct grub_fshelp_journal -{ - int type; - union - { - struct - { - grub_fshelp_node_t node; - grub_disk_addr_t (*get_block) (grub_fshelp_node_t node, grub_disk_addr_t block); - }; - grub_disk_addr_t blkno; - }; - int first_block; - int last_block; - int start_block; - int num_mappings; - grub_disk_addr_t mapping[0]; -}; -typedef struct grub_fshelp_journal *grub_fshelp_journal_t; - /* Lookup the node PATH. The node ROOTNODE describes the root of the directory tree. The node found is returned in FOUNDNODE, which is either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to @@ -84,15 +56,6 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path, enum grub_fshelp_filetype expect); -/* Read LEN bytes from the block BLOCK on disk DISK into the buffer BUF, - beginning with the block POS. Apply mappings from LOG. The blocks - have a size of LOG2BLOCKSIZE (in log2). */ -grub_err_t -EXPORT_FUNC(grub_fshelp_read) (grub_disk_t disk, grub_fshelp_journal_t log, - grub_disk_addr_t block, grub_off_t pos, - grub_size_t len, char *buf, int log2blocksize); - - /* Read LEN bytes from the file NODE on disk DISK into the buffer BUF, beginning with the block POS. READ_HOOK should be set before reading a block from the file. GET_BLOCK is used to translate file @@ -112,7 +75,4 @@ unsigned int EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize, unsigned int *pow); -grub_disk_addr_t -EXPORT_FUNC(grub_fshelp_map_block) (grub_fshelp_journal_t log, grub_disk_addr_t block); - #endif /* ! GRUB_FSHELP_HEADER */