1 /* 2 * (C) Copyright 2011 - 2012 Samsung Electronics 3 * EXT4 filesystem implementation in Uboot by 4 * Uma Shankar <uma.shankar@samsung.com> 5 * Manjunatha C Achar <a.manjunatha@samsung.com> 6 * 7 * Ext4 Extent data structures are taken from original ext4 fs code 8 * as found in the linux kernel. 9 * 10 * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com 11 * Written by Alex Tomas <alex@clusterfs.com> 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License version 2 as 15 * published by the Free Software Foundation. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 */ 26 27 #ifndef __EXT4__ 28 #define __EXT4__ 29 #include <ext_common.h> 30 #include <fs.h> 31 32 struct disk_partition; 33 34 #define EXT4_INDEX_FL 0x00001000 /* Inode uses hash tree index */ 35 #define EXT4_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ 36 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ 37 #define EXT4_EXT_MAGIC 0xf30a 38 39 #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 40 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 41 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 42 #define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 43 #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 44 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 45 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 46 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 47 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 48 #define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 49 50 #define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 51 #define EXT4_FEATURE_INCOMPAT_RECOVER 0x0004 52 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 53 #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 54 #define EXT4_FEATURE_INCOMPAT_MMP 0x0100 55 #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 56 #define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 57 #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 58 59 #define EXT4_INDIRECT_BLOCKS 12 60 61 /* 62 * Incompat features supported by this implementation. 63 */ 64 #define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE | \ 65 EXT4_FEATURE_INCOMPAT_RECOVER | \ 66 EXT4_FEATURE_INCOMPAT_EXTENTS | \ 67 EXT4_FEATURE_INCOMPAT_64BIT | \ 68 EXT4_FEATURE_INCOMPAT_FLEX_BG) 69 70 /* 71 * Incompat features supported by this implementation only in a lazy 72 * way, good enough for reading files. 73 * 74 * - Multi mount protection (mmp) is not supported, but for read-only 75 * we get away with it. 76 * - Same for metadata_csum_seed and metadata_csum. 77 * - The implementation has also no clue about fscrypt, but it can read 78 * unencrypted files. Reading encrypted files will read garbage. 79 */ 80 #define EXT4_FEATURE_INCOMPAT_SUPP_LAZY_RO (EXT4_FEATURE_INCOMPAT_MMP | \ 81 EXT4_FEATURE_INCOMPAT_CSUM_SEED | \ 82 EXT4_FEATURE_INCOMPAT_ENCRYPT) 83 84 /* 85 * Read-only compat features we support. 86 * If unknown ro compat features are detected, writing to the fs is denied. 87 */ 88 #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | \ 89 EXT4_FEATURE_RO_COMPAT_LARGE_FILE | \ 90 EXT4_FEATURE_RO_COMPAT_HUGE_FILE | \ 91 EXT4_FEATURE_RO_COMPAT_GDT_CSUM | \ 92 EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ 93 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE) 94 95 #define EXT4_BG_INODE_UNINIT 0x0001 96 #define EXT4_BG_BLOCK_UNINIT 0x0002 97 #define EXT4_BG_INODE_ZEROED 0x0004 98 99 /* 100 * ext4_inode has i_block array (60 bytes total). 101 * The first 12 bytes store ext4_extent_header; 102 * the remainder stores an array of ext4_extent. 103 */ 104 105 /* 106 * This is the extent on-disk structure. 107 * It's used at the bottom of the tree. 108 */ 109 struct ext4_extent { 110 __le32 ee_block; /* first logical block extent covers */ 111 __le16 ee_len; /* number of blocks covered by extent */ 112 __le16 ee_start_hi; /* high 16 bits of physical block */ 113 __le32 ee_start_lo; /* low 32 bits of physical block */ 114 }; 115 116 /* 117 * This is index on-disk structure. 118 * It's used at all the levels except the bottom. 119 */ 120 struct ext4_extent_idx { 121 __le32 ei_block; /* index covers logical blocks from 'block' */ 122 __le32 ei_leaf_lo; /* pointer to the physical block of the next * 123 * level. leaf or next index could be there */ 124 __le16 ei_leaf_hi; /* high 16 bits of physical block */ 125 __u16 ei_unused; 126 }; 127 128 /* Each block (leaves and indexes), even inode-stored has header. */ 129 struct ext4_extent_header { 130 __le16 eh_magic; /* probably will support different formats */ 131 __le16 eh_entries; /* number of valid entries */ 132 __le16 eh_max; /* capacity of store in entries */ 133 __le16 eh_depth; /* has tree real underlying blocks? */ 134 __le32 eh_generation; /* generation of the tree */ 135 }; 136 137 struct ext_filesystem { 138 /* Total Sector of partition */ 139 uint64_t total_sect; 140 /* Block size of partition */ 141 uint32_t blksz; 142 /* Inode size of partition */ 143 uint32_t inodesz; 144 /* Sectors per Block */ 145 uint32_t sect_perblk; 146 /* Group Descriptor size */ 147 uint16_t gdsize; 148 /* Group Descriptor Block Number */ 149 uint32_t gdtable_blkno; 150 /* Total block groups of partition */ 151 uint32_t no_blkgrp; 152 /* No of blocks required for bgdtable */ 153 uint32_t no_blk_pergdt; 154 /* Superblock */ 155 struct ext2_sblock *sb; 156 /* Block group descritpor table */ 157 char *gdtable; 158 159 /* Block Bitmap Related */ 160 unsigned char **blk_bmaps; 161 long int curr_blkno; 162 uint16_t first_pass_bbmap; 163 164 /* Inode Bitmap Related */ 165 unsigned char **inode_bmaps; 166 int curr_inode_no; 167 uint16_t first_pass_ibmap; 168 169 /* Journal Related */ 170 171 /* Block Device Descriptor */ 172 struct blk_desc *dev_desc; 173 }; 174 175 struct ext_block_cache { 176 char *buf; 177 lbaint_t block; 178 int size; 179 }; 180 181 extern struct ext2_data *ext4fs_root; 182 extern struct ext2fs_node *ext4fs_file; 183 184 #if defined(CONFIG_EXT4_WRITE) 185 extern struct ext2_inode *g_parent_inode; 186 extern int gd_index; 187 extern int gindex; 188 189 int ext4fs_init(void); 190 void ext4fs_deinit(void); 191 int ext4fs_filename_unlink(char *filename); 192 int ext4fs_write(const char *fname, const char *buffer, 193 unsigned long sizebytes, int type); 194 int ext4_write_file(const char *filename, void *buf, loff_t offset, loff_t len, 195 loff_t *actwrite); 196 int ext4fs_create_link(const char *target, const char *fname); 197 #endif 198 199 struct ext_filesystem *get_fs(void); 200 int ext4fs_open(const char *filename, loff_t *len); 201 int ext4fs_read(char *buf, loff_t offset, loff_t len, loff_t *actread); 202 int ext4fs_mount(void); 203 void ext4fs_close(void); 204 void ext4fs_reinit_global(void); 205 int ext4fs_ls(const char *dirname); 206 int ext4fs_exists(const char *filename); 207 int ext4fs_size(const char *filename, loff_t *size); 208 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot); 209 int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf); 210 void ext4fs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info); 211 long int read_allocated_block(struct ext2_inode *inode, int fileblock, 212 struct ext_block_cache *cache); 213 int ext4fs_probe(struct blk_desc *fs_dev_desc, 214 struct disk_partition *fs_partition); 215 int ext4_read_file(const char *filename, void *buf, loff_t offset, loff_t len, 216 loff_t *actread); 217 int ext4_read_superblock(char *buffer); 218 int ext4fs_uuid(char *uuid_str); 219 void ext_cache_init(struct ext_block_cache *cache); 220 void ext_cache_fini(struct ext_block_cache *cache); 221 int ext_cache_read(struct ext_block_cache *cache, lbaint_t block, int size); 222 int ext4fs_opendir(const char *dirname, struct fs_dir_stream **dirsp); 223 int ext4fs_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); 224 void ext4fs_closedir(struct fs_dir_stream *dirs); 225 #endif 226