diff options
Diffstat (limited to 'qemu/roms/u-boot/fs/ext4/ext4_journal.c')
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_journal.c | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/qemu/roms/u-boot/fs/ext4/ext4_journal.c b/qemu/roms/u-boot/fs/ext4/ext4_journal.c deleted file mode 100644 index 3f613351a..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4_journal.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * (C) Copyright 2011 - 2012 Samsung Electronics - * EXT4 filesystem implementation in Uboot by - * Uma Shankar <uma.shankar@samsung.com> - * Manjunatha C Achar <a.manjunatha@samsung.com> - * - * Journal data structures and headers for Journaling feature of ext4 - * have been referred from JBD2 (Journaling Block device 2) - * implementation in Linux Kernel. - * Written by Stephen C. Tweedie <sct@redhat.com> - * - * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <ext4fs.h> -#include <malloc.h> -#include <ext_common.h> -#include "ext4_common.h" - -static struct revoke_blk_list *revk_blk_list; -static struct revoke_blk_list *prev_node; -static int first_node = true; - -int gindex; -int gd_index; -int jrnl_blk_idx; -struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES]; -struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES]; - -int ext4fs_init_journal(void) -{ - int i; - char *temp = NULL; - struct ext_filesystem *fs = get_fs(); - - /* init globals */ - revk_blk_list = NULL; - prev_node = NULL; - gindex = 0; - gd_index = 0; - jrnl_blk_idx = 1; - - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - journal_ptr[i] = zalloc(sizeof(struct journal_log)); - if (!journal_ptr[i]) - goto fail; - dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks)); - if (!dirty_block_ptr[i]) - goto fail; - journal_ptr[i]->buf = NULL; - journal_ptr[i]->blknr = -1; - - dirty_block_ptr[i]->buf = NULL; - dirty_block_ptr[i]->blknr = -1; - } - - if (fs->blksz == 4096) { - temp = zalloc(fs->blksz); - if (!temp) - goto fail; - journal_ptr[gindex]->buf = zalloc(fs->blksz); - if (!journal_ptr[gindex]->buf) - goto fail; - ext4fs_devread(0, 0, fs->blksz, temp); - memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE); - memcpy(journal_ptr[gindex]->buf, temp, fs->blksz); - journal_ptr[gindex++]->blknr = 0; - free(temp); - } else { - journal_ptr[gindex]->buf = zalloc(fs->blksz); - if (!journal_ptr[gindex]->buf) - goto fail; - memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE); - journal_ptr[gindex++]->blknr = 1; - } - - /* Check the file system state using journal super block */ - if (ext4fs_check_journal_state(SCAN)) - goto fail; - /* Check the file system state using journal super block */ - if (ext4fs_check_journal_state(RECOVER)) - goto fail; - - return 0; -fail: - return -1; -} - -void ext4fs_dump_metadata(void) -{ - struct ext_filesystem *fs = get_fs(); - int i; - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (dirty_block_ptr[i]->blknr == -1) - break; - put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr * - (uint64_t)fs->blksz), dirty_block_ptr[i]->buf, - fs->blksz); - } -} - -void ext4fs_free_journal(void) -{ - int i; - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (dirty_block_ptr[i]->blknr == -1) - break; - if (dirty_block_ptr[i]->buf) - free(dirty_block_ptr[i]->buf); - } - - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (journal_ptr[i]->blknr == -1) - break; - if (journal_ptr[i]->buf) - free(journal_ptr[i]->buf); - } - - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (journal_ptr[i]) - free(journal_ptr[i]); - if (dirty_block_ptr[i]) - free(dirty_block_ptr[i]); - } - gindex = 0; - gd_index = 0; - jrnl_blk_idx = 1; -} - -int ext4fs_log_gdt(char *gd_table) -{ - struct ext_filesystem *fs = get_fs(); - short i; - long int var = fs->gdtable_blkno; - for (i = 0; i < fs->no_blk_pergdt; i++) { - journal_ptr[gindex]->buf = zalloc(fs->blksz); - if (!journal_ptr[gindex]->buf) - return -ENOMEM; - memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz); - gd_table += fs->blksz; - journal_ptr[gindex++]->blknr = var++; - } - - return 0; -} - -/* - * This function stores the backup copy of meta data in RAM - * journal_buffer -- Buffer containing meta data - * blknr -- Block number on disk of the meta data buffer - */ -int ext4fs_log_journal(char *journal_buffer, long int blknr) -{ - struct ext_filesystem *fs = get_fs(); - short i; - - if (!journal_buffer) { - printf("Invalid input arguments %s\n", __func__); - return -EINVAL; - } - - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (journal_ptr[i]->blknr == -1) - break; - if (journal_ptr[i]->blknr == blknr) - return 0; - } - - journal_ptr[gindex]->buf = zalloc(fs->blksz); - if (!journal_ptr[gindex]->buf) - return -ENOMEM; - - memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz); - journal_ptr[gindex++]->blknr = blknr; - - return 0; -} - -/* - * This function stores the modified meta data in RAM - * metadata_buffer -- Buffer containing meta data - * blknr -- Block number on disk of the meta data buffer - */ -int ext4fs_put_metadata(char *metadata_buffer, long int blknr) -{ - struct ext_filesystem *fs = get_fs(); - if (!metadata_buffer) { - printf("Invalid input arguments %s\n", __func__); - return -EINVAL; - } - dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz); - if (!dirty_block_ptr[gd_index]->buf) - return -ENOMEM; - memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz); - dirty_block_ptr[gd_index++]->blknr = blknr; - - return 0; -} - -void print_revoke_blks(char *revk_blk) -{ - int offset; - int max; - long int blocknr; - struct journal_revoke_header_t *header; - - if (revk_blk == NULL) - return; - - header = (struct journal_revoke_header_t *) revk_blk; - offset = sizeof(struct journal_revoke_header_t); - max = be32_to_cpu(header->r_count); - printf("total bytes %d\n", max); - - while (offset < max) { - blocknr = be32_to_cpu(*((long int *)(revk_blk + offset))); - printf("revoke blknr is %ld\n", blocknr); - offset += 4; - } -} - -static struct revoke_blk_list *_get_node(void) -{ - struct revoke_blk_list *tmp_node; - tmp_node = zalloc(sizeof(struct revoke_blk_list)); - if (tmp_node == NULL) - return NULL; - tmp_node->content = NULL; - tmp_node->next = NULL; - - return tmp_node; -} - -void ext4fs_push_revoke_blk(char *buffer) -{ - struct revoke_blk_list *node = NULL; - struct ext_filesystem *fs = get_fs(); - if (buffer == NULL) { - printf("buffer ptr is NULL\n"); - return; - } - node = _get_node(); - if (!node) { - printf("_get_node: malloc failed\n"); - return; - } - - node->content = zalloc(fs->blksz); - if (node->content == NULL) - return; - memcpy(node->content, buffer, fs->blksz); - - if (first_node == true) { - revk_blk_list = node; - prev_node = node; - first_node = false; - } else { - prev_node->next = node; - prev_node = node; - } -} - -void ext4fs_free_revoke_blks(void) -{ - struct revoke_blk_list *tmp_node = revk_blk_list; - struct revoke_blk_list *next_node = NULL; - - while (tmp_node != NULL) { - if (tmp_node->content) - free(tmp_node->content); - tmp_node = tmp_node->next; - } - - tmp_node = revk_blk_list; - while (tmp_node != NULL) { - next_node = tmp_node->next; - free(tmp_node); - tmp_node = next_node; - } - - revk_blk_list = NULL; - prev_node = NULL; - first_node = true; -} - -int check_blknr_for_revoke(long int blknr, int sequence_no) -{ - struct journal_revoke_header_t *header; - int offset; - int max; - long int blocknr; - char *revk_blk; - struct revoke_blk_list *tmp_revk_node = revk_blk_list; - while (tmp_revk_node != NULL) { - revk_blk = tmp_revk_node->content; - - header = (struct journal_revoke_header_t *) revk_blk; - if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) { - offset = sizeof(struct journal_revoke_header_t); - max = be32_to_cpu(header->r_count); - - while (offset < max) { - blocknr = be32_to_cpu(*((long int *) - (revk_blk + offset))); - if (blocknr == blknr) - goto found; - offset += 4; - } - } - tmp_revk_node = tmp_revk_node->next; - } - - return -1; - -found: - return 0; -} - -/* - * This function parses the journal blocks and replays the - * suceessful transactions. A transaction is successfull - * if commit block is found for a descriptor block - * The tags in descriptor block contain the disk block - * numbers of the metadata to be replayed - */ -void recover_transaction(int prev_desc_logical_no) -{ - struct ext2_inode inode_journal; - struct ext_filesystem *fs = get_fs(); - struct journal_header_t *jdb; - long int blknr; - char *p_jdb; - int ofs, flags; - int i; - struct ext3_journal_block_tag *tag; - char *temp_buff = zalloc(fs->blksz); - char *metadata_buff = zalloc(fs->blksz); - if (!temp_buff || !metadata_buff) - goto fail; - i = prev_desc_logical_no; - ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, - (struct ext2_inode *)&inode_journal); - blknr = read_allocated_block((struct ext2_inode *) - &inode_journal, i); - ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, - temp_buff); - p_jdb = (char *)temp_buff; - jdb = (struct journal_header_t *) temp_buff; - ofs = sizeof(struct journal_header_t); - - do { - tag = (struct ext3_journal_block_tag *)&p_jdb[ofs]; - ofs += sizeof(struct ext3_journal_block_tag); - - if (ofs > fs->blksz) - break; - - flags = be32_to_cpu(tag->flags); - if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) - ofs += 16; - - i++; - debug("\t\ttag %u\n", be32_to_cpu(tag->block)); - if (revk_blk_list != NULL) { - if (check_blknr_for_revoke(be32_to_cpu(tag->block), - be32_to_cpu(jdb->h_sequence)) == 0) - continue; - } - blknr = read_allocated_block(&inode_journal, i); - ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, - fs->blksz, metadata_buff); - put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz), - metadata_buff, (uint32_t) fs->blksz); - } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); -fail: - free(temp_buff); - free(metadata_buff); -} - -void print_jrnl_status(int recovery_flag) -{ - if (recovery_flag == RECOVER) - printf("Journal Recovery Completed\n"); - else - printf("Journal Scan Completed\n"); -} - -int ext4fs_check_journal_state(int recovery_flag) -{ - int i; - int DB_FOUND = NO; - long int blknr; - int transaction_state = TRANSACTION_COMPLETE; - int prev_desc_logical_no = 0; - int curr_desc_logical_no = 0; - int ofs, flags; - struct ext2_inode inode_journal; - struct journal_superblock_t *jsb = NULL; - struct journal_header_t *jdb = NULL; - char *p_jdb = NULL; - struct ext3_journal_block_tag *tag = NULL; - char *temp_buff = NULL; - char *temp_buff1 = NULL; - struct ext_filesystem *fs = get_fs(); - - temp_buff = zalloc(fs->blksz); - if (!temp_buff) - return -ENOMEM; - temp_buff1 = zalloc(fs->blksz); - if (!temp_buff1) { - free(temp_buff); - return -ENOMEM; - } - - ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); - blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK); - ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz, - temp_buff); - jsb = (struct journal_superblock_t *) temp_buff; - - if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { - if (recovery_flag == RECOVER) - printf("Recovery required\n"); - } else { - if (recovery_flag == RECOVER) - printf("File System is consistent\n"); - goto end; - } - - if (be32_to_cpu(jsb->s_start) == 0) - goto end; - - if (!(jsb->s_feature_compat & - cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM))) - jsb->s_feature_compat |= - cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM); - - i = be32_to_cpu(jsb->s_first); - while (1) { - blknr = read_allocated_block(&inode_journal, i); - memset(temp_buff1, '\0', fs->blksz); - ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, - 0, fs->blksz, temp_buff1); - jdb = (struct journal_header_t *) temp_buff1; - - if (be32_to_cpu(jdb->h_blocktype) == - EXT3_JOURNAL_DESCRIPTOR_BLOCK) { - if (be32_to_cpu(jdb->h_sequence) != - be32_to_cpu(jsb->s_sequence)) { - print_jrnl_status(recovery_flag); - break; - } - - curr_desc_logical_no = i; - if (transaction_state == TRANSACTION_COMPLETE) - transaction_state = TRANSACTION_RUNNING; - else - return -1; - p_jdb = (char *)temp_buff1; - ofs = sizeof(struct journal_header_t); - do { - tag = (struct ext3_journal_block_tag *) - &p_jdb[ofs]; - ofs += sizeof(struct ext3_journal_block_tag); - if (ofs > fs->blksz) - break; - flags = be32_to_cpu(tag->flags); - if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID)) - ofs += 16; - i++; - debug("\t\ttag %u\n", be32_to_cpu(tag->block)); - } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); - i++; - DB_FOUND = YES; - } else if (be32_to_cpu(jdb->h_blocktype) == - EXT3_JOURNAL_COMMIT_BLOCK) { - if (be32_to_cpu(jdb->h_sequence) != - be32_to_cpu(jsb->s_sequence)) { - print_jrnl_status(recovery_flag); - break; - } - - if (transaction_state == TRANSACTION_RUNNING || - (DB_FOUND == NO)) { - transaction_state = TRANSACTION_COMPLETE; - i++; - jsb->s_sequence = - cpu_to_be32(be32_to_cpu( - jsb->s_sequence) + 1); - } - prev_desc_logical_no = curr_desc_logical_no; - if ((recovery_flag == RECOVER) && (DB_FOUND == YES)) - recover_transaction(prev_desc_logical_no); - - DB_FOUND = NO; - } else if (be32_to_cpu(jdb->h_blocktype) == - EXT3_JOURNAL_REVOKE_BLOCK) { - if (be32_to_cpu(jdb->h_sequence) != - be32_to_cpu(jsb->s_sequence)) { - print_jrnl_status(recovery_flag); - break; - } - if (recovery_flag == SCAN) - ext4fs_push_revoke_blk((char *)jdb); - i++; - } else { - debug("Else Case\n"); - if (be32_to_cpu(jdb->h_sequence) != - be32_to_cpu(jsb->s_sequence)) { - print_jrnl_status(recovery_flag); - break; - } - } - } - -end: - if (recovery_flag == RECOVER) { - jsb->s_start = cpu_to_be32(1); - jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1); - /* get the superblock */ - ext4_read_superblock((char *)fs->sb); - fs->sb->feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER; - - /* Update the super block */ - put_ext4((uint64_t) (SUPERBLOCK_SIZE), - (struct ext2_sblock *)fs->sb, - (uint32_t) SUPERBLOCK_SIZE); - ext4_read_superblock((char *)fs->sb); - - blknr = read_allocated_block(&inode_journal, - EXT2_JOURNAL_SUPERBLOCK); - put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), - (struct journal_superblock_t *)temp_buff, - (uint32_t) fs->blksz); - ext4fs_free_revoke_blks(); - } - free(temp_buff); - free(temp_buff1); - - return 0; -} - -static void update_descriptor_block(long int blknr) -{ - int i; - long int jsb_blknr; - struct journal_header_t jdb; - struct ext3_journal_block_tag tag; - struct ext2_inode inode_journal; - struct journal_superblock_t *jsb = NULL; - char *buf = NULL; - char *temp = NULL; - struct ext_filesystem *fs = get_fs(); - char *temp_buff = zalloc(fs->blksz); - if (!temp_buff) - return; - - ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); - jsb_blknr = read_allocated_block(&inode_journal, - EXT2_JOURNAL_SUPERBLOCK); - ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, - temp_buff); - jsb = (struct journal_superblock_t *) temp_buff; - - jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK); - jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); - jdb.h_sequence = jsb->s_sequence; - buf = zalloc(fs->blksz); - if (!buf) { - free(temp_buff); - return; - } - temp = buf; - memcpy(buf, &jdb, sizeof(struct journal_header_t)); - temp += sizeof(struct journal_header_t); - - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (journal_ptr[i]->blknr == -1) - break; - - tag.block = cpu_to_be32(journal_ptr[i]->blknr); - tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID); - memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag)); - temp = temp + sizeof(struct ext3_journal_block_tag); - } - - tag.block = cpu_to_be32(journal_ptr[--i]->blknr); - tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG); - memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag, - sizeof(struct ext3_journal_block_tag)); - put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz); - - free(temp_buff); - free(buf); -} - -static void update_commit_block(long int blknr) -{ - struct journal_header_t jdb; - struct ext_filesystem *fs = get_fs(); - char *buf = NULL; - struct ext2_inode inode_journal; - struct journal_superblock_t *jsb; - long int jsb_blknr; - char *temp_buff = zalloc(fs->blksz); - if (!temp_buff) - return; - - ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, - &inode_journal); - jsb_blknr = read_allocated_block(&inode_journal, - EXT2_JOURNAL_SUPERBLOCK); - ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz, - temp_buff); - jsb = (struct journal_superblock_t *) temp_buff; - - jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK); - jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER); - jdb.h_sequence = jsb->s_sequence; - buf = zalloc(fs->blksz); - if (!buf) { - free(temp_buff); - return; - } - memcpy(buf, &jdb, sizeof(struct journal_header_t)); - put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz); - - free(temp_buff); - free(buf); -} - -void ext4fs_update_journal(void) -{ - struct ext2_inode inode_journal; - struct ext_filesystem *fs = get_fs(); - long int blknr; - int i; - ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal); - blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); - update_descriptor_block(blknr); - for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) { - if (journal_ptr[i]->blknr == -1) - break; - blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); - put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), - journal_ptr[i]->buf, fs->blksz); - } - blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++); - update_commit_block(blknr); - printf("update journal finished\n"); -} |