diff options
author | RajithaY <rajithax.yerrumsetty@intel.com> | 2017-04-25 03:31:15 -0700 |
---|---|---|
committer | Rajitha Yerrumchetty <rajithax.yerrumsetty@intel.com> | 2017-05-22 06:48:08 +0000 |
commit | bb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch) | |
tree | ca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/u-boot/fs/ext4 | |
parent | a14b48d18a9ed03ec191cf16b162206998a895ce (diff) |
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to
kvmfornfv repo and make use of the updated latest qemu for the
execution of all testcase
Change-Id: I1280af507a857675c7f81d30c95255635667bdd7
Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/fs/ext4')
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/Makefile | 13 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/crc16.c | 62 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/crc16.h | 16 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/dev.c | 146 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_common.c | 2250 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_common.h | 78 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_journal.c | 653 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_journal.h | 125 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4_write.c | 977 | ||||
-rw-r--r-- | qemu/roms/u-boot/fs/ext4/ext4fs.c | 228 |
10 files changed, 0 insertions, 4548 deletions
diff --git a/qemu/roms/u-boot/fs/ext4/Makefile b/qemu/roms/u-boot/fs/ext4/Makefile deleted file mode 100644 index 8d15bdad6..000000000 --- a/qemu/roms/u-boot/fs/ext4/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2003 -# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de -# -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := ext4fs.o ext4_common.o dev.o -obj-$(CONFIG_EXT4_WRITE) += ext4_write.o ext4_journal.o crc16.o diff --git a/qemu/roms/u-boot/fs/ext4/crc16.c b/qemu/roms/u-boot/fs/ext4/crc16.c deleted file mode 100644 index 3afb34dae..000000000 --- a/qemu/roms/u-boot/fs/ext4/crc16.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * crc16.c - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#include <common.h> -#include <asm/byteorder.h> -#include <linux/stat.h> -#include "crc16.h" - -/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */ -static __u16 const crc16_table[256] = { - 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, - 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, - 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, - 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, - 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, - 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, - 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, - 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, - 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, - 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, - 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, - 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, - 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, - 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, - 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, - 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, - 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, - 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, - 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, - 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, - 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, - 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, - 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, - 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, - 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, - 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, - 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, - 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, - 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, - 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, - 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, - 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 -}; - -/** - * Compute the CRC-16 for the data buffer -*/ - -unsigned int ext2fs_crc16(unsigned int crc, - const void *buffer, unsigned int len) -{ - const unsigned char *cp = buffer; - - while (len--) - crc = (((crc >> 8) & 0xffU) ^ - crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU; - return crc; -} diff --git a/qemu/roms/u-boot/fs/ext4/crc16.h b/qemu/roms/u-boot/fs/ext4/crc16.h deleted file mode 100644 index 5fd113a56..000000000 --- a/qemu/roms/u-boot/fs/ext4/crc16.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * crc16.h - CRC-16 routine - * Implements the standard CRC-16: - * Width 16 - * Poly 0x8005 (x16 + x15 + x2 + 1) - * Init 0 - * - * Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com> - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ -#ifndef __CRC16_H -#define __CRC16_H -extern unsigned int ext2fs_crc16(unsigned int crc, - const void *buffer, unsigned int len); -#endif diff --git a/qemu/roms/u-boot/fs/ext4/dev.c b/qemu/roms/u-boot/fs/ext4/dev.c deleted file mode 100644 index e0b513a4e..000000000 --- a/qemu/roms/u-boot/fs/ext4/dev.c +++ /dev/null @@ -1,146 +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> - * - * made from existing ext2/dev.c file of Uboot - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code of fs/reiserfs/dev.c by - * - * (C) Copyright 2003 - 2004 - * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Changelog: - * 0.1 - Newly created file for ext4fs support. Taken from - * fs/ext2/dev.c file in uboot. - */ - -#include <common.h> -#include <config.h> -#include <ext4fs.h> -#include <ext_common.h> -#include "ext4_common.h" - -lbaint_t part_offset; - -static block_dev_desc_t *ext4fs_block_dev_desc; -static disk_partition_t *part_info; - -void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info) -{ - assert(rbdd->blksz == (1 << rbdd->log2blksz)); - ext4fs_block_dev_desc = rbdd; - get_fs()->dev_desc = rbdd; - part_info = info; - part_offset = info->start; - get_fs()->total_sect = ((uint64_t)info->size * info->blksz) >> - get_fs()->dev_desc->log2blksz; -} - -int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf) -{ - unsigned block_len; - int log2blksz = ext4fs_block_dev_desc->log2blksz; - ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, (ext4fs_block_dev_desc ? - ext4fs_block_dev_desc->blksz : - 0)); - if (ext4fs_block_dev_desc == NULL) { - printf("** Invalid Block Device Descriptor (NULL)\n"); - return 0; - } - - /* Check partition boundaries */ - if ((sector < 0) || - ((sector + ((byte_offset + byte_len - 1) >> log2blksz)) - >= part_info->size)) { - printf("%s read outside partition " LBAFU "\n", __func__, - sector); - return 0; - } - - /* Get the read to the beginning of a partition */ - sector += byte_offset >> log2blksz; - byte_offset &= ext4fs_block_dev_desc->blksz - 1; - - debug(" <" LBAFU ", %d, %d>\n", sector, byte_offset, byte_len); - - if (byte_offset != 0) { - /* read first part which isn't aligned with start of sector */ - if (ext4fs_block_dev_desc-> - block_read(ext4fs_block_dev_desc->dev, - part_info->start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf(" ** ext2fs_devread() read error **\n"); - return 0; - } - memcpy(buf, sec_buf + byte_offset, - min(ext4fs_block_dev_desc->blksz - - byte_offset, byte_len)); - buf += min(ext4fs_block_dev_desc->blksz - - byte_offset, byte_len); - byte_len -= min(ext4fs_block_dev_desc->blksz - - byte_offset, byte_len); - sector++; - } - - if (byte_len == 0) - return 1; - - /* read sector aligned part */ - block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1); - - if (block_len == 0) { - ALLOC_CACHE_ALIGN_BUFFER(u8, p, ext4fs_block_dev_desc->blksz); - - block_len = ext4fs_block_dev_desc->blksz; - ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, - part_info->start + sector, - 1, (unsigned long *)p); - memcpy(buf, p, byte_len); - return 1; - } - - if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev, - part_info->start + sector, - block_len >> log2blksz, - (unsigned long *) buf) != - block_len >> log2blksz) { - printf(" ** %s read error - block\n", __func__); - return 0; - } - block_len = byte_len & ~(ext4fs_block_dev_desc->blksz - 1); - buf += block_len; - byte_len -= block_len; - sector += block_len / ext4fs_block_dev_desc->blksz; - - if (byte_len != 0) { - /* read rest of data which are not in whole sector */ - if (ext4fs_block_dev_desc-> - block_read(ext4fs_block_dev_desc->dev, - part_info->start + sector, 1, - (unsigned long *) sec_buf) != 1) { - printf("* %s read error - last part\n", __func__); - return 0; - } - memcpy(buf, sec_buf, byte_len); - } - return 1; -} - -int ext4_read_superblock(char *buffer) -{ - struct ext_filesystem *fs = get_fs(); - int sect = SUPERBLOCK_START >> fs->dev_desc->log2blksz; - int off = SUPERBLOCK_START % fs->dev_desc->blksz; - - return ext4fs_devread(sect, off, SUPERBLOCK_SIZE, - buffer); -} diff --git a/qemu/roms/u-boot/fs/ext4/ext4_common.c b/qemu/roms/u-boot/fs/ext4/ext4_common.c deleted file mode 100644 index 1c1172163..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4_common.c +++ /dev/null @@ -1,2250 +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> - * - * ext4ls and ext4load : Based on ext2 ls load support in Uboot. - * - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * ext4write : Based on generic ext4 protocol. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <ext_common.h> -#include <ext4fs.h> -#include <malloc.h> -#include <stddef.h> -#include <linux/stat.h> -#include <linux/time.h> -#include <asm/byteorder.h> -#include "ext4_common.h" - -struct ext2_data *ext4fs_root; -struct ext2fs_node *ext4fs_file; -uint32_t *ext4fs_indir1_block; -int ext4fs_indir1_size; -int ext4fs_indir1_blkno = -1; -uint32_t *ext4fs_indir2_block; -int ext4fs_indir2_size; -int ext4fs_indir2_blkno = -1; - -uint32_t *ext4fs_indir3_block; -int ext4fs_indir3_size; -int ext4fs_indir3_blkno = -1; -struct ext2_inode *g_parent_inode; -static int symlinknest; - -#if defined(CONFIG_EXT4_WRITE) -uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n) -{ - uint32_t res = size / n; - if (res * n != size) - res++; - - return res; -} - -void put_ext4(uint64_t off, void *buf, uint32_t size) -{ - uint64_t startblock; - uint64_t remainder; - unsigned char *temp_ptr = NULL; - struct ext_filesystem *fs = get_fs(); - int log2blksz = fs->dev_desc->log2blksz; - ALLOC_CACHE_ALIGN_BUFFER(unsigned char, sec_buf, fs->dev_desc->blksz); - - startblock = off >> log2blksz; - startblock += part_offset; - remainder = off & (uint64_t)(fs->dev_desc->blksz - 1); - - if (fs->dev_desc == NULL) - return; - - if ((startblock + (size >> log2blksz)) > - (part_offset + fs->total_sect)) { - printf("part_offset is " LBAFU "\n", part_offset); - printf("total_sector is %llu\n", fs->total_sect); - printf("error: overflow occurs\n"); - return; - } - - if (remainder) { - if (fs->dev_desc->block_read) { - fs->dev_desc->block_read(fs->dev_desc->dev, - startblock, 1, sec_buf); - temp_ptr = sec_buf; - memcpy((temp_ptr + remainder), - (unsigned char *)buf, size); - fs->dev_desc->block_write(fs->dev_desc->dev, - startblock, 1, sec_buf); - } - } else { - if (size >> log2blksz != 0) { - fs->dev_desc->block_write(fs->dev_desc->dev, - startblock, - size >> log2blksz, - (unsigned long *)buf); - } else { - fs->dev_desc->block_read(fs->dev_desc->dev, - startblock, 1, sec_buf); - temp_ptr = sec_buf; - memcpy(temp_ptr, buf, size); - fs->dev_desc->block_write(fs->dev_desc->dev, - startblock, 1, - (unsigned long *)sec_buf); - } - } -} - -static int _get_new_inode_no(unsigned char *buffer) -{ - struct ext_filesystem *fs = get_fs(); - unsigned char input; - int operand, status; - int count = 1; - int j = 0; - - /* get the blocksize of the filesystem */ - unsigned char *ptr = buffer; - while (*ptr == 255) { - ptr++; - count += 8; - if (count > ext4fs_root->sblock.inodes_per_group) - return -1; - } - - for (j = 0; j < fs->blksz; j++) { - input = *ptr; - int i = 0; - while (i <= 7) { - operand = 1 << i; - status = input & operand; - if (status) { - i++; - count++; - } else { - *ptr |= operand; - return count; - } - } - ptr = ptr + 1; - } - - return -1; -} - -static int _get_new_blk_no(unsigned char *buffer) -{ - unsigned char input; - int operand, status; - int count = 0; - int j = 0; - unsigned char *ptr = buffer; - struct ext_filesystem *fs = get_fs(); - - if (fs->blksz != 1024) - count = 0; - else - count = 1; - - while (*ptr == 255) { - ptr++; - count += 8; - if (count == (fs->blksz * 8)) - return -1; - } - - for (j = 0; j < fs->blksz; j++) { - input = *ptr; - int i = 0; - while (i <= 7) { - operand = 1 << i; - status = input & operand; - if (status) { - i++; - count++; - } else { - *ptr |= operand; - return count; - } - } - ptr = ptr + 1; - } - - return -1; -} - -int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index) -{ - int i, remainder, status; - unsigned char *ptr = buffer; - unsigned char operand; - i = blockno / 8; - remainder = blockno % 8; - int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); - - i = i - (index * blocksize); - if (blocksize != 1024) { - ptr = ptr + i; - operand = 1 << remainder; - status = *ptr & operand; - if (status) - return -1; - - *ptr = *ptr | operand; - return 0; - } else { - if (remainder == 0) { - ptr = ptr + i - 1; - operand = (1 << 7); - } else { - ptr = ptr + i; - operand = (1 << (remainder - 1)); - } - status = *ptr & operand; - if (status) - return -1; - - *ptr = *ptr | operand; - return 0; - } -} - -void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, int index) -{ - int i, remainder, status; - unsigned char *ptr = buffer; - unsigned char operand; - i = blockno / 8; - remainder = blockno % 8; - int blocksize = EXT2_BLOCK_SIZE(ext4fs_root); - - i = i - (index * blocksize); - if (blocksize != 1024) { - ptr = ptr + i; - operand = (1 << remainder); - status = *ptr & operand; - if (status) - *ptr = *ptr & ~(operand); - } else { - if (remainder == 0) { - ptr = ptr + i - 1; - operand = (1 << 7); - } else { - ptr = ptr + i; - operand = (1 << (remainder - 1)); - } - status = *ptr & operand; - if (status) - *ptr = *ptr & ~(operand); - } -} - -int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index) -{ - int i, remainder, status; - unsigned char *ptr = buffer; - unsigned char operand; - - inode_no -= (index * ext4fs_root->sblock.inodes_per_group); - i = inode_no / 8; - remainder = inode_no % 8; - if (remainder == 0) { - ptr = ptr + i - 1; - operand = (1 << 7); - } else { - ptr = ptr + i; - operand = (1 << (remainder - 1)); - } - status = *ptr & operand; - if (status) - return -1; - - *ptr = *ptr | operand; - - return 0; -} - -void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index) -{ - int i, remainder, status; - unsigned char *ptr = buffer; - unsigned char operand; - - inode_no -= (index * ext4fs_root->sblock.inodes_per_group); - i = inode_no / 8; - remainder = inode_no % 8; - if (remainder == 0) { - ptr = ptr + i - 1; - operand = (1 << 7); - } else { - ptr = ptr + i; - operand = (1 << (remainder - 1)); - } - status = *ptr & operand; - if (status) - *ptr = *ptr & ~(operand); -} - -int ext4fs_checksum_update(unsigned int i) -{ - struct ext2_block_group *desc; - struct ext_filesystem *fs = get_fs(); - __u16 crc = 0; - - desc = (struct ext2_block_group *)&fs->bgd[i]; - if (fs->sb->feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) { - int offset = offsetof(struct ext2_block_group, bg_checksum); - - crc = ext2fs_crc16(~0, fs->sb->unique_id, - sizeof(fs->sb->unique_id)); - crc = ext2fs_crc16(crc, &i, sizeof(i)); - crc = ext2fs_crc16(crc, desc, offset); - offset += sizeof(desc->bg_checksum); /* skip checksum */ - assert(offset == sizeof(*desc)); - } - - return crc; -} - -static int check_void_in_dentry(struct ext2_dirent *dir, char *filename) -{ - int dentry_length; - int sizeof_void_space; - int new_entry_byte_reqd; - short padding_factor = 0; - - if (dir->namelen % 4 != 0) - padding_factor = 4 - (dir->namelen % 4); - - dentry_length = sizeof(struct ext2_dirent) + - dir->namelen + padding_factor; - sizeof_void_space = dir->direntlen - dentry_length; - if (sizeof_void_space == 0) - return 0; - - padding_factor = 0; - if (strlen(filename) % 4 != 0) - padding_factor = 4 - (strlen(filename) % 4); - - new_entry_byte_reqd = strlen(filename) + - sizeof(struct ext2_dirent) + padding_factor; - if (sizeof_void_space >= new_entry_byte_reqd) { - dir->direntlen = dentry_length; - return sizeof_void_space; - } - - return 0; -} - -void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type) -{ - unsigned int *zero_buffer = NULL; - char *root_first_block_buffer = NULL; - int direct_blk_idx; - long int root_blknr; - long int first_block_no_of_root = 0; - long int previous_blknr = -1; - int totalbytes = 0; - short int padding_factor = 0; - unsigned int new_entry_byte_reqd; - unsigned int last_entry_dirlen; - int sizeof_void_space = 0; - int templength = 0; - int inodeno; - int status; - struct ext_filesystem *fs = get_fs(); - /* directory entry */ - struct ext2_dirent *dir; - char *temp_dir = NULL; - - zero_buffer = zalloc(fs->blksz); - if (!zero_buffer) { - printf("No Memory\n"); - return; - } - root_first_block_buffer = zalloc(fs->blksz); - if (!root_first_block_buffer) { - free(zero_buffer); - printf("No Memory\n"); - return; - } -restart: - - /* read the block no allocated to a file */ - for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; - direct_blk_idx++) { - root_blknr = read_allocated_block(g_parent_inode, - direct_blk_idx); - if (root_blknr == 0) { - first_block_no_of_root = previous_blknr; - break; - } - previous_blknr = root_blknr; - } - - status = ext4fs_devread((lbaint_t)first_block_no_of_root - * fs->sect_perblk, - 0, fs->blksz, root_first_block_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) - goto fail; - dir = (struct ext2_dirent *)root_first_block_buffer; - totalbytes = 0; - while (dir->direntlen > 0) { - /* - * blocksize-totalbytes because last directory length - * i.e. dir->direntlen is free availble space in the - * block that means it is a last entry of directory - * entry - */ - - /* traversing the each directory entry */ - if (fs->blksz - totalbytes == dir->direntlen) { - if (strlen(filename) % 4 != 0) - padding_factor = 4 - (strlen(filename) % 4); - - new_entry_byte_reqd = strlen(filename) + - sizeof(struct ext2_dirent) + padding_factor; - padding_factor = 0; - /* - * update last directory entry length to its - * length because we are creating new directory - * entry - */ - if (dir->namelen % 4 != 0) - padding_factor = 4 - (dir->namelen % 4); - - last_entry_dirlen = dir->namelen + - sizeof(struct ext2_dirent) + padding_factor; - if ((fs->blksz - totalbytes - last_entry_dirlen) < - new_entry_byte_reqd) { - printf("1st Block Full:Allocate new block\n"); - - if (direct_blk_idx == INDIRECT_BLOCKS - 1) { - printf("Directory exceeds limit\n"); - goto fail; - } - g_parent_inode->b.blocks.dir_blocks - [direct_blk_idx] = ext4fs_get_new_blk_no(); - if (g_parent_inode->b.blocks.dir_blocks - [direct_blk_idx] == -1) { - printf("no block left to assign\n"); - goto fail; - } - put_ext4(((uint64_t) - ((uint64_t)g_parent_inode->b. - blocks.dir_blocks[direct_blk_idx] * - (uint64_t)fs->blksz)), zero_buffer, fs->blksz); - g_parent_inode->size = - g_parent_inode->size + fs->blksz; - g_parent_inode->blockcnt = - g_parent_inode->blockcnt + fs->sect_perblk; - if (ext4fs_put_metadata - (root_first_block_buffer, - first_block_no_of_root)) - goto fail; - goto restart; - } - dir->direntlen = last_entry_dirlen; - break; - } - - templength = dir->direntlen; - totalbytes = totalbytes + templength; - sizeof_void_space = check_void_in_dentry(dir, filename); - if (sizeof_void_space) - break; - - dir = (struct ext2_dirent *)((char *)dir + templength); - } - - /* make a pointer ready for creating next directory entry */ - templength = dir->direntlen; - totalbytes = totalbytes + templength; - dir = (struct ext2_dirent *)((char *)dir + templength); - - /* get the next available inode number */ - inodeno = ext4fs_get_new_inode_no(); - if (inodeno == -1) { - printf("no inode left to assign\n"); - goto fail; - } - dir->inode = inodeno; - if (sizeof_void_space) - dir->direntlen = sizeof_void_space; - else - dir->direntlen = fs->blksz - totalbytes; - - dir->namelen = strlen(filename); - dir->filetype = FILETYPE_REG; /* regular file */ - temp_dir = (char *)dir; - temp_dir = temp_dir + sizeof(struct ext2_dirent); - memcpy(temp_dir, filename, strlen(filename)); - - *p_ino = inodeno; - - /* update or write the 1st block of root inode */ - if (ext4fs_put_metadata(root_first_block_buffer, - first_block_no_of_root)) - goto fail; - -fail: - free(zero_buffer); - free(root_first_block_buffer); -} - -static int search_dir(struct ext2_inode *parent_inode, char *dirname) -{ - int status; - int inodeno; - int totalbytes; - int templength; - int direct_blk_idx; - long int blknr; - int found = 0; - char *ptr = NULL; - unsigned char *block_buffer = NULL; - struct ext2_dirent *dir = NULL; - struct ext2_dirent *previous_dir = NULL; - struct ext_filesystem *fs = get_fs(); - - /* read the block no allocated to a file */ - for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; - direct_blk_idx++) { - blknr = read_allocated_block(parent_inode, direct_blk_idx); - if (blknr == 0) - goto fail; - - /* read the blocks of parenet inode */ - block_buffer = zalloc(fs->blksz); - if (!block_buffer) - goto fail; - - status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, - 0, fs->blksz, (char *)block_buffer); - if (status == 0) - goto fail; - - dir = (struct ext2_dirent *)block_buffer; - ptr = (char *)dir; - totalbytes = 0; - while (dir->direntlen >= 0) { - /* - * blocksize-totalbytes because last directory - * length i.e.,*dir->direntlen is free availble - * space in the block that means - * it is a last entry of directory entry - */ - if (strlen(dirname) == dir->namelen) { - if (strncmp(dirname, ptr + - sizeof(struct ext2_dirent), - dir->namelen) == 0) { - previous_dir->direntlen += - dir->direntlen; - inodeno = dir->inode; - dir->inode = 0; - found = 1; - break; - } - } - - if (fs->blksz - totalbytes == dir->direntlen) - break; - - /* traversing the each directory entry */ - templength = dir->direntlen; - totalbytes = totalbytes + templength; - previous_dir = dir; - dir = (struct ext2_dirent *)((char *)dir + templength); - ptr = (char *)dir; - } - - if (found == 1) { - free(block_buffer); - block_buffer = NULL; - return inodeno; - } - - free(block_buffer); - block_buffer = NULL; - } - -fail: - free(block_buffer); - - return -1; -} - -static int find_dir_depth(char *dirname) -{ - char *token = strtok(dirname, "/"); - int count = 0; - while (token != NULL) { - token = strtok(NULL, "/"); - count++; - } - return count + 1 + 1; - /* - * for example for string /home/temp - * depth=home(1)+temp(1)+1 extra for NULL; - * so count is 4; - */ -} - -static int parse_path(char **arr, char *dirname) -{ - char *token = strtok(dirname, "/"); - int i = 0; - - /* add root */ - arr[i] = zalloc(strlen("/") + 1); - if (!arr[i]) - return -ENOMEM; - - arr[i++] = "/"; - - /* add each path entry after root */ - while (token != NULL) { - arr[i] = zalloc(strlen(token) + 1); - if (!arr[i]) - return -ENOMEM; - memcpy(arr[i++], token, strlen(token)); - token = strtok(NULL, "/"); - } - arr[i] = NULL; - - return 0; -} - -int ext4fs_iget(int inode_no, struct ext2_inode *inode) -{ - if (ext4fs_read_inode(ext4fs_root, inode_no, inode) == 0) - return -1; - - return 0; -} - -/* - * Function: ext4fs_get_parent_inode_num - * Return Value: inode Number of the parent directory of file/Directory to be - * created - * dirname : Input parmater, input path name of the file/directory to be created - * dname : Output parameter, to be filled with the name of the directory - * extracted from dirname - */ -int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags) -{ - int i; - int depth = 0; - int matched_inode_no; - int result_inode_no = -1; - char **ptr = NULL; - char *depth_dirname = NULL; - char *parse_dirname = NULL; - struct ext2_inode *parent_inode = NULL; - struct ext2_inode *first_inode = NULL; - struct ext2_inode temp_inode; - - if (*dirname != '/') { - printf("Please supply Absolute path\n"); - return -1; - } - - /* TODO: input validation make equivalent to linux */ - depth_dirname = zalloc(strlen(dirname) + 1); - if (!depth_dirname) - return -ENOMEM; - - memcpy(depth_dirname, dirname, strlen(dirname)); - depth = find_dir_depth(depth_dirname); - parse_dirname = zalloc(strlen(dirname) + 1); - if (!parse_dirname) - goto fail; - memcpy(parse_dirname, dirname, strlen(dirname)); - - /* allocate memory for each directory level */ - ptr = zalloc((depth) * sizeof(char *)); - if (!ptr) - goto fail; - if (parse_path(ptr, parse_dirname)) - goto fail; - parent_inode = zalloc(sizeof(struct ext2_inode)); - if (!parent_inode) - goto fail; - first_inode = zalloc(sizeof(struct ext2_inode)); - if (!first_inode) - goto fail; - memcpy(parent_inode, ext4fs_root->inode, sizeof(struct ext2_inode)); - memcpy(first_inode, parent_inode, sizeof(struct ext2_inode)); - if (flags & F_FILE) - result_inode_no = EXT2_ROOT_INO; - for (i = 1; i < depth; i++) { - matched_inode_no = search_dir(parent_inode, ptr[i]); - if (matched_inode_no == -1) { - if (ptr[i + 1] == NULL && i == 1) { - result_inode_no = EXT2_ROOT_INO; - goto end; - } else { - if (ptr[i + 1] == NULL) - break; - printf("Invalid path\n"); - result_inode_no = -1; - goto fail; - } - } else { - if (ptr[i + 1] != NULL) { - memset(parent_inode, '\0', - sizeof(struct ext2_inode)); - if (ext4fs_iget(matched_inode_no, - parent_inode)) { - result_inode_no = -1; - goto fail; - } - result_inode_no = matched_inode_no; - } else { - break; - } - } - } - -end: - if (i == 1) - matched_inode_no = search_dir(first_inode, ptr[i]); - else - matched_inode_no = search_dir(parent_inode, ptr[i]); - - if (matched_inode_no != -1) { - ext4fs_iget(matched_inode_no, &temp_inode); - if (temp_inode.mode & S_IFDIR) { - printf("It is a Directory\n"); - result_inode_no = -1; - goto fail; - } - } - - if (strlen(ptr[i]) > 256) { - result_inode_no = -1; - goto fail; - } - memcpy(dname, ptr[i], strlen(ptr[i])); - -fail: - free(depth_dirname); - free(parse_dirname); - free(ptr); - free(parent_inode); - free(first_inode); - - return result_inode_no; -} - -static int check_filename(char *filename, unsigned int blknr) -{ - unsigned int first_block_no_of_root; - int totalbytes = 0; - int templength = 0; - int status, inodeno; - int found = 0; - char *root_first_block_buffer = NULL; - char *root_first_block_addr = NULL; - struct ext2_dirent *dir = NULL; - struct ext2_dirent *previous_dir = NULL; - char *ptr = NULL; - struct ext_filesystem *fs = get_fs(); - - /* get the first block of root */ - first_block_no_of_root = blknr; - root_first_block_buffer = zalloc(fs->blksz); - if (!root_first_block_buffer) - return -ENOMEM; - root_first_block_addr = root_first_block_buffer; - status = ext4fs_devread((lbaint_t)first_block_no_of_root * - fs->sect_perblk, 0, - fs->blksz, root_first_block_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(root_first_block_buffer, first_block_no_of_root)) - goto fail; - dir = (struct ext2_dirent *)root_first_block_buffer; - ptr = (char *)dir; - totalbytes = 0; - while (dir->direntlen >= 0) { - /* - * blocksize-totalbytes because last - * directory length i.e., *dir->direntlen - * is free availble space in the block that - * means it is a last entry of directory entry - */ - if (strlen(filename) == dir->namelen) { - if (strncmp(filename, ptr + sizeof(struct ext2_dirent), - dir->namelen) == 0) { - printf("file found deleting\n"); - previous_dir->direntlen += dir->direntlen; - inodeno = dir->inode; - dir->inode = 0; - found = 1; - break; - } - } - - if (fs->blksz - totalbytes == dir->direntlen) - break; - - /* traversing the each directory entry */ - templength = dir->direntlen; - totalbytes = totalbytes + templength; - previous_dir = dir; - dir = (struct ext2_dirent *)((char *)dir + templength); - ptr = (char *)dir; - } - - - if (found == 1) { - if (ext4fs_put_metadata(root_first_block_addr, - first_block_no_of_root)) - goto fail; - return inodeno; - } -fail: - free(root_first_block_buffer); - - return -1; -} - -int ext4fs_filename_check(char *filename) -{ - short direct_blk_idx = 0; - long int blknr = -1; - int inodeno = -1; - - /* read the block no allocated to a file */ - for (direct_blk_idx = 0; direct_blk_idx < INDIRECT_BLOCKS; - direct_blk_idx++) { - blknr = read_allocated_block(g_parent_inode, direct_blk_idx); - if (blknr == 0) - break; - inodeno = check_filename(filename, blknr); - if (inodeno != -1) - return inodeno; - } - - return -1; -} - -long int ext4fs_get_new_blk_no(void) -{ - short i; - short status; - int remainder; - unsigned int bg_idx; - static int prev_bg_bitmap_index = -1; - unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - char *zero_buffer = zalloc(fs->blksz); - if (!journal_buffer || !zero_buffer) - goto fail; - struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable; - - if (fs->first_pass_bbmap == 0) { - for (i = 0; i < fs->no_blkgrp; i++) { - if (bgd[i].free_blocks) { - if (bgd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) { - put_ext4(((uint64_t) ((uint64_t)bgd[i].block_id * - (uint64_t)fs->blksz)), - zero_buffer, fs->blksz); - bgd[i].bg_flags = - bgd[i]. - bg_flags & ~EXT4_BG_BLOCK_UNINIT; - memcpy(fs->blk_bmaps[i], zero_buffer, - fs->blksz); - } - fs->curr_blkno = - _get_new_blk_no(fs->blk_bmaps[i]); - if (fs->curr_blkno == -1) - /* if block bitmap is completely fill */ - continue; - fs->curr_blkno = fs->curr_blkno + - (i * fs->blksz * 8); - fs->first_pass_bbmap++; - bgd[i].free_blocks--; - fs->sb->free_blocks--; - status = ext4fs_devread((lbaint_t) - bgd[i].block_id * - fs->sect_perblk, 0, - fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[i].block_id)) - goto fail; - goto success; - } else { - debug("no space left on block group %d\n", i); - } - } - - goto fail; - } else { -restart: - fs->curr_blkno++; - /* get the blockbitmap index respective to blockno */ - bg_idx = fs->curr_blkno / blk_per_grp; - if (fs->blksz == 1024) { - remainder = fs->curr_blkno % blk_per_grp; - if (!remainder) - bg_idx--; - } - - /* - * To skip completely filled block group bitmaps - * Optimize the block allocation - */ - if (bg_idx >= fs->no_blkgrp) - goto fail; - - if (bgd[bg_idx].free_blocks == 0) { - debug("block group %u is full. Skipping\n", bg_idx); - fs->curr_blkno = fs->curr_blkno + blk_per_grp; - fs->curr_blkno--; - goto restart; - } - - if (bgd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) { - memset(zero_buffer, '\0', fs->blksz); - put_ext4(((uint64_t) ((uint64_t)bgd[bg_idx].block_id * - (uint64_t)fs->blksz)), zero_buffer, fs->blksz); - memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz); - bgd[bg_idx].bg_flags = bgd[bg_idx].bg_flags & - ~EXT4_BG_BLOCK_UNINIT; - } - - if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx], - bg_idx) != 0) { - debug("going for restart for the block no %ld %u\n", - fs->curr_blkno, bg_idx); - goto restart; - } - - /* journal backup */ - if (prev_bg_bitmap_index != bg_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id - * fs->sect_perblk, - 0, fs->blksz, journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - - prev_bg_bitmap_index = bg_idx; - } - bgd[bg_idx].free_blocks--; - fs->sb->free_blocks--; - goto success; - } -success: - free(journal_buffer); - free(zero_buffer); - - return fs->curr_blkno; -fail: - free(journal_buffer); - free(zero_buffer); - - return -1; -} - -int ext4fs_get_new_inode_no(void) -{ - short i; - short status; - unsigned int ibmap_idx; - static int prev_inode_bitmap_index = -1; - unsigned int inodes_per_grp = ext4fs_root->sblock.inodes_per_group; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - char *zero_buffer = zalloc(fs->blksz); - if (!journal_buffer || !zero_buffer) - goto fail; - struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable; - - if (fs->first_pass_ibmap == 0) { - for (i = 0; i < fs->no_blkgrp; i++) { - if (bgd[i].free_inodes) { - if (bgd[i].bg_itable_unused != - bgd[i].free_inodes) - bgd[i].bg_itable_unused = - bgd[i].free_inodes; - if (bgd[i].bg_flags & EXT4_BG_INODE_UNINIT) { - put_ext4(((uint64_t) - ((uint64_t)bgd[i].inode_id * - (uint64_t)fs->blksz)), - zero_buffer, fs->blksz); - bgd[i].bg_flags = bgd[i].bg_flags & - ~EXT4_BG_INODE_UNINIT; - memcpy(fs->inode_bmaps[i], - zero_buffer, fs->blksz); - } - fs->curr_inode_no = - _get_new_inode_no(fs->inode_bmaps[i]); - if (fs->curr_inode_no == -1) - /* if block bitmap is completely fill */ - continue; - fs->curr_inode_no = fs->curr_inode_no + - (i * inodes_per_grp); - fs->first_pass_ibmap++; - bgd[i].free_inodes--; - bgd[i].bg_itable_unused--; - fs->sb->free_inodes--; - status = ext4fs_devread((lbaint_t) - bgd[i].inode_id * - fs->sect_perblk, 0, - fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[i].inode_id)) - goto fail; - goto success; - } else - debug("no inode left on block group %d\n", i); - } - goto fail; - } else { -restart: - fs->curr_inode_no++; - /* get the blockbitmap index respective to blockno */ - ibmap_idx = fs->curr_inode_no / inodes_per_grp; - if (bgd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) { - memset(zero_buffer, '\0', fs->blksz); - put_ext4(((uint64_t) ((uint64_t)bgd[ibmap_idx].inode_id * - (uint64_t)fs->blksz)), zero_buffer, - fs->blksz); - bgd[ibmap_idx].bg_flags = - bgd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT; - memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer, - fs->blksz); - } - - if (ext4fs_set_inode_bmap(fs->curr_inode_no, - fs->inode_bmaps[ibmap_idx], - ibmap_idx) != 0) { - debug("going for restart for the block no %d %u\n", - fs->curr_inode_no, ibmap_idx); - goto restart; - } - - /* journal backup */ - if (prev_inode_bitmap_index != ibmap_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t) - bgd[ibmap_idx].inode_id - * fs->sect_perblk, - 0, fs->blksz, journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[ibmap_idx].inode_id)) - goto fail; - prev_inode_bitmap_index = ibmap_idx; - } - if (bgd[ibmap_idx].bg_itable_unused != - bgd[ibmap_idx].free_inodes) - bgd[ibmap_idx].bg_itable_unused = - bgd[ibmap_idx].free_inodes; - bgd[ibmap_idx].free_inodes--; - bgd[ibmap_idx].bg_itable_unused--; - fs->sb->free_inodes--; - goto success; - } - -success: - free(journal_buffer); - free(zero_buffer); - - return fs->curr_inode_no; -fail: - free(journal_buffer); - free(zero_buffer); - - return -1; - -} - - -static void alloc_single_indirect_block(struct ext2_inode *file_inode, - unsigned int *total_remaining_blocks, - unsigned int *no_blks_reqd) -{ - short i; - short status; - long int actual_block_no; - long int si_blockno; - /* si :single indirect */ - unsigned int *si_buffer = NULL; - unsigned int *si_start_addr = NULL; - struct ext_filesystem *fs = get_fs(); - - if (*total_remaining_blocks != 0) { - si_buffer = zalloc(fs->blksz); - if (!si_buffer) { - printf("No Memory\n"); - return; - } - si_start_addr = si_buffer; - si_blockno = ext4fs_get_new_blk_no(); - if (si_blockno == -1) { - printf("no block left to assign\n"); - goto fail; - } - (*no_blks_reqd)++; - debug("SIPB %ld: %u\n", si_blockno, *total_remaining_blocks); - - status = ext4fs_devread((lbaint_t)si_blockno * fs->sect_perblk, - 0, fs->blksz, (char *)si_buffer); - memset(si_buffer, '\0', fs->blksz); - if (status == 0) - goto fail; - - for (i = 0; i < (fs->blksz / sizeof(int)); i++) { - actual_block_no = ext4fs_get_new_blk_no(); - if (actual_block_no == -1) { - printf("no block left to assign\n"); - goto fail; - } - *si_buffer = actual_block_no; - debug("SIAB %u: %u\n", *si_buffer, - *total_remaining_blocks); - - si_buffer++; - (*total_remaining_blocks)--; - if (*total_remaining_blocks == 0) - break; - } - - /* write the block to disk */ - put_ext4(((uint64_t) ((uint64_t)si_blockno * (uint64_t)fs->blksz)), - si_start_addr, fs->blksz); - file_inode->b.blocks.indir_block = si_blockno; - } -fail: - free(si_start_addr); -} - -static void alloc_double_indirect_block(struct ext2_inode *file_inode, - unsigned int *total_remaining_blocks, - unsigned int *no_blks_reqd) -{ - short i; - short j; - short status; - long int actual_block_no; - /* di:double indirect */ - long int di_blockno_parent; - long int di_blockno_child; - unsigned int *di_parent_buffer = NULL; - unsigned int *di_child_buff = NULL; - unsigned int *di_block_start_addr = NULL; - unsigned int *di_child_buff_start = NULL; - struct ext_filesystem *fs = get_fs(); - - if (*total_remaining_blocks != 0) { - /* double indirect parent block connecting to inode */ - di_blockno_parent = ext4fs_get_new_blk_no(); - if (di_blockno_parent == -1) { - printf("no block left to assign\n"); - goto fail; - } - di_parent_buffer = zalloc(fs->blksz); - if (!di_parent_buffer) - goto fail; - - di_block_start_addr = di_parent_buffer; - (*no_blks_reqd)++; - debug("DIPB %ld: %u\n", di_blockno_parent, - *total_remaining_blocks); - - status = ext4fs_devread((lbaint_t)di_blockno_parent * - fs->sect_perblk, 0, - fs->blksz, (char *)di_parent_buffer); - - if (!status) { - printf("%s: Device read error!\n", __func__); - goto fail; - } - memset(di_parent_buffer, '\0', fs->blksz); - - /* - * start:for each double indirect parent - * block create one more block - */ - for (i = 0; i < (fs->blksz / sizeof(int)); i++) { - di_blockno_child = ext4fs_get_new_blk_no(); - if (di_blockno_child == -1) { - printf("no block left to assign\n"); - goto fail; - } - di_child_buff = zalloc(fs->blksz); - if (!di_child_buff) - goto fail; - - di_child_buff_start = di_child_buff; - *di_parent_buffer = di_blockno_child; - di_parent_buffer++; - (*no_blks_reqd)++; - debug("DICB %ld: %u\n", di_blockno_child, - *total_remaining_blocks); - - status = ext4fs_devread((lbaint_t)di_blockno_child * - fs->sect_perblk, 0, - fs->blksz, - (char *)di_child_buff); - - if (!status) { - printf("%s: Device read error!\n", __func__); - goto fail; - } - memset(di_child_buff, '\0', fs->blksz); - /* filling of actual datablocks for each child */ - for (j = 0; j < (fs->blksz / sizeof(int)); j++) { - actual_block_no = ext4fs_get_new_blk_no(); - if (actual_block_no == -1) { - printf("no block left to assign\n"); - goto fail; - } - *di_child_buff = actual_block_no; - debug("DIAB %ld: %u\n", actual_block_no, - *total_remaining_blocks); - - di_child_buff++; - (*total_remaining_blocks)--; - if (*total_remaining_blocks == 0) - break; - } - /* write the block table */ - put_ext4(((uint64_t) ((uint64_t)di_blockno_child * (uint64_t)fs->blksz)), - di_child_buff_start, fs->blksz); - free(di_child_buff_start); - di_child_buff_start = NULL; - - if (*total_remaining_blocks == 0) - break; - } - put_ext4(((uint64_t) ((uint64_t)di_blockno_parent * (uint64_t)fs->blksz)), - di_block_start_addr, fs->blksz); - file_inode->b.blocks.double_indir_block = di_blockno_parent; - } -fail: - free(di_block_start_addr); -} - -static void alloc_triple_indirect_block(struct ext2_inode *file_inode, - unsigned int *total_remaining_blocks, - unsigned int *no_blks_reqd) -{ - short i; - short j; - short k; - long int actual_block_no; - /* ti: Triple Indirect */ - long int ti_gp_blockno; - long int ti_parent_blockno; - long int ti_child_blockno; - unsigned int *ti_gp_buff = NULL; - unsigned int *ti_parent_buff = NULL; - unsigned int *ti_child_buff = NULL; - unsigned int *ti_gp_buff_start_addr = NULL; - unsigned int *ti_pbuff_start_addr = NULL; - unsigned int *ti_cbuff_start_addr = NULL; - struct ext_filesystem *fs = get_fs(); - if (*total_remaining_blocks != 0) { - /* triple indirect grand parent block connecting to inode */ - ti_gp_blockno = ext4fs_get_new_blk_no(); - if (ti_gp_blockno == -1) { - printf("no block left to assign\n"); - goto fail; - } - ti_gp_buff = zalloc(fs->blksz); - if (!ti_gp_buff) - goto fail; - - ti_gp_buff_start_addr = ti_gp_buff; - (*no_blks_reqd)++; - debug("TIGPB %ld: %u\n", ti_gp_blockno, - *total_remaining_blocks); - - /* for each 4 byte grand parent entry create one more block */ - for (i = 0; i < (fs->blksz / sizeof(int)); i++) { - ti_parent_blockno = ext4fs_get_new_blk_no(); - if (ti_parent_blockno == -1) { - printf("no block left to assign\n"); - goto fail; - } - ti_parent_buff = zalloc(fs->blksz); - if (!ti_parent_buff) - goto fail; - - ti_pbuff_start_addr = ti_parent_buff; - *ti_gp_buff = ti_parent_blockno; - ti_gp_buff++; - (*no_blks_reqd)++; - debug("TIPB %ld: %u\n", ti_parent_blockno, - *total_remaining_blocks); - - /* for each 4 byte entry parent create one more block */ - for (j = 0; j < (fs->blksz / sizeof(int)); j++) { - ti_child_blockno = ext4fs_get_new_blk_no(); - if (ti_child_blockno == -1) { - printf("no block left assign\n"); - goto fail; - } - ti_child_buff = zalloc(fs->blksz); - if (!ti_child_buff) - goto fail; - - ti_cbuff_start_addr = ti_child_buff; - *ti_parent_buff = ti_child_blockno; - ti_parent_buff++; - (*no_blks_reqd)++; - debug("TICB %ld: %u\n", ti_parent_blockno, - *total_remaining_blocks); - - /* fill actual datablocks for each child */ - for (k = 0; k < (fs->blksz / sizeof(int)); - k++) { - actual_block_no = - ext4fs_get_new_blk_no(); - if (actual_block_no == -1) { - printf("no block left\n"); - goto fail; - } - *ti_child_buff = actual_block_no; - debug("TIAB %ld: %u\n", actual_block_no, - *total_remaining_blocks); - - ti_child_buff++; - (*total_remaining_blocks)--; - if (*total_remaining_blocks == 0) - break; - } - /* write the child block */ - put_ext4(((uint64_t) ((uint64_t)ti_child_blockno * - (uint64_t)fs->blksz)), - ti_cbuff_start_addr, fs->blksz); - free(ti_cbuff_start_addr); - - if (*total_remaining_blocks == 0) - break; - } - /* write the parent block */ - put_ext4(((uint64_t) ((uint64_t)ti_parent_blockno * (uint64_t)fs->blksz)), - ti_pbuff_start_addr, fs->blksz); - free(ti_pbuff_start_addr); - - if (*total_remaining_blocks == 0) - break; - } - /* write the grand parent block */ - put_ext4(((uint64_t) ((uint64_t)ti_gp_blockno * (uint64_t)fs->blksz)), - ti_gp_buff_start_addr, fs->blksz); - file_inode->b.blocks.triple_indir_block = ti_gp_blockno; - } -fail: - free(ti_gp_buff_start_addr); -} - -void ext4fs_allocate_blocks(struct ext2_inode *file_inode, - unsigned int total_remaining_blocks, - unsigned int *total_no_of_block) -{ - short i; - long int direct_blockno; - unsigned int no_blks_reqd = 0; - - /* allocation of direct blocks */ - for (i = 0; i < INDIRECT_BLOCKS; i++) { - direct_blockno = ext4fs_get_new_blk_no(); - if (direct_blockno == -1) { - printf("no block left to assign\n"); - return; - } - file_inode->b.blocks.dir_blocks[i] = direct_blockno; - debug("DB %ld: %u\n", direct_blockno, total_remaining_blocks); - - total_remaining_blocks--; - if (total_remaining_blocks == 0) - break; - } - - alloc_single_indirect_block(file_inode, &total_remaining_blocks, - &no_blks_reqd); - alloc_double_indirect_block(file_inode, &total_remaining_blocks, - &no_blks_reqd); - alloc_triple_indirect_block(file_inode, &total_remaining_blocks, - &no_blks_reqd); - *total_no_of_block += no_blks_reqd; -} - -#endif - -static struct ext4_extent_header *ext4fs_get_extent_block - (struct ext2_data *data, char *buf, - struct ext4_extent_header *ext_block, - uint32_t fileblock, int log2_blksz) -{ - struct ext4_extent_idx *index; - unsigned long long block; - int blksz = EXT2_BLOCK_SIZE(data); - int i; - - while (1) { - index = (struct ext4_extent_idx *)(ext_block + 1); - - if (le16_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC) - return 0; - - if (ext_block->eh_depth == 0) - return ext_block; - i = -1; - do { - i++; - if (i >= le16_to_cpu(ext_block->eh_entries)) - break; - } while (fileblock >= le32_to_cpu(index[i].ei_block)); - - if (--i < 0) - return 0; - - block = le16_to_cpu(index[i].ei_leaf_hi); - block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo); - - if (ext4fs_devread((lbaint_t)block << log2_blksz, 0, blksz, - buf)) - ext_block = (struct ext4_extent_header *)buf; - else - return 0; - } -} - -static int ext4fs_blockgroup - (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) -{ - long int blkno; - unsigned int blkoff, desc_per_blk; - int log2blksz = get_fs()->dev_desc->log2blksz; - - desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); - - blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + - group / desc_per_blk; - blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); - - debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n", - group, blkno, blkoff); - - return ext4fs_devread((lbaint_t)blkno << - (LOG2_BLOCK_SIZE(data) - log2blksz), - blkoff, sizeof(struct ext2_block_group), - (char *)blkgrp); -} - -int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) -{ - struct ext2_block_group blkgrp; - struct ext2_sblock *sblock = &data->sblock; - struct ext_filesystem *fs = get_fs(); - int log2blksz = get_fs()->dev_desc->log2blksz; - int inodes_per_block, status; - long int blkno; - unsigned int blkoff; - - /* It is easier to calculate if the first inode is 0. */ - ino--; - status = ext4fs_blockgroup(data, ino / __le32_to_cpu - (sblock->inodes_per_group), &blkgrp); - if (status == 0) - return 0; - - inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz; - blkno = __le32_to_cpu(blkgrp.inode_table_id) + - (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; - blkoff = (ino % inodes_per_block) * fs->inodesz; - /* Read the inode. */ - status = ext4fs_devread((lbaint_t)blkno << (LOG2_BLOCK_SIZE(data) - - log2blksz), blkoff, - sizeof(struct ext2_inode), (char *)inode); - if (status == 0) - return 0; - - return 1; -} - -long int read_allocated_block(struct ext2_inode *inode, int fileblock) -{ - long int blknr; - int blksz; - int log2_blksz; - int status; - long int rblock; - long int perblock_parent; - long int perblock_child; - unsigned long long start; - /* get the blocksize of the filesystem */ - blksz = EXT2_BLOCK_SIZE(ext4fs_root); - log2_blksz = LOG2_BLOCK_SIZE(ext4fs_root) - - get_fs()->dev_desc->log2blksz; - - if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) { - char *buf = zalloc(blksz); - if (!buf) - return -ENOMEM; - struct ext4_extent_header *ext_block; - struct ext4_extent *extent; - int i = -1; - ext_block = - ext4fs_get_extent_block(ext4fs_root, buf, - (struct ext4_extent_header *) - inode->b.blocks.dir_blocks, - fileblock, log2_blksz); - if (!ext_block) { - printf("invalid extent block\n"); - free(buf); - return -EINVAL; - } - - extent = (struct ext4_extent *)(ext_block + 1); - - do { - i++; - if (i >= le16_to_cpu(ext_block->eh_entries)) - break; - } while (fileblock >= le32_to_cpu(extent[i].ee_block)); - if (--i >= 0) { - fileblock -= le32_to_cpu(extent[i].ee_block); - if (fileblock >= le16_to_cpu(extent[i].ee_len)) { - free(buf); - return 0; - } - - start = le16_to_cpu(extent[i].ee_start_hi); - start = (start << 32) + - le32_to_cpu(extent[i].ee_start_lo); - free(buf); - return fileblock + start; - } - - printf("Extent Error\n"); - free(buf); - return -1; - } - - /* Direct blocks. */ - if (fileblock < INDIRECT_BLOCKS) - blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); - - /* Indirect. */ - else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { - if (ext4fs_indir1_block == NULL) { - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** SI ext2fs read block (indir 1)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - ext4fs_indir1_blkno = -1; - } - if (blksz != ext4fs_indir1_size) { - free(ext4fs_indir1_block); - ext4fs_indir1_block = NULL; - ext4fs_indir1_size = 0; - ext4fs_indir1_blkno = -1; - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** SI ext2fs read block (indir 1):" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - } - if ((__le32_to_cpu(inode->b.blocks.indir_block) << - log2_blksz) != ext4fs_indir1_blkno) { - status = - ext4fs_devread((lbaint_t)__le32_to_cpu - (inode->b.blocks. - indir_block) << log2_blksz, 0, - blksz, (char *)ext4fs_indir1_block); - if (status == 0) { - printf("** SI ext2fs read block (indir 1)" - "failed. **\n"); - return 0; - } - ext4fs_indir1_blkno = - __le32_to_cpu(inode->b.blocks. - indir_block) << log2_blksz; - } - blknr = __le32_to_cpu(ext4fs_indir1_block - [fileblock - INDIRECT_BLOCKS]); - } - /* Double indirect. */ - else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * - (blksz / 4 + 1)))) { - - long int perblock = blksz / 4; - long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); - - if (ext4fs_indir1_block == NULL) { - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** DI ext2fs read block (indir 2 1)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - ext4fs_indir1_blkno = -1; - } - if (blksz != ext4fs_indir1_size) { - free(ext4fs_indir1_block); - ext4fs_indir1_block = NULL; - ext4fs_indir1_size = 0; - ext4fs_indir1_blkno = -1; - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** DI ext2fs read block (indir 2 1)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - } - if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << - log2_blksz) != ext4fs_indir1_blkno) { - status = - ext4fs_devread((lbaint_t)__le32_to_cpu - (inode->b.blocks. - double_indir_block) << log2_blksz, - 0, blksz, - (char *)ext4fs_indir1_block); - if (status == 0) { - printf("** DI ext2fs read block (indir 2 1)" - "failed. **\n"); - return -1; - } - ext4fs_indir1_blkno = - __le32_to_cpu(inode->b.blocks.double_indir_block) << - log2_blksz; - } - - if (ext4fs_indir2_block == NULL) { - ext4fs_indir2_block = zalloc(blksz); - if (ext4fs_indir2_block == NULL) { - printf("** DI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir2_size = blksz; - ext4fs_indir2_blkno = -1; - } - if (blksz != ext4fs_indir2_size) { - free(ext4fs_indir2_block); - ext4fs_indir2_block = NULL; - ext4fs_indir2_size = 0; - ext4fs_indir2_blkno = -1; - ext4fs_indir2_block = zalloc(blksz); - if (ext4fs_indir2_block == NULL) { - printf("** DI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir2_size = blksz; - } - if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) << - log2_blksz) != ext4fs_indir2_blkno) { - status = ext4fs_devread((lbaint_t)__le32_to_cpu - (ext4fs_indir1_block - [rblock / - perblock]) << log2_blksz, 0, - blksz, - (char *)ext4fs_indir2_block); - if (status == 0) { - printf("** DI ext2fs read block (indir 2 2)" - "failed. **\n"); - return -1; - } - ext4fs_indir2_blkno = - __le32_to_cpu(ext4fs_indir1_block[rblock - / - perblock]) << - log2_blksz; - } - blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]); - } - /* Tripple indirect. */ - else { - rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + - (blksz / 4 * blksz / 4)); - perblock_child = blksz / 4; - perblock_parent = ((blksz / 4) * (blksz / 4)); - - if (ext4fs_indir1_block == NULL) { - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** TI ext2fs read block (indir 2 1)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - ext4fs_indir1_blkno = -1; - } - if (blksz != ext4fs_indir1_size) { - free(ext4fs_indir1_block); - ext4fs_indir1_block = NULL; - ext4fs_indir1_size = 0; - ext4fs_indir1_blkno = -1; - ext4fs_indir1_block = zalloc(blksz); - if (ext4fs_indir1_block == NULL) { - printf("** TI ext2fs read block (indir 2 1)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir1_size = blksz; - } - if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) << - log2_blksz) != ext4fs_indir1_blkno) { - status = ext4fs_devread - ((lbaint_t) - __le32_to_cpu(inode->b.blocks.triple_indir_block) - << log2_blksz, 0, blksz, - (char *)ext4fs_indir1_block); - if (status == 0) { - printf("** TI ext2fs read block (indir 2 1)" - "failed. **\n"); - return -1; - } - ext4fs_indir1_blkno = - __le32_to_cpu(inode->b.blocks.triple_indir_block) << - log2_blksz; - } - - if (ext4fs_indir2_block == NULL) { - ext4fs_indir2_block = zalloc(blksz); - if (ext4fs_indir2_block == NULL) { - printf("** TI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir2_size = blksz; - ext4fs_indir2_blkno = -1; - } - if (blksz != ext4fs_indir2_size) { - free(ext4fs_indir2_block); - ext4fs_indir2_block = NULL; - ext4fs_indir2_size = 0; - ext4fs_indir2_blkno = -1; - ext4fs_indir2_block = zalloc(blksz); - if (ext4fs_indir2_block == NULL) { - printf("** TI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir2_size = blksz; - } - if ((__le32_to_cpu(ext4fs_indir1_block[rblock / - perblock_parent]) << - log2_blksz) - != ext4fs_indir2_blkno) { - status = ext4fs_devread((lbaint_t)__le32_to_cpu - (ext4fs_indir1_block - [rblock / - perblock_parent]) << - log2_blksz, 0, blksz, - (char *)ext4fs_indir2_block); - if (status == 0) { - printf("** TI ext2fs read block (indir 2 2)" - "failed. **\n"); - return -1; - } - ext4fs_indir2_blkno = - __le32_to_cpu(ext4fs_indir1_block[rblock / - perblock_parent]) - << log2_blksz; - } - - if (ext4fs_indir3_block == NULL) { - ext4fs_indir3_block = zalloc(blksz); - if (ext4fs_indir3_block == NULL) { - printf("** TI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir3_size = blksz; - ext4fs_indir3_blkno = -1; - } - if (blksz != ext4fs_indir3_size) { - free(ext4fs_indir3_block); - ext4fs_indir3_block = NULL; - ext4fs_indir3_size = 0; - ext4fs_indir3_blkno = -1; - ext4fs_indir3_block = zalloc(blksz); - if (ext4fs_indir3_block == NULL) { - printf("** TI ext2fs read block (indir 2 2)" - "malloc failed. **\n"); - return -1; - } - ext4fs_indir3_size = blksz; - } - if ((__le32_to_cpu(ext4fs_indir2_block[rblock - / - perblock_child]) << - log2_blksz) != ext4fs_indir3_blkno) { - status = - ext4fs_devread((lbaint_t)__le32_to_cpu - (ext4fs_indir2_block - [(rblock / perblock_child) - % (blksz / 4)]) << log2_blksz, 0, - blksz, (char *)ext4fs_indir3_block); - if (status == 0) { - printf("** TI ext2fs read block (indir 2 2)" - "failed. **\n"); - return -1; - } - ext4fs_indir3_blkno = - __le32_to_cpu(ext4fs_indir2_block[(rblock / - perblock_child) % - (blksz / - 4)]) << - log2_blksz; - } - - blknr = __le32_to_cpu(ext4fs_indir3_block - [rblock % perblock_child]); - } - debug("read_allocated_block %ld\n", blknr); - - return blknr; -} - -/** - * ext4fs_reinit_global() - Reinitialize values of ext4 write implementation's - * global pointers - * - * This function assures that for a file with the same name but different size - * the sequential store on the ext4 filesystem will be correct. - * - * In this function the global data, responsible for internal representation - * of the ext4 data are initialized to the reset state. Without this, during - * replacement of the smaller file with the bigger truncation of new file was - * performed. - */ -void ext4fs_reinit_global(void) -{ - if (ext4fs_indir1_block != NULL) { - free(ext4fs_indir1_block); - ext4fs_indir1_block = NULL; - ext4fs_indir1_size = 0; - ext4fs_indir1_blkno = -1; - } - if (ext4fs_indir2_block != NULL) { - free(ext4fs_indir2_block); - ext4fs_indir2_block = NULL; - ext4fs_indir2_size = 0; - ext4fs_indir2_blkno = -1; - } - if (ext4fs_indir3_block != NULL) { - free(ext4fs_indir3_block); - ext4fs_indir3_block = NULL; - ext4fs_indir3_size = 0; - ext4fs_indir3_blkno = -1; - } -} -void ext4fs_close(void) -{ - if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) { - ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen); - ext4fs_file = NULL; - } - if (ext4fs_root != NULL) { - free(ext4fs_root); - ext4fs_root = NULL; - } - - ext4fs_reinit_global(); -} - -int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, - struct ext2fs_node **fnode, int *ftype) -{ - unsigned int fpos = 0; - int status; - struct ext2fs_node *diro = (struct ext2fs_node *) dir; - -#ifdef DEBUG - if (name != NULL) - printf("Iterate dir %s\n", name); -#endif /* of DEBUG */ - if (!diro->inode_read) { - status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); - if (status == 0) - return 0; - } - /* Search the file. */ - while (fpos < __le32_to_cpu(diro->inode.size)) { - struct ext2_dirent dirent; - - status = ext4fs_read_file(diro, fpos, - sizeof(struct ext2_dirent), - (char *) &dirent); - if (status < 1) - return 0; - - if (dirent.namelen != 0) { - char filename[dirent.namelen + 1]; - struct ext2fs_node *fdiro; - int type = FILETYPE_UNKNOWN; - - status = ext4fs_read_file(diro, - fpos + - sizeof(struct ext2_dirent), - dirent.namelen, filename); - if (status < 1) - return 0; - - fdiro = zalloc(sizeof(struct ext2fs_node)); - if (!fdiro) - return 0; - - fdiro->data = diro->data; - fdiro->ino = __le32_to_cpu(dirent.inode); - - filename[dirent.namelen] = '\0'; - - if (dirent.filetype != FILETYPE_UNKNOWN) { - fdiro->inode_read = 0; - - if (dirent.filetype == FILETYPE_DIRECTORY) - type = FILETYPE_DIRECTORY; - else if (dirent.filetype == FILETYPE_SYMLINK) - type = FILETYPE_SYMLINK; - else if (dirent.filetype == FILETYPE_REG) - type = FILETYPE_REG; - } else { - status = ext4fs_read_inode(diro->data, - __le32_to_cpu - (dirent.inode), - &fdiro->inode); - if (status == 0) { - free(fdiro); - return 0; - } - fdiro->inode_read = 1; - - if ((__le16_to_cpu(fdiro->inode.mode) & - FILETYPE_INO_MASK) == - FILETYPE_INO_DIRECTORY) { - type = FILETYPE_DIRECTORY; - } else if ((__le16_to_cpu(fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_SYMLINK) { - type = FILETYPE_SYMLINK; - } else if ((__le16_to_cpu(fdiro->inode.mode) - & FILETYPE_INO_MASK) == - FILETYPE_INO_REG) { - type = FILETYPE_REG; - } - } -#ifdef DEBUG - printf("iterate >%s<\n", filename); -#endif /* of DEBUG */ - if ((name != NULL) && (fnode != NULL) - && (ftype != NULL)) { - if (strcmp(filename, name) == 0) { - *ftype = type; - *fnode = fdiro; - return 1; - } - } else { - if (fdiro->inode_read == 0) { - status = ext4fs_read_inode(diro->data, - __le32_to_cpu( - dirent.inode), - &fdiro->inode); - if (status == 0) { - free(fdiro); - return 0; - } - fdiro->inode_read = 1; - } - switch (type) { - case FILETYPE_DIRECTORY: - printf("<DIR> "); - break; - case FILETYPE_SYMLINK: - printf("<SYM> "); - break; - case FILETYPE_REG: - printf(" "); - break; - default: - printf("< ? > "); - break; - } - printf("%10d %s\n", - __le32_to_cpu(fdiro->inode.size), - filename); - } - free(fdiro); - } - fpos += __le16_to_cpu(dirent.direntlen); - } - return 0; -} - -static char *ext4fs_read_symlink(struct ext2fs_node *node) -{ - char *symlink; - struct ext2fs_node *diro = node; - int status; - - if (!diro->inode_read) { - status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); - if (status == 0) - return 0; - } - symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); - if (!symlink) - return 0; - - if (__le32_to_cpu(diro->inode.size) <= 60) { - strncpy(symlink, diro->inode.b.symlink, - __le32_to_cpu(diro->inode.size)); - } else { - status = ext4fs_read_file(diro, 0, - __le32_to_cpu(diro->inode.size), - symlink); - if (status == 0) { - free(symlink); - return 0; - } - } - symlink[__le32_to_cpu(diro->inode.size)] = '\0'; - return symlink; -} - -static int ext4fs_find_file1(const char *currpath, - struct ext2fs_node *currroot, - struct ext2fs_node **currfound, int *foundtype) -{ - char fpath[strlen(currpath) + 1]; - char *name = fpath; - char *next; - int status; - int type = FILETYPE_DIRECTORY; - struct ext2fs_node *currnode = currroot; - struct ext2fs_node *oldnode = currroot; - - strncpy(fpath, currpath, strlen(currpath) + 1); - - /* Remove all leading slashes. */ - while (*name == '/') - name++; - - if (!*name) { - *currfound = currnode; - return 1; - } - - for (;;) { - int found; - - /* Extract the actual part from the pathname. */ - next = strchr(name, '/'); - if (next) { - /* Remove all leading slashes. */ - while (*next == '/') - *(next++) = '\0'; - } - - if (type != FILETYPE_DIRECTORY) { - ext4fs_free_node(currnode, currroot); - return 0; - } - - oldnode = currnode; - - /* Iterate over the directory. */ - found = ext4fs_iterate_dir(currnode, name, &currnode, &type); - if (found == 0) - return 0; - - if (found == -1) - break; - - /* Read in the symlink and follow it. */ - if (type == FILETYPE_SYMLINK) { - char *symlink; - - /* Test if the symlink does not loop. */ - if (++symlinknest == 8) { - ext4fs_free_node(currnode, currroot); - ext4fs_free_node(oldnode, currroot); - return 0; - } - - symlink = ext4fs_read_symlink(currnode); - ext4fs_free_node(currnode, currroot); - - if (!symlink) { - ext4fs_free_node(oldnode, currroot); - return 0; - } - - debug("Got symlink >%s<\n", symlink); - - if (symlink[0] == '/') { - ext4fs_free_node(oldnode, currroot); - oldnode = &ext4fs_root->diropen; - } - - /* Lookup the node the symlink points to. */ - status = ext4fs_find_file1(symlink, oldnode, - &currnode, &type); - - free(symlink); - - if (status == 0) { - ext4fs_free_node(oldnode, currroot); - return 0; - } - } - - ext4fs_free_node(oldnode, currroot); - - /* Found the node! */ - if (!next || *next == '\0') { - *currfound = currnode; - *foundtype = type; - return 1; - } - name = next; - } - return -1; -} - -int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, - struct ext2fs_node **foundnode, int expecttype) -{ - int status; - int foundtype = FILETYPE_DIRECTORY; - - symlinknest = 0; - if (!path) - return 0; - - status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype); - if (status == 0) - return 0; - - /* Check if the node that was found was of the expected type. */ - if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) - return 0; - else if ((expecttype == FILETYPE_DIRECTORY) - && (foundtype != expecttype)) - return 0; - - return 1; -} - -int ext4fs_open(const char *filename) -{ - struct ext2fs_node *fdiro = NULL; - int status; - int len; - - if (ext4fs_root == NULL) - return -1; - - ext4fs_file = NULL; - status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro, - FILETYPE_REG); - if (status == 0) - goto fail; - - if (!fdiro->inode_read) { - status = ext4fs_read_inode(fdiro->data, fdiro->ino, - &fdiro->inode); - if (status == 0) - goto fail; - } - len = __le32_to_cpu(fdiro->inode.size); - ext4fs_file = fdiro; - - return len; -fail: - ext4fs_free_node(fdiro, &ext4fs_root->diropen); - - return -1; -} - -int ext4fs_mount(unsigned part_length) -{ - struct ext2_data *data; - int status; - struct ext_filesystem *fs = get_fs(); - data = zalloc(SUPERBLOCK_SIZE); - if (!data) - return 0; - - /* Read the superblock. */ - status = ext4_read_superblock((char *)&data->sblock); - - if (status == 0) - goto fail; - - /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) - goto fail; - - if (__le32_to_cpu(data->sblock.revision_level == 0)) - fs->inodesz = 128; - else - fs->inodesz = __le16_to_cpu(data->sblock.inode_size); - - debug("EXT2 rev %d, inode_size %d\n", - __le32_to_cpu(data->sblock.revision_level), fs->inodesz); - - data->diropen.data = data; - data->diropen.ino = 2; - data->diropen.inode_read = 1; - data->inode = &data->diropen.inode; - - status = ext4fs_read_inode(data, 2, data->inode); - if (status == 0) - goto fail; - - ext4fs_root = data; - - return 1; -fail: - printf("Failed to mount ext2 filesystem...\n"); - free(data); - ext4fs_root = NULL; - - return 0; -} diff --git a/qemu/roms/u-boot/fs/ext4/ext4_common.h b/qemu/roms/u-boot/fs/ext4/ext4_common.h deleted file mode 100644 index 5fa1719f2..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4_common.h +++ /dev/null @@ -1,78 +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> - * - * ext4ls and ext4load : based on ext2 ls load support in Uboot. - * - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * ext4write : Based on generic ext4 protocol. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __EXT4_COMMON__ -#define __EXT4_COMMON__ -#include <ext_common.h> -#include <ext4fs.h> -#include <malloc.h> -#include <asm/errno.h> -#if defined(CONFIG_EXT4_WRITE) -#include "ext4_journal.h" -#include "crc16.h" -#endif - -#define YES 1 -#define NO 0 -#define RECOVER 1 -#define SCAN 0 - -#define S_IFLNK 0120000 /* symbolic link */ -#define BLOCK_NO_ONE 1 -#define SUPERBLOCK_START (2 * 512) -#define SUPERBLOCK_SIZE 1024 -#define F_FILE 1 - -static inline void *zalloc(size_t size) -{ - void *p = memalign(ARCH_DMA_MINALIGN, size); - memset(p, 0, size); - return p; -} - -int ext4fs_read_inode(struct ext2_data *data, int ino, - struct ext2_inode *inode); -int ext4fs_read_file(struct ext2fs_node *node, int pos, - unsigned int len, char *buf); -int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, - struct ext2fs_node **foundnode, int expecttype); -int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, - struct ext2fs_node **fnode, int *ftype); - -#if defined(CONFIG_EXT4_WRITE) -uint32_t ext4fs_div_roundup(uint32_t size, uint32_t n); -int ext4fs_checksum_update(unsigned int i); -int ext4fs_get_parent_inode_num(const char *dirname, char *dname, int flags); -void ext4fs_update_parent_dentry(char *filename, int *p_ino, int file_type); -long int ext4fs_get_new_blk_no(void); -int ext4fs_get_new_inode_no(void); -void ext4fs_reset_block_bmap(long int blockno, unsigned char *buffer, - int index); -int ext4fs_set_block_bmap(long int blockno, unsigned char *buffer, int index); -int ext4fs_set_inode_bmap(int inode_no, unsigned char *buffer, int index); -void ext4fs_reset_inode_bmap(int inode_no, unsigned char *buffer, int index); -int ext4fs_iget(int inode_no, struct ext2_inode *inode); -void ext4fs_allocate_blocks(struct ext2_inode *file_inode, - unsigned int total_remaining_blocks, - unsigned int *total_no_of_block); -void put_ext4(uint64_t off, void *buf, uint32_t size); -#endif -#endif 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"); -} diff --git a/qemu/roms/u-boot/fs/ext4/ext4_journal.h b/qemu/roms/u-boot/fs/ext4/ext4_journal.h deleted file mode 100644 index d926094be..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4_journal.h +++ /dev/null @@ -1,125 +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+ - */ - -#ifndef __EXT4_JRNL__ -#define __EXT4_JRNL__ - -#define EXT2_JOURNAL_INO 8 /* Journal inode */ -#define EXT2_JOURNAL_SUPERBLOCK 0 /* Journal Superblock number */ - -#define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 -#define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U -#define TRANSACTION_RUNNING 1 -#define TRANSACTION_COMPLETE 0 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ -#define EXT3_JOURNAL_DESCRIPTOR_BLOCK 1 -#define EXT3_JOURNAL_COMMIT_BLOCK 2 -#define EXT3_JOURNAL_SUPERBLOCK_V1 3 -#define EXT3_JOURNAL_SUPERBLOCK_V2 4 -#define EXT3_JOURNAL_REVOKE_BLOCK 5 -#define EXT3_JOURNAL_FLAG_ESCAPE 1 -#define EXT3_JOURNAL_FLAG_SAME_UUID 2 -#define EXT3_JOURNAL_FLAG_DELETED 4 -#define EXT3_JOURNAL_FLAG_LAST_TAG 8 - -/* Maximum entries in 1 journal transaction */ -#define MAX_JOURNAL_ENTRIES 100 -struct journal_log { - char *buf; - int blknr; -}; - -struct dirty_blocks { - char *buf; - int blknr; -}; - -/* Standard header for all descriptor blocks: */ -struct journal_header_t { - __u32 h_magic; - __u32 h_blocktype; - __u32 h_sequence; -}; - -/* The journal superblock. All fields are in big-endian byte order. */ -struct journal_superblock_t { - /* 0x0000 */ - struct journal_header_t s_header; - - /* Static information describing the journal */ - __u32 s_blocksize; /* journal device blocksize */ - __u32 s_maxlen; /* total blocks in journal file */ - __u32 s_first; /* first block of log information */ - - /* Dynamic information describing the current state of the log */ - __u32 s_sequence; /* first commit ID expected in log */ - __u32 s_start; /* blocknr of start of log */ - - /* Error value, as set by journal_abort(). */ - __s32 s_errno; - - /* Remaining fields are only valid in a version-2 superblock */ - __u32 s_feature_compat; /* compatible feature set */ - __u32 s_feature_incompat; /* incompatible feature set */ - __u32 s_feature_ro_compat; /* readonly-compatible feature set */ - /* 0x0030 */ - __u8 s_uuid[16]; /* 128-bit uuid for journal */ - - /* 0x0040 */ - __u32 s_nr_users; /* Nr of filesystems sharing log */ - - __u32 s_dynsuper; /* Blocknr of dynamic superblock copy */ - - /* 0x0048 */ - __u32 s_max_transaction; /* Limit of journal blocks per trans. */ - __u32 s_max_trans_data; /* Limit of data blocks per trans. */ - - /* 0x0050 */ - __u32 s_padding[44]; - - /* 0x0100 */ - __u8 s_users[16 * 48]; /* ids of all fs'es sharing the log */ - /* 0x0400 */ -} ; - -struct ext3_journal_block_tag { - uint32_t block; - uint32_t flags; -}; - -struct journal_revoke_header_t { - struct journal_header_t r_header; - int r_count; /* Count of bytes used in the block */ -}; - -struct revoke_blk_list { - char *content; /* revoke block itself */ - struct revoke_blk_list *next; -}; - -extern struct ext2_data *ext4fs_root; - -int ext4fs_init_journal(void); -int ext4fs_log_gdt(char *gd_table); -int ext4fs_check_journal_state(int recovery_flag); -int ext4fs_log_journal(char *journal_buffer, long int blknr); -int ext4fs_put_metadata(char *metadata_buffer, long int blknr); -void ext4fs_update_journal(void); -void ext4fs_dump_metadata(void); -void ext4fs_push_revoke_blk(char *buffer); -void ext4fs_free_journal(void); -void ext4fs_free_revoke_blks(void); -#endif diff --git a/qemu/roms/u-boot/fs/ext4/ext4_write.c b/qemu/roms/u-boot/fs/ext4/ext4_write.c deleted file mode 100644 index c42add9a7..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4_write.c +++ /dev/null @@ -1,977 +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> - * - * ext4ls and ext4load : Based on ext2 ls and load support in Uboot. - * Ext4 read optimization taken from Open-Moko - * Qi bootloader - * - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * ext4write : Based on generic ext4 protocol. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - - -#include <common.h> -#include <linux/stat.h> -#include <div64.h> -#include "ext4_common.h" - -static void ext4fs_update(void) -{ - short i; - ext4fs_update_journal(); - struct ext_filesystem *fs = get_fs(); - - /* update super block */ - put_ext4((uint64_t)(SUPERBLOCK_SIZE), - (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); - - /* update block groups */ - for (i = 0; i < fs->no_blkgrp; i++) { - fs->bgd[i].bg_checksum = ext4fs_checksum_update(i); - put_ext4((uint64_t)((uint64_t)fs->bgd[i].block_id * (uint64_t)fs->blksz), - fs->blk_bmaps[i], fs->blksz); - } - - /* update inode table groups */ - for (i = 0; i < fs->no_blkgrp; i++) { - put_ext4((uint64_t) ((uint64_t)fs->bgd[i].inode_id * (uint64_t)fs->blksz), - fs->inode_bmaps[i], fs->blksz); - } - - /* update the block group descriptor table */ - put_ext4((uint64_t)((uint64_t)fs->gdtable_blkno * (uint64_t)fs->blksz), - (struct ext2_block_group *)fs->gdtable, - (fs->blksz * fs->no_blk_pergdt)); - - ext4fs_dump_metadata(); - - gindex = 0; - gd_index = 0; -} - -int ext4fs_get_bgdtable(void) -{ - int status; - int grp_desc_size; - struct ext_filesystem *fs = get_fs(); - grp_desc_size = sizeof(struct ext2_block_group); - fs->no_blk_pergdt = (fs->no_blkgrp * grp_desc_size) / fs->blksz; - if ((fs->no_blkgrp * grp_desc_size) % fs->blksz) - fs->no_blk_pergdt++; - - /* allocate memory for gdtable */ - fs->gdtable = zalloc(fs->blksz * fs->no_blk_pergdt); - if (!fs->gdtable) - return -ENOMEM; - /* read the group descriptor table */ - status = ext4fs_devread((lbaint_t)fs->gdtable_blkno * fs->sect_perblk, - 0, fs->blksz * fs->no_blk_pergdt, fs->gdtable); - if (status == 0) - goto fail; - - if (ext4fs_log_gdt(fs->gdtable)) { - printf("Error in ext4fs_log_gdt\n"); - return -1; - } - - return 0; -fail: - free(fs->gdtable); - fs->gdtable = NULL; - - return -1; -} - -static void delete_single_indirect_block(struct ext2_inode *inode) -{ - struct ext2_block_group *bgd = NULL; - static int prev_bg_bmap_idx = -1; - long int blknr; - int remainder; - int bg_idx; - int status; - unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - if (!journal_buffer) { - printf("No memory\n"); - return; - } - /* get block group descriptor table */ - bgd = (struct ext2_block_group *)fs->gdtable; - - /* deleting the single indirect block associated with inode */ - if (inode->b.blocks.indir_block != 0) { - debug("SIPB releasing %u\n", inode->b.blocks.indir_block); - blknr = inode->b.blocks.indir_block; - bg_idx = blknr / blk_per_grp; - if (fs->blksz == 1024) { - remainder = blknr % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - status = - ext4fs_devread((lbaint_t)bgd[bg_idx].block_id * - fs->sect_perblk, 0, fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal - (journal_buffer, bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } -fail: - free(journal_buffer); -} - -static void delete_double_indirect_block(struct ext2_inode *inode) -{ - int i; - short status; - static int prev_bg_bmap_idx = -1; - long int blknr; - int remainder; - int bg_idx; - unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; - unsigned int *di_buffer = NULL; - unsigned int *DIB_start_addr = NULL; - struct ext2_block_group *bgd = NULL; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - if (!journal_buffer) { - printf("No memory\n"); - return; - } - /* get the block group descriptor table */ - bgd = (struct ext2_block_group *)fs->gdtable; - - if (inode->b.blocks.double_indir_block != 0) { - di_buffer = zalloc(fs->blksz); - if (!di_buffer) { - printf("No memory\n"); - return; - } - DIB_start_addr = (unsigned int *)di_buffer; - blknr = inode->b.blocks.double_indir_block; - status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, - fs->blksz, (char *)di_buffer); - for (i = 0; i < fs->blksz / sizeof(int); i++) { - if (*di_buffer == 0) - break; - - debug("DICB releasing %u\n", *di_buffer); - bg_idx = *di_buffer / blk_per_grp; - if (fs->blksz == 1024) { - remainder = *di_buffer % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(*di_buffer, - fs->blk_bmaps[bg_idx], bg_idx); - di_buffer++; - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - status = ext4fs_devread((lbaint_t) - bgd[bg_idx].block_id - * fs->sect_perblk, 0, - fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } - - /* removing the parent double indirect block */ - blknr = inode->b.blocks.double_indir_block; - bg_idx = blknr / blk_per_grp; - if (fs->blksz == 1024) { - remainder = blknr % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id * - fs->sect_perblk, 0, fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - debug("DIPB releasing %ld\n", blknr); - } -fail: - free(DIB_start_addr); - free(journal_buffer); -} - -static void delete_triple_indirect_block(struct ext2_inode *inode) -{ - int i, j; - short status; - static int prev_bg_bmap_idx = -1; - long int blknr; - int remainder; - int bg_idx; - unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; - unsigned int *tigp_buffer = NULL; - unsigned int *tib_start_addr = NULL; - unsigned int *tip_buffer = NULL; - unsigned int *tipb_start_addr = NULL; - struct ext2_block_group *bgd = NULL; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - if (!journal_buffer) { - printf("No memory\n"); - return; - } - /* get block group descriptor table */ - bgd = (struct ext2_block_group *)fs->gdtable; - - if (inode->b.blocks.triple_indir_block != 0) { - tigp_buffer = zalloc(fs->blksz); - if (!tigp_buffer) { - printf("No memory\n"); - return; - } - tib_start_addr = (unsigned int *)tigp_buffer; - blknr = inode->b.blocks.triple_indir_block; - status = ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, - fs->blksz, (char *)tigp_buffer); - for (i = 0; i < fs->blksz / sizeof(int); i++) { - if (*tigp_buffer == 0) - break; - debug("tigp buffer releasing %u\n", *tigp_buffer); - - tip_buffer = zalloc(fs->blksz); - if (!tip_buffer) - goto fail; - tipb_start_addr = (unsigned int *)tip_buffer; - status = ext4fs_devread((lbaint_t)(*tigp_buffer) * - fs->sect_perblk, 0, fs->blksz, - (char *)tip_buffer); - for (j = 0; j < fs->blksz / sizeof(int); j++) { - if (*tip_buffer == 0) - break; - bg_idx = *tip_buffer / blk_per_grp; - if (fs->blksz == 1024) { - remainder = *tip_buffer % blk_per_grp; - if (!remainder) - bg_idx--; - } - - ext4fs_reset_block_bmap(*tip_buffer, - fs->blk_bmaps[bg_idx], - bg_idx); - - tip_buffer++; - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - status = - ext4fs_devread( - (lbaint_t) - bgd[bg_idx].block_id * - fs->sect_perblk, 0, - fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx]. - block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } - free(tipb_start_addr); - tipb_start_addr = NULL; - - /* - * removing the grand parent blocks - * which is connected to inode - */ - bg_idx = *tigp_buffer / blk_per_grp; - if (fs->blksz == 1024) { - remainder = *tigp_buffer % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(*tigp_buffer, - fs->blk_bmaps[bg_idx], bg_idx); - - tigp_buffer++; - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = - ext4fs_devread((lbaint_t) - bgd[bg_idx].block_id * - fs->sect_perblk, 0, - fs->blksz, journal_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } - - /* removing the grand parent triple indirect block */ - blknr = inode->b.blocks.triple_indir_block; - bg_idx = blknr / blk_per_grp; - if (fs->blksz == 1024) { - remainder = blknr % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx); - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t)bgd[bg_idx].block_id * - fs->sect_perblk, 0, fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - debug("tigp buffer itself releasing %ld\n", blknr); - } -fail: - free(tib_start_addr); - free(tipb_start_addr); - free(journal_buffer); -} - -static int ext4fs_delete_file(int inodeno) -{ - struct ext2_inode inode; - short status; - int i; - int remainder; - long int blknr; - int bg_idx; - int ibmap_idx; - char *read_buffer = NULL; - char *start_block_address = NULL; - unsigned int no_blocks; - - static int prev_bg_bmap_idx = -1; - unsigned int inodes_per_block; - long int blkno; - unsigned int blkoff; - unsigned int blk_per_grp = ext4fs_root->sblock.blocks_per_group; - unsigned int inode_per_grp = ext4fs_root->sblock.inodes_per_group; - struct ext2_inode *inode_buffer = NULL; - struct ext2_block_group *bgd = NULL; - struct ext_filesystem *fs = get_fs(); - char *journal_buffer = zalloc(fs->blksz); - if (!journal_buffer) - return -ENOMEM; - /* get the block group descriptor table */ - bgd = (struct ext2_block_group *)fs->gdtable; - status = ext4fs_read_inode(ext4fs_root, inodeno, &inode); - if (status == 0) - goto fail; - - /* read the block no allocated to a file */ - no_blocks = inode.size / fs->blksz; - if (inode.size % fs->blksz) - no_blocks++; - - if (le32_to_cpu(inode.flags) & EXT4_EXTENTS_FL) { - struct ext2fs_node *node_inode = - zalloc(sizeof(struct ext2fs_node)); - if (!node_inode) - goto fail; - node_inode->data = ext4fs_root; - node_inode->ino = inodeno; - node_inode->inode_read = 0; - memcpy(&(node_inode->inode), &inode, sizeof(struct ext2_inode)); - - for (i = 0; i < no_blocks; i++) { - blknr = read_allocated_block(&(node_inode->inode), i); - bg_idx = blknr / blk_per_grp; - if (fs->blksz == 1024) { - remainder = blknr % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], - bg_idx); - debug("EXT4_EXTENTS Block releasing %ld: %d\n", - blknr, bg_idx); - - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - status = - ext4fs_devread((lbaint_t) - bgd[bg_idx].block_id * - fs->sect_perblk, 0, - fs->blksz, journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } - if (node_inode) { - free(node_inode); - node_inode = NULL; - } - } else { - - delete_single_indirect_block(&inode); - delete_double_indirect_block(&inode); - delete_triple_indirect_block(&inode); - - /* read the block no allocated to a file */ - no_blocks = inode.size / fs->blksz; - if (inode.size % fs->blksz) - no_blocks++; - for (i = 0; i < no_blocks; i++) { - blknr = read_allocated_block(&inode, i); - bg_idx = blknr / blk_per_grp; - if (fs->blksz == 1024) { - remainder = blknr % blk_per_grp; - if (!remainder) - bg_idx--; - } - ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], - bg_idx); - debug("ActualB releasing %ld: %d\n", blknr, bg_idx); - - bgd[bg_idx].free_blocks++; - fs->sb->free_blocks++; - /* journal backup */ - if (prev_bg_bmap_idx != bg_idx) { - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t) - bgd[bg_idx].block_id - * fs->sect_perblk, - 0, fs->blksz, - journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, - bgd[bg_idx].block_id)) - goto fail; - prev_bg_bmap_idx = bg_idx; - } - } - } - - /* from the inode no to blockno */ - inodes_per_block = fs->blksz / fs->inodesz; - ibmap_idx = inodeno / inode_per_grp; - - /* get the block no */ - inodeno--; - blkno = __le32_to_cpu(bgd[ibmap_idx].inode_table_id) + - (inodeno % __le32_to_cpu(inode_per_grp)) / inodes_per_block; - - /* get the offset of the inode */ - blkoff = ((inodeno) % inodes_per_block) * fs->inodesz; - - /* read the block no containing the inode */ - read_buffer = zalloc(fs->blksz); - if (!read_buffer) - goto fail; - start_block_address = read_buffer; - status = ext4fs_devread((lbaint_t)blkno * fs->sect_perblk, - 0, fs->blksz, read_buffer); - if (status == 0) - goto fail; - - if (ext4fs_log_journal(read_buffer, blkno)) - goto fail; - - read_buffer = read_buffer + blkoff; - inode_buffer = (struct ext2_inode *)read_buffer; - memset(inode_buffer, '\0', sizeof(struct ext2_inode)); - - /* write the inode to original position in inode table */ - if (ext4fs_put_metadata(start_block_address, blkno)) - goto fail; - - /* update the respective inode bitmaps */ - inodeno++; - ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx); - bgd[ibmap_idx].free_inodes++; - fs->sb->free_inodes++; - /* journal backup */ - memset(journal_buffer, '\0', fs->blksz); - status = ext4fs_devread((lbaint_t)bgd[ibmap_idx].inode_id * - fs->sect_perblk, 0, fs->blksz, journal_buffer); - if (status == 0) - goto fail; - if (ext4fs_log_journal(journal_buffer, bgd[ibmap_idx].inode_id)) - goto fail; - - ext4fs_update(); - ext4fs_deinit(); - ext4fs_reinit_global(); - - if (ext4fs_init() != 0) { - printf("error in File System init\n"); - goto fail; - } - - free(start_block_address); - free(journal_buffer); - - return 0; -fail: - free(start_block_address); - free(journal_buffer); - - return -1; -} - -int ext4fs_init(void) -{ - short status; - int i; - unsigned int real_free_blocks = 0; - struct ext_filesystem *fs = get_fs(); - - /* populate fs */ - fs->blksz = EXT2_BLOCK_SIZE(ext4fs_root); - fs->inodesz = INODE_SIZE_FILESYSTEM(ext4fs_root); - fs->sect_perblk = fs->blksz >> fs->dev_desc->log2blksz; - - /* get the superblock */ - fs->sb = zalloc(SUPERBLOCK_SIZE); - if (!fs->sb) - return -ENOMEM; - if (!ext4_read_superblock((char *)fs->sb)) - goto fail; - - /* init journal */ - if (ext4fs_init_journal()) - goto fail; - - /* get total no of blockgroups */ - fs->no_blkgrp = (uint32_t)ext4fs_div_roundup( - (ext4fs_root->sblock.total_blocks - - ext4fs_root->sblock.first_data_block), - ext4fs_root->sblock.blocks_per_group); - - /* get the block group descriptor table */ - fs->gdtable_blkno = ((EXT2_MIN_BLOCK_SIZE == fs->blksz) + 1); - if (ext4fs_get_bgdtable() == -1) { - printf("Error in getting the block group descriptor table\n"); - goto fail; - } - fs->bgd = (struct ext2_block_group *)fs->gdtable; - - /* load all the available bitmap block of the partition */ - fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *)); - if (!fs->blk_bmaps) - goto fail; - for (i = 0; i < fs->no_blkgrp; i++) { - fs->blk_bmaps[i] = zalloc(fs->blksz); - if (!fs->blk_bmaps[i]) - goto fail; - } - - for (i = 0; i < fs->no_blkgrp; i++) { - status = - ext4fs_devread((lbaint_t)fs->bgd[i].block_id * - fs->sect_perblk, 0, - fs->blksz, (char *)fs->blk_bmaps[i]); - if (status == 0) - goto fail; - } - - /* load all the available inode bitmap of the partition */ - fs->inode_bmaps = zalloc(fs->no_blkgrp * sizeof(unsigned char *)); - if (!fs->inode_bmaps) - goto fail; - for (i = 0; i < fs->no_blkgrp; i++) { - fs->inode_bmaps[i] = zalloc(fs->blksz); - if (!fs->inode_bmaps[i]) - goto fail; - } - - for (i = 0; i < fs->no_blkgrp; i++) { - status = ext4fs_devread((lbaint_t)fs->bgd[i].inode_id * - fs->sect_perblk, - 0, fs->blksz, - (char *)fs->inode_bmaps[i]); - if (status == 0) - goto fail; - } - - /* - * check filesystem consistency with free blocks of file system - * some time we observed that superblock freeblocks does not match - * with the blockgroups freeblocks when improper - * reboot of a linux kernel - */ - for (i = 0; i < fs->no_blkgrp; i++) - real_free_blocks = real_free_blocks + fs->bgd[i].free_blocks; - if (real_free_blocks != fs->sb->free_blocks) - fs->sb->free_blocks = real_free_blocks; - - return 0; -fail: - ext4fs_deinit(); - - return -1; -} - -void ext4fs_deinit(void) -{ - int i; - struct ext2_inode inode_journal; - struct journal_superblock_t *jsb; - long int blknr; - struct ext_filesystem *fs = get_fs(); - - /* free journal */ - char *temp_buff = zalloc(fs->blksz); - if (temp_buff) { - 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; - jsb->s_start = cpu_to_be32(0); - put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), - (struct journal_superblock_t *)temp_buff, fs->blksz); - free(temp_buff); - } - ext4fs_free_journal(); - - /* get the superblock */ - ext4_read_superblock((char *)fs->sb); - fs->sb->feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; - put_ext4((uint64_t)(SUPERBLOCK_SIZE), - (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE); - free(fs->sb); - fs->sb = NULL; - - if (fs->blk_bmaps) { - for (i = 0; i < fs->no_blkgrp; i++) { - free(fs->blk_bmaps[i]); - fs->blk_bmaps[i] = NULL; - } - free(fs->blk_bmaps); - fs->blk_bmaps = NULL; - } - - if (fs->inode_bmaps) { - for (i = 0; i < fs->no_blkgrp; i++) { - free(fs->inode_bmaps[i]); - fs->inode_bmaps[i] = NULL; - } - free(fs->inode_bmaps); - fs->inode_bmaps = NULL; - } - - - free(fs->gdtable); - fs->gdtable = NULL; - fs->bgd = NULL; - /* - * reinitiliazed the global inode and - * block bitmap first execution check variables - */ - fs->first_pass_ibmap = 0; - fs->first_pass_bbmap = 0; - fs->curr_inode_no = 0; - fs->curr_blkno = 0; -} - -static int ext4fs_write_file(struct ext2_inode *file_inode, - int pos, unsigned int len, char *buf) -{ - int i; - int blockcnt; - unsigned int filesize = __le32_to_cpu(file_inode->size); - struct ext_filesystem *fs = get_fs(); - int log2blksz = fs->dev_desc->log2blksz; - int log2_fs_blocksize = LOG2_BLOCK_SIZE(ext4fs_root) - log2blksz; - int previous_block_number = -1; - int delayed_start = 0; - int delayed_extent = 0; - int delayed_next = 0; - char *delayed_buf = NULL; - - /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) - len = filesize; - - blockcnt = ((len + pos) + fs->blksz - 1) / fs->blksz; - - for (i = pos / fs->blksz; i < blockcnt; i++) { - long int blknr; - int blockend = fs->blksz; - int skipfirst = 0; - blknr = read_allocated_block(file_inode, i); - if (blknr < 0) - return -1; - - blknr = blknr << log2_fs_blocksize; - - if (blknr) { - if (previous_block_number != -1) { - if (delayed_next == blknr) { - delayed_extent += blockend; - delayed_next += blockend >> log2blksz; - } else { /* spill */ - put_ext4((uint64_t) - ((uint64_t)delayed_start << log2blksz), - delayed_buf, - (uint32_t) delayed_extent); - previous_block_number = blknr; - delayed_start = blknr; - delayed_extent = blockend; - delayed_buf = buf; - delayed_next = blknr + - (blockend >> log2blksz); - } - } else { - previous_block_number = blknr; - delayed_start = blknr; - delayed_extent = blockend; - delayed_buf = buf; - delayed_next = blknr + - (blockend >> log2blksz); - } - } else { - if (previous_block_number != -1) { - /* spill */ - put_ext4((uint64_t) ((uint64_t)delayed_start << - log2blksz), - delayed_buf, - (uint32_t) delayed_extent); - previous_block_number = -1; - } - memset(buf, 0, fs->blksz - skipfirst); - } - buf += fs->blksz - skipfirst; - } - if (previous_block_number != -1) { - /* spill */ - put_ext4((uint64_t) ((uint64_t)delayed_start << log2blksz), - delayed_buf, (uint32_t) delayed_extent); - previous_block_number = -1; - } - - return len; -} - -int ext4fs_write(const char *fname, unsigned char *buffer, - unsigned long sizebytes) -{ - int ret = 0; - struct ext2_inode *file_inode = NULL; - unsigned char *inode_buffer = NULL; - int parent_inodeno; - int inodeno; - time_t timestamp = 0; - - uint64_t bytes_reqd_for_file; - unsigned int blks_reqd_for_file; - unsigned int blocks_remaining; - int existing_file_inodeno; - char *temp_ptr = NULL; - long int itable_blkno; - long int parent_itable_blkno; - long int blkoff; - struct ext2_sblock *sblock = &(ext4fs_root->sblock); - unsigned int inodes_per_block; - unsigned int ibmap_idx; - struct ext_filesystem *fs = get_fs(); - ALLOC_CACHE_ALIGN_BUFFER(char, filename, 256); - memset(filename, 0x00, sizeof(filename)); - - g_parent_inode = zalloc(sizeof(struct ext2_inode)); - if (!g_parent_inode) - goto fail; - - if (ext4fs_init() != 0) { - printf("error in File System init\n"); - return -1; - } - inodes_per_block = fs->blksz / fs->inodesz; - parent_inodeno = ext4fs_get_parent_inode_num(fname, filename, F_FILE); - if (parent_inodeno == -1) - goto fail; - if (ext4fs_iget(parent_inodeno, g_parent_inode)) - goto fail; - /* check if the filename is already present in root */ - existing_file_inodeno = ext4fs_filename_check(filename); - if (existing_file_inodeno != -1) { - ret = ext4fs_delete_file(existing_file_inodeno); - fs->first_pass_bbmap = 0; - fs->curr_blkno = 0; - - fs->first_pass_ibmap = 0; - fs->curr_inode_no = 0; - if (ret) - goto fail; - } - /* calucalate how many blocks required */ - bytes_reqd_for_file = sizebytes; - blks_reqd_for_file = lldiv(bytes_reqd_for_file, fs->blksz); - if (do_div(bytes_reqd_for_file, fs->blksz) != 0) { - blks_reqd_for_file++; - debug("total bytes for a file %u\n", blks_reqd_for_file); - } - blocks_remaining = blks_reqd_for_file; - /* test for available space in partition */ - if (fs->sb->free_blocks < blks_reqd_for_file) { - printf("Not enough space on partition !!!\n"); - goto fail; - } - - ext4fs_update_parent_dentry(filename, &inodeno, FILETYPE_REG); - /* prepare file inode */ - inode_buffer = zalloc(fs->inodesz); - if (!inode_buffer) - goto fail; - file_inode = (struct ext2_inode *)inode_buffer; - file_inode->mode = S_IFREG | S_IRWXU | - S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH; - /* ToDo: Update correct time */ - file_inode->mtime = timestamp; - file_inode->atime = timestamp; - file_inode->ctime = timestamp; - file_inode->nlinks = 1; - file_inode->size = sizebytes; - - /* Allocate data blocks */ - ext4fs_allocate_blocks(file_inode, blocks_remaining, - &blks_reqd_for_file); - file_inode->blockcnt = (blks_reqd_for_file * fs->blksz) >> - fs->dev_desc->log2blksz; - - temp_ptr = zalloc(fs->blksz); - if (!temp_ptr) - goto fail; - ibmap_idx = inodeno / ext4fs_root->sblock.inodes_per_group; - inodeno--; - itable_blkno = __le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) + - (inodeno % __le32_to_cpu(sblock->inodes_per_group)) / - inodes_per_block; - blkoff = (inodeno % inodes_per_block) * fs->inodesz; - ext4fs_devread((lbaint_t)itable_blkno * fs->sect_perblk, 0, fs->blksz, - temp_ptr); - if (ext4fs_log_journal(temp_ptr, itable_blkno)) - goto fail; - - memcpy(temp_ptr + blkoff, inode_buffer, fs->inodesz); - if (ext4fs_put_metadata(temp_ptr, itable_blkno)) - goto fail; - /* copy the file content into data blocks */ - if (ext4fs_write_file(file_inode, 0, sizebytes, (char *)buffer) == -1) { - printf("Error in copying content\n"); - goto fail; - } - ibmap_idx = parent_inodeno / ext4fs_root->sblock.inodes_per_group; - parent_inodeno--; - parent_itable_blkno = __le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) + - (parent_inodeno % - __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; - blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz; - if (parent_itable_blkno != itable_blkno) { - memset(temp_ptr, '\0', fs->blksz); - ext4fs_devread((lbaint_t)parent_itable_blkno * fs->sect_perblk, - 0, fs->blksz, temp_ptr); - if (ext4fs_log_journal(temp_ptr, parent_itable_blkno)) - goto fail; - - memcpy(temp_ptr + blkoff, g_parent_inode, - sizeof(struct ext2_inode)); - if (ext4fs_put_metadata(temp_ptr, parent_itable_blkno)) - goto fail; - free(temp_ptr); - } else { - /* - * If parent and child fall in same inode table block - * both should be kept in 1 buffer - */ - memcpy(temp_ptr + blkoff, g_parent_inode, - sizeof(struct ext2_inode)); - gd_index--; - if (ext4fs_put_metadata(temp_ptr, itable_blkno)) - goto fail; - free(temp_ptr); - } - ext4fs_update(); - ext4fs_deinit(); - - fs->first_pass_bbmap = 0; - fs->curr_blkno = 0; - fs->first_pass_ibmap = 0; - fs->curr_inode_no = 0; - free(inode_buffer); - free(g_parent_inode); - g_parent_inode = NULL; - - return 0; -fail: - ext4fs_deinit(); - free(inode_buffer); - free(g_parent_inode); - g_parent_inode = NULL; - - return -1; -} diff --git a/qemu/roms/u-boot/fs/ext4/ext4fs.c b/qemu/roms/u-boot/fs/ext4/ext4fs.c deleted file mode 100644 index 417ce7b63..000000000 --- a/qemu/roms/u-boot/fs/ext4/ext4fs.c +++ /dev/null @@ -1,228 +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> - * - * ext4ls and ext4load : Based on ext2 ls and load support in Uboot. - * Ext4 read optimization taken from Open-Moko - * Qi bootloader - * - * (C) Copyright 2004 - * esd gmbh <www.esd-electronics.com> - * Reinhard Arlt <reinhard.arlt@esd-electronics.com> - * - * based on code from grub2 fs/ext2.c and fs/fshelp.c by - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. - * - * ext4write : Based on generic ext4 protocol. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <ext_common.h> -#include <ext4fs.h> -#include "ext4_common.h" - -int ext4fs_symlinknest; -struct ext_filesystem ext_fs; - -struct ext_filesystem *get_fs(void) -{ - return &ext_fs; -} - -void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot) -{ - if ((node != &ext4fs_root->diropen) && (node != currroot)) - free(node); -} - -/* - * Taken from openmoko-kernel mailing list: By Andy green - * Optimized read file API : collects and defers contiguous sector - * reads into one potentially more efficient larger sequential read action - */ -int ext4fs_read_file(struct ext2fs_node *node, int pos, - unsigned int len, char *buf) -{ - struct ext_filesystem *fs = get_fs(); - int i; - lbaint_t blockcnt; - int log2blksz = fs->dev_desc->log2blksz; - int log2_fs_blocksize = LOG2_BLOCK_SIZE(node->data) - log2blksz; - int blocksize = (1 << (log2_fs_blocksize + log2blksz)); - unsigned int filesize = __le32_to_cpu(node->inode.size); - lbaint_t previous_block_number = -1; - lbaint_t delayed_start = 0; - lbaint_t delayed_extent = 0; - lbaint_t delayed_skipfirst = 0; - lbaint_t delayed_next = 0; - char *delayed_buf = NULL; - short status; - - /* Adjust len so it we can't read past the end of the file. */ - if (len > filesize) - len = filesize; - - blockcnt = ((len + pos) + blocksize - 1) / blocksize; - - for (i = pos / blocksize; i < blockcnt; i++) { - lbaint_t blknr; - int blockoff = pos % blocksize; - int blockend = blocksize; - int skipfirst = 0; - blknr = read_allocated_block(&(node->inode), i); - if (blknr < 0) - return -1; - - blknr = blknr << log2_fs_blocksize; - - /* Last block. */ - if (i == blockcnt - 1) { - blockend = (len + pos) % blocksize; - - /* The last portion is exactly blocksize. */ - if (!blockend) - blockend = blocksize; - } - - /* First block. */ - if (i == pos / blocksize) { - skipfirst = blockoff; - blockend -= skipfirst; - } - if (blknr) { - int status; - - if (previous_block_number != -1) { - if (delayed_next == blknr) { - delayed_extent += blockend; - delayed_next += blockend >> log2blksz; - } else { /* spill */ - status = ext4fs_devread(delayed_start, - delayed_skipfirst, - delayed_extent, - delayed_buf); - if (status == 0) - return -1; - previous_block_number = blknr; - delayed_start = blknr; - delayed_extent = blockend; - delayed_skipfirst = skipfirst; - delayed_buf = buf; - delayed_next = blknr + - (blockend >> log2blksz); - } - } else { - previous_block_number = blknr; - delayed_start = blknr; - delayed_extent = blockend; - delayed_skipfirst = skipfirst; - delayed_buf = buf; - delayed_next = blknr + - (blockend >> log2blksz); - } - } else { - if (previous_block_number != -1) { - /* spill */ - status = ext4fs_devread(delayed_start, - delayed_skipfirst, - delayed_extent, - delayed_buf); - if (status == 0) - return -1; - previous_block_number = -1; - } - memset(buf, 0, blocksize - skipfirst); - } - buf += blocksize - skipfirst; - } - if (previous_block_number != -1) { - /* spill */ - status = ext4fs_devread(delayed_start, - delayed_skipfirst, delayed_extent, - delayed_buf); - if (status == 0) - return -1; - previous_block_number = -1; - } - - return len; -} - -int ext4fs_ls(const char *dirname) -{ - struct ext2fs_node *dirnode; - int status; - - if (dirname == NULL) - return 0; - - status = ext4fs_find_file(dirname, &ext4fs_root->diropen, &dirnode, - FILETYPE_DIRECTORY); - if (status != 1) { - printf("** Can not find directory. **\n"); - return 1; - } - - ext4fs_iterate_dir(dirnode, NULL, NULL, NULL); - ext4fs_free_node(dirnode, &ext4fs_root->diropen); - - return 0; -} - -int ext4fs_exists(const char *filename) -{ - int file_len; - - file_len = ext4fs_open(filename); - return file_len >= 0; -} - -int ext4fs_read(char *buf, unsigned len) -{ - if (ext4fs_root == NULL || ext4fs_file == NULL) - return 0; - - return ext4fs_read_file(ext4fs_file, 0, len, buf); -} - -int ext4fs_probe(block_dev_desc_t *fs_dev_desc, - disk_partition_t *fs_partition) -{ - ext4fs_set_blk_dev(fs_dev_desc, fs_partition); - - if (!ext4fs_mount(fs_partition->size)) { - ext4fs_close(); - return -1; - } - - return 0; -} - -int ext4_read_file(const char *filename, void *buf, int offset, int len) -{ - int file_len; - int len_read; - - if (offset != 0) { - printf("** Cannot support non-zero offset **\n"); - return -1; - } - - file_len = ext4fs_open(filename); - if (file_len < 0) { - printf("** File not found %s **\n", filename); - return -1; - } - - if (len == 0) - len = file_len; - - len_read = ext4fs_read(buf, len); - - return len_read; -} |