1*a1596438SUma Shankar /* 2*a1596438SUma Shankar * (C) Copyright 2011 - 2012 Samsung Electronics 3*a1596438SUma Shankar * EXT4 filesystem implementation in Uboot by 4*a1596438SUma Shankar * Uma Shankar <uma.shankar@samsung.com> 5*a1596438SUma Shankar * Manjunatha C Achar <a.manjunatha@samsung.com> 6*a1596438SUma Shankar * 7*a1596438SUma Shankar * ext4ls and ext4load : Based on ext2 ls load support in Uboot. 8*a1596438SUma Shankar * 9*a1596438SUma Shankar * (C) Copyright 2004 10*a1596438SUma Shankar * esd gmbh <www.esd-electronics.com> 11*a1596438SUma Shankar * Reinhard Arlt <reinhard.arlt@esd-electronics.com> 12*a1596438SUma Shankar * 13*a1596438SUma Shankar * based on code from grub2 fs/ext2.c and fs/fshelp.c by 14*a1596438SUma Shankar * GRUB -- GRand Unified Bootloader 15*a1596438SUma Shankar * Copyright (C) 2003, 2004 Free Software Foundation, Inc. 16*a1596438SUma Shankar * 17*a1596438SUma Shankar * This program is free software; you can redistribute it and/or modify 18*a1596438SUma Shankar * it under the terms of the GNU General Public License as published by 19*a1596438SUma Shankar * the Free Software Foundation; either version 2 of the License, or 20*a1596438SUma Shankar * (at your option) any later version. 21*a1596438SUma Shankar * 22*a1596438SUma Shankar * This program is distributed in the hope that it will be useful, 23*a1596438SUma Shankar * but WITHOUT ANY WARRANTY; without even the implied warranty of 24*a1596438SUma Shankar * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25*a1596438SUma Shankar * GNU General Public License for more details. 26*a1596438SUma Shankar * 27*a1596438SUma Shankar * You should have received a copy of the GNU General Public License 28*a1596438SUma Shankar * along with this program; if not, write to the Free Software 29*a1596438SUma Shankar * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 30*a1596438SUma Shankar */ 31*a1596438SUma Shankar 32*a1596438SUma Shankar #include <common.h> 33*a1596438SUma Shankar #include <ext_common.h> 34*a1596438SUma Shankar #include <ext4fs.h> 35*a1596438SUma Shankar #include <malloc.h> 36*a1596438SUma Shankar #include <stddef.h> 37*a1596438SUma Shankar #include <linux/stat.h> 38*a1596438SUma Shankar #include <linux/time.h> 39*a1596438SUma Shankar #include <asm/byteorder.h> 40*a1596438SUma Shankar #include "ext4_common.h" 41*a1596438SUma Shankar 42*a1596438SUma Shankar struct ext2_data *ext4fs_root; 43*a1596438SUma Shankar struct ext2fs_node *ext4fs_file; 44*a1596438SUma Shankar uint32_t *ext4fs_indir1_block; 45*a1596438SUma Shankar int ext4fs_indir1_size; 46*a1596438SUma Shankar int ext4fs_indir1_blkno = -1; 47*a1596438SUma Shankar uint32_t *ext4fs_indir2_block; 48*a1596438SUma Shankar int ext4fs_indir2_size; 49*a1596438SUma Shankar int ext4fs_indir2_blkno = -1; 50*a1596438SUma Shankar 51*a1596438SUma Shankar uint32_t *ext4fs_indir3_block; 52*a1596438SUma Shankar int ext4fs_indir3_size; 53*a1596438SUma Shankar int ext4fs_indir3_blkno = -1; 54*a1596438SUma Shankar struct ext2_inode *g_parent_inode; 55*a1596438SUma Shankar static int symlinknest; 56*a1596438SUma Shankar 57*a1596438SUma Shankar static struct ext4_extent_header *ext4fs_get_extent_block 58*a1596438SUma Shankar (struct ext2_data *data, char *buf, 59*a1596438SUma Shankar struct ext4_extent_header *ext_block, 60*a1596438SUma Shankar uint32_t fileblock, int log2_blksz) 61*a1596438SUma Shankar { 62*a1596438SUma Shankar struct ext4_extent_idx *index; 63*a1596438SUma Shankar unsigned long long block; 64*a1596438SUma Shankar struct ext_filesystem *fs = get_fs(); 65*a1596438SUma Shankar int i; 66*a1596438SUma Shankar 67*a1596438SUma Shankar while (1) { 68*a1596438SUma Shankar index = (struct ext4_extent_idx *)(ext_block + 1); 69*a1596438SUma Shankar 70*a1596438SUma Shankar if (le32_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC) 71*a1596438SUma Shankar return 0; 72*a1596438SUma Shankar 73*a1596438SUma Shankar if (ext_block->eh_depth == 0) 74*a1596438SUma Shankar return ext_block; 75*a1596438SUma Shankar i = -1; 76*a1596438SUma Shankar do { 77*a1596438SUma Shankar i++; 78*a1596438SUma Shankar if (i >= le32_to_cpu(ext_block->eh_entries)) 79*a1596438SUma Shankar break; 80*a1596438SUma Shankar } while (fileblock > le32_to_cpu(index[i].ei_block)); 81*a1596438SUma Shankar 82*a1596438SUma Shankar if (--i < 0) 83*a1596438SUma Shankar return 0; 84*a1596438SUma Shankar 85*a1596438SUma Shankar block = le32_to_cpu(index[i].ei_leaf_hi); 86*a1596438SUma Shankar block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo); 87*a1596438SUma Shankar 88*a1596438SUma Shankar if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf)) 89*a1596438SUma Shankar ext_block = (struct ext4_extent_header *)buf; 90*a1596438SUma Shankar else 91*a1596438SUma Shankar return 0; 92*a1596438SUma Shankar } 93*a1596438SUma Shankar } 94*a1596438SUma Shankar 95*a1596438SUma Shankar static int ext4fs_blockgroup 96*a1596438SUma Shankar (struct ext2_data *data, int group, struct ext2_block_group *blkgrp) 97*a1596438SUma Shankar { 98*a1596438SUma Shankar long int blkno; 99*a1596438SUma Shankar unsigned int blkoff, desc_per_blk; 100*a1596438SUma Shankar 101*a1596438SUma Shankar desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group); 102*a1596438SUma Shankar 103*a1596438SUma Shankar blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 + 104*a1596438SUma Shankar group / desc_per_blk; 105*a1596438SUma Shankar blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group); 106*a1596438SUma Shankar 107*a1596438SUma Shankar debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n", 108*a1596438SUma Shankar group, blkno, blkoff); 109*a1596438SUma Shankar 110*a1596438SUma Shankar return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), 111*a1596438SUma Shankar blkoff, sizeof(struct ext2_block_group), 112*a1596438SUma Shankar (char *)blkgrp); 113*a1596438SUma Shankar } 114*a1596438SUma Shankar 115*a1596438SUma Shankar int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) 116*a1596438SUma Shankar { 117*a1596438SUma Shankar struct ext2_block_group blkgrp; 118*a1596438SUma Shankar struct ext2_sblock *sblock = &data->sblock; 119*a1596438SUma Shankar struct ext_filesystem *fs = get_fs(); 120*a1596438SUma Shankar int inodes_per_block, status; 121*a1596438SUma Shankar long int blkno; 122*a1596438SUma Shankar unsigned int blkoff; 123*a1596438SUma Shankar 124*a1596438SUma Shankar /* It is easier to calculate if the first inode is 0. */ 125*a1596438SUma Shankar ino--; 126*a1596438SUma Shankar status = ext4fs_blockgroup(data, ino / __le32_to_cpu 127*a1596438SUma Shankar (sblock->inodes_per_group), &blkgrp); 128*a1596438SUma Shankar if (status == 0) 129*a1596438SUma Shankar return 0; 130*a1596438SUma Shankar 131*a1596438SUma Shankar inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz; 132*a1596438SUma Shankar blkno = __le32_to_cpu(blkgrp.inode_table_id) + 133*a1596438SUma Shankar (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; 134*a1596438SUma Shankar blkoff = (ino % inodes_per_block) * fs->inodesz; 135*a1596438SUma Shankar /* Read the inode. */ 136*a1596438SUma Shankar status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff, 137*a1596438SUma Shankar sizeof(struct ext2_inode), (char *)inode); 138*a1596438SUma Shankar if (status == 0) 139*a1596438SUma Shankar return 0; 140*a1596438SUma Shankar 141*a1596438SUma Shankar return 1; 142*a1596438SUma Shankar } 143*a1596438SUma Shankar 144*a1596438SUma Shankar long int read_allocated_block(struct ext2_inode *inode, int fileblock) 145*a1596438SUma Shankar { 146*a1596438SUma Shankar long int blknr; 147*a1596438SUma Shankar int blksz; 148*a1596438SUma Shankar int log2_blksz; 149*a1596438SUma Shankar int status; 150*a1596438SUma Shankar long int rblock; 151*a1596438SUma Shankar long int perblock_parent; 152*a1596438SUma Shankar long int perblock_child; 153*a1596438SUma Shankar unsigned long long start; 154*a1596438SUma Shankar /* get the blocksize of the filesystem */ 155*a1596438SUma Shankar blksz = EXT2_BLOCK_SIZE(ext4fs_root); 156*a1596438SUma Shankar log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root); 157*a1596438SUma Shankar if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) { 158*a1596438SUma Shankar char *buf = zalloc(blksz); 159*a1596438SUma Shankar if (!buf) 160*a1596438SUma Shankar return -ENOMEM; 161*a1596438SUma Shankar struct ext4_extent_header *ext_block; 162*a1596438SUma Shankar struct ext4_extent *extent; 163*a1596438SUma Shankar int i = -1; 164*a1596438SUma Shankar ext_block = ext4fs_get_extent_block(ext4fs_root, buf, 165*a1596438SUma Shankar (struct ext4_extent_header 166*a1596438SUma Shankar *)inode->b. 167*a1596438SUma Shankar blocks.dir_blocks, 168*a1596438SUma Shankar fileblock, log2_blksz); 169*a1596438SUma Shankar if (!ext_block) { 170*a1596438SUma Shankar printf("invalid extent block\n"); 171*a1596438SUma Shankar free(buf); 172*a1596438SUma Shankar return -EINVAL; 173*a1596438SUma Shankar } 174*a1596438SUma Shankar 175*a1596438SUma Shankar extent = (struct ext4_extent *)(ext_block + 1); 176*a1596438SUma Shankar 177*a1596438SUma Shankar do { 178*a1596438SUma Shankar i++; 179*a1596438SUma Shankar if (i >= le32_to_cpu(ext_block->eh_entries)) 180*a1596438SUma Shankar break; 181*a1596438SUma Shankar } while (fileblock >= le32_to_cpu(extent[i].ee_block)); 182*a1596438SUma Shankar if (--i >= 0) { 183*a1596438SUma Shankar fileblock -= le32_to_cpu(extent[i].ee_block); 184*a1596438SUma Shankar if (fileblock >= le32_to_cpu(extent[i].ee_len)) { 185*a1596438SUma Shankar free(buf); 186*a1596438SUma Shankar return 0; 187*a1596438SUma Shankar } 188*a1596438SUma Shankar 189*a1596438SUma Shankar start = le32_to_cpu(extent[i].ee_start_hi); 190*a1596438SUma Shankar start = (start << 32) + 191*a1596438SUma Shankar le32_to_cpu(extent[i].ee_start_lo); 192*a1596438SUma Shankar free(buf); 193*a1596438SUma Shankar return fileblock + start; 194*a1596438SUma Shankar } 195*a1596438SUma Shankar 196*a1596438SUma Shankar printf("Extent Error\n"); 197*a1596438SUma Shankar free(buf); 198*a1596438SUma Shankar return -1; 199*a1596438SUma Shankar } 200*a1596438SUma Shankar 201*a1596438SUma Shankar /* Direct blocks. */ 202*a1596438SUma Shankar if (fileblock < INDIRECT_BLOCKS) 203*a1596438SUma Shankar blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]); 204*a1596438SUma Shankar 205*a1596438SUma Shankar /* Indirect. */ 206*a1596438SUma Shankar else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) { 207*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 208*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 209*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 210*a1596438SUma Shankar printf("** SI ext2fs read block (indir 1)" 211*a1596438SUma Shankar "malloc failed. **\n"); 212*a1596438SUma Shankar return -1; 213*a1596438SUma Shankar } 214*a1596438SUma Shankar ext4fs_indir1_size = blksz; 215*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 216*a1596438SUma Shankar } 217*a1596438SUma Shankar if (blksz != ext4fs_indir1_size) { 218*a1596438SUma Shankar free(ext4fs_indir1_block); 219*a1596438SUma Shankar ext4fs_indir1_block = NULL; 220*a1596438SUma Shankar ext4fs_indir1_size = 0; 221*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 222*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 223*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 224*a1596438SUma Shankar printf("** SI ext2fs read block (indir 1):" 225*a1596438SUma Shankar "malloc failed. **\n"); 226*a1596438SUma Shankar return -1; 227*a1596438SUma Shankar } 228*a1596438SUma Shankar ext4fs_indir1_size = blksz; 229*a1596438SUma Shankar } 230*a1596438SUma Shankar if ((__le32_to_cpu(inode->b.blocks.indir_block) << 231*a1596438SUma Shankar log2_blksz) != ext4fs_indir1_blkno) { 232*a1596438SUma Shankar status = 233*a1596438SUma Shankar ext4fs_devread(__le32_to_cpu 234*a1596438SUma Shankar (inode->b.blocks. 235*a1596438SUma Shankar indir_block) << log2_blksz, 0, 236*a1596438SUma Shankar blksz, (char *)ext4fs_indir1_block); 237*a1596438SUma Shankar if (status == 0) { 238*a1596438SUma Shankar printf("** SI ext2fs read block (indir 1)" 239*a1596438SUma Shankar "failed. **\n"); 240*a1596438SUma Shankar return 0; 241*a1596438SUma Shankar } 242*a1596438SUma Shankar ext4fs_indir1_blkno = 243*a1596438SUma Shankar __le32_to_cpu(inode->b.blocks. 244*a1596438SUma Shankar indir_block) << log2_blksz; 245*a1596438SUma Shankar } 246*a1596438SUma Shankar blknr = __le32_to_cpu(ext4fs_indir1_block 247*a1596438SUma Shankar [fileblock - INDIRECT_BLOCKS]); 248*a1596438SUma Shankar } 249*a1596438SUma Shankar /* Double indirect. */ 250*a1596438SUma Shankar else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * 251*a1596438SUma Shankar (blksz / 4 + 1)))) { 252*a1596438SUma Shankar 253*a1596438SUma Shankar long int perblock = blksz / 4; 254*a1596438SUma Shankar long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); 255*a1596438SUma Shankar 256*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 257*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 258*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 259*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 1)" 260*a1596438SUma Shankar "malloc failed. **\n"); 261*a1596438SUma Shankar return -1; 262*a1596438SUma Shankar } 263*a1596438SUma Shankar ext4fs_indir1_size = blksz; 264*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 265*a1596438SUma Shankar } 266*a1596438SUma Shankar if (blksz != ext4fs_indir1_size) { 267*a1596438SUma Shankar free(ext4fs_indir1_block); 268*a1596438SUma Shankar ext4fs_indir1_block = NULL; 269*a1596438SUma Shankar ext4fs_indir1_size = 0; 270*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 271*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 272*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 273*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 1)" 274*a1596438SUma Shankar "malloc failed. **\n"); 275*a1596438SUma Shankar return -1; 276*a1596438SUma Shankar } 277*a1596438SUma Shankar ext4fs_indir1_size = blksz; 278*a1596438SUma Shankar } 279*a1596438SUma Shankar if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << 280*a1596438SUma Shankar log2_blksz) != ext4fs_indir1_blkno) { 281*a1596438SUma Shankar status = 282*a1596438SUma Shankar ext4fs_devread(__le32_to_cpu 283*a1596438SUma Shankar (inode->b.blocks. 284*a1596438SUma Shankar double_indir_block) << log2_blksz, 285*a1596438SUma Shankar 0, blksz, 286*a1596438SUma Shankar (char *)ext4fs_indir1_block); 287*a1596438SUma Shankar if (status == 0) { 288*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 1)" 289*a1596438SUma Shankar "failed. **\n"); 290*a1596438SUma Shankar return -1; 291*a1596438SUma Shankar } 292*a1596438SUma Shankar ext4fs_indir1_blkno = 293*a1596438SUma Shankar __le32_to_cpu(inode->b.blocks.double_indir_block) << 294*a1596438SUma Shankar log2_blksz; 295*a1596438SUma Shankar } 296*a1596438SUma Shankar 297*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 298*a1596438SUma Shankar ext4fs_indir2_block = zalloc(blksz); 299*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 300*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 2)" 301*a1596438SUma Shankar "malloc failed. **\n"); 302*a1596438SUma Shankar return -1; 303*a1596438SUma Shankar } 304*a1596438SUma Shankar ext4fs_indir2_size = blksz; 305*a1596438SUma Shankar ext4fs_indir2_blkno = -1; 306*a1596438SUma Shankar } 307*a1596438SUma Shankar if (blksz != ext4fs_indir2_size) { 308*a1596438SUma Shankar free(ext4fs_indir2_block); 309*a1596438SUma Shankar ext4fs_indir2_block = NULL; 310*a1596438SUma Shankar ext4fs_indir2_size = 0; 311*a1596438SUma Shankar ext4fs_indir2_blkno = -1; 312*a1596438SUma Shankar ext4fs_indir2_block = zalloc(blksz); 313*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 314*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 2)" 315*a1596438SUma Shankar "malloc failed. **\n"); 316*a1596438SUma Shankar return -1; 317*a1596438SUma Shankar } 318*a1596438SUma Shankar ext4fs_indir2_size = blksz; 319*a1596438SUma Shankar } 320*a1596438SUma Shankar if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) << 321*a1596438SUma Shankar log2_blksz) != ext4fs_indir2_blkno) { 322*a1596438SUma Shankar status = ext4fs_devread(__le32_to_cpu 323*a1596438SUma Shankar (ext4fs_indir1_block 324*a1596438SUma Shankar [rblock / 325*a1596438SUma Shankar perblock]) << log2_blksz, 0, 326*a1596438SUma Shankar blksz, 327*a1596438SUma Shankar (char *)ext4fs_indir2_block); 328*a1596438SUma Shankar if (status == 0) { 329*a1596438SUma Shankar printf("** DI ext2fs read block (indir 2 2)" 330*a1596438SUma Shankar "failed. **\n"); 331*a1596438SUma Shankar return -1; 332*a1596438SUma Shankar } 333*a1596438SUma Shankar ext4fs_indir2_blkno = 334*a1596438SUma Shankar __le32_to_cpu(ext4fs_indir1_block[rblock 335*a1596438SUma Shankar / 336*a1596438SUma Shankar perblock]) << 337*a1596438SUma Shankar log2_blksz; 338*a1596438SUma Shankar } 339*a1596438SUma Shankar blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]); 340*a1596438SUma Shankar } 341*a1596438SUma Shankar /* Tripple indirect. */ 342*a1596438SUma Shankar else { 343*a1596438SUma Shankar rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 + 344*a1596438SUma Shankar (blksz / 4 * blksz / 4)); 345*a1596438SUma Shankar perblock_child = blksz / 4; 346*a1596438SUma Shankar perblock_parent = ((blksz / 4) * (blksz / 4)); 347*a1596438SUma Shankar 348*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 349*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 350*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 351*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 1)" 352*a1596438SUma Shankar "malloc failed. **\n"); 353*a1596438SUma Shankar return -1; 354*a1596438SUma Shankar } 355*a1596438SUma Shankar ext4fs_indir1_size = blksz; 356*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 357*a1596438SUma Shankar } 358*a1596438SUma Shankar if (blksz != ext4fs_indir1_size) { 359*a1596438SUma Shankar free(ext4fs_indir1_block); 360*a1596438SUma Shankar ext4fs_indir1_block = NULL; 361*a1596438SUma Shankar ext4fs_indir1_size = 0; 362*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 363*a1596438SUma Shankar ext4fs_indir1_block = zalloc(blksz); 364*a1596438SUma Shankar if (ext4fs_indir1_block == NULL) { 365*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 1)" 366*a1596438SUma Shankar "malloc failed. **\n"); 367*a1596438SUma Shankar return -1; 368*a1596438SUma Shankar } 369*a1596438SUma Shankar ext4fs_indir1_size = blksz; 370*a1596438SUma Shankar } 371*a1596438SUma Shankar if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) << 372*a1596438SUma Shankar log2_blksz) != ext4fs_indir1_blkno) { 373*a1596438SUma Shankar status = ext4fs_devread 374*a1596438SUma Shankar (__le32_to_cpu(inode->b.blocks.triple_indir_block) 375*a1596438SUma Shankar << log2_blksz, 0, blksz, 376*a1596438SUma Shankar (char *)ext4fs_indir1_block); 377*a1596438SUma Shankar if (status == 0) { 378*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 1)" 379*a1596438SUma Shankar "failed. **\n"); 380*a1596438SUma Shankar return -1; 381*a1596438SUma Shankar } 382*a1596438SUma Shankar ext4fs_indir1_blkno = 383*a1596438SUma Shankar __le32_to_cpu(inode->b.blocks.triple_indir_block) << 384*a1596438SUma Shankar log2_blksz; 385*a1596438SUma Shankar } 386*a1596438SUma Shankar 387*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 388*a1596438SUma Shankar ext4fs_indir2_block = zalloc(blksz); 389*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 390*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 391*a1596438SUma Shankar "malloc failed. **\n"); 392*a1596438SUma Shankar return -1; 393*a1596438SUma Shankar } 394*a1596438SUma Shankar ext4fs_indir2_size = blksz; 395*a1596438SUma Shankar ext4fs_indir2_blkno = -1; 396*a1596438SUma Shankar } 397*a1596438SUma Shankar if (blksz != ext4fs_indir2_size) { 398*a1596438SUma Shankar free(ext4fs_indir2_block); 399*a1596438SUma Shankar ext4fs_indir2_block = NULL; 400*a1596438SUma Shankar ext4fs_indir2_size = 0; 401*a1596438SUma Shankar ext4fs_indir2_blkno = -1; 402*a1596438SUma Shankar ext4fs_indir2_block = zalloc(blksz); 403*a1596438SUma Shankar if (ext4fs_indir2_block == NULL) { 404*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 405*a1596438SUma Shankar "malloc failed. **\n"); 406*a1596438SUma Shankar return -1; 407*a1596438SUma Shankar } 408*a1596438SUma Shankar ext4fs_indir2_size = blksz; 409*a1596438SUma Shankar } 410*a1596438SUma Shankar if ((__le32_to_cpu(ext4fs_indir1_block[rblock / 411*a1596438SUma Shankar perblock_parent]) << 412*a1596438SUma Shankar log2_blksz) 413*a1596438SUma Shankar != ext4fs_indir2_blkno) { 414*a1596438SUma Shankar status = ext4fs_devread(__le32_to_cpu 415*a1596438SUma Shankar (ext4fs_indir1_block 416*a1596438SUma Shankar [rblock / 417*a1596438SUma Shankar perblock_parent]) << 418*a1596438SUma Shankar log2_blksz, 0, blksz, 419*a1596438SUma Shankar (char *)ext4fs_indir2_block); 420*a1596438SUma Shankar if (status == 0) { 421*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 422*a1596438SUma Shankar "failed. **\n"); 423*a1596438SUma Shankar return -1; 424*a1596438SUma Shankar } 425*a1596438SUma Shankar ext4fs_indir2_blkno = 426*a1596438SUma Shankar __le32_to_cpu(ext4fs_indir1_block[rblock / 427*a1596438SUma Shankar perblock_parent]) 428*a1596438SUma Shankar << log2_blksz; 429*a1596438SUma Shankar } 430*a1596438SUma Shankar 431*a1596438SUma Shankar if (ext4fs_indir3_block == NULL) { 432*a1596438SUma Shankar ext4fs_indir3_block = zalloc(blksz); 433*a1596438SUma Shankar if (ext4fs_indir3_block == NULL) { 434*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 435*a1596438SUma Shankar "malloc failed. **\n"); 436*a1596438SUma Shankar return -1; 437*a1596438SUma Shankar } 438*a1596438SUma Shankar ext4fs_indir3_size = blksz; 439*a1596438SUma Shankar ext4fs_indir3_blkno = -1; 440*a1596438SUma Shankar } 441*a1596438SUma Shankar if (blksz != ext4fs_indir3_size) { 442*a1596438SUma Shankar free(ext4fs_indir3_block); 443*a1596438SUma Shankar ext4fs_indir3_block = NULL; 444*a1596438SUma Shankar ext4fs_indir3_size = 0; 445*a1596438SUma Shankar ext4fs_indir3_blkno = -1; 446*a1596438SUma Shankar ext4fs_indir3_block = zalloc(blksz); 447*a1596438SUma Shankar if (ext4fs_indir3_block == NULL) { 448*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 449*a1596438SUma Shankar "malloc failed. **\n"); 450*a1596438SUma Shankar return -1; 451*a1596438SUma Shankar } 452*a1596438SUma Shankar ext4fs_indir3_size = blksz; 453*a1596438SUma Shankar } 454*a1596438SUma Shankar if ((__le32_to_cpu(ext4fs_indir2_block[rblock 455*a1596438SUma Shankar / 456*a1596438SUma Shankar perblock_child]) << 457*a1596438SUma Shankar log2_blksz) != ext4fs_indir3_blkno) { 458*a1596438SUma Shankar status = 459*a1596438SUma Shankar ext4fs_devread(__le32_to_cpu 460*a1596438SUma Shankar (ext4fs_indir2_block 461*a1596438SUma Shankar [(rblock / perblock_child) 462*a1596438SUma Shankar % (blksz / 4)]) << log2_blksz, 0, 463*a1596438SUma Shankar blksz, (char *)ext4fs_indir3_block); 464*a1596438SUma Shankar if (status == 0) { 465*a1596438SUma Shankar printf("** TI ext2fs read block (indir 2 2)" 466*a1596438SUma Shankar "failed. **\n"); 467*a1596438SUma Shankar return -1; 468*a1596438SUma Shankar } 469*a1596438SUma Shankar ext4fs_indir3_blkno = 470*a1596438SUma Shankar __le32_to_cpu(ext4fs_indir2_block[(rblock / 471*a1596438SUma Shankar perblock_child) % 472*a1596438SUma Shankar (blksz / 473*a1596438SUma Shankar 4)]) << 474*a1596438SUma Shankar log2_blksz; 475*a1596438SUma Shankar } 476*a1596438SUma Shankar 477*a1596438SUma Shankar blknr = __le32_to_cpu(ext4fs_indir3_block 478*a1596438SUma Shankar [rblock % perblock_child]); 479*a1596438SUma Shankar } 480*a1596438SUma Shankar debug("ext4fs_read_block %ld\n", blknr); 481*a1596438SUma Shankar 482*a1596438SUma Shankar return blknr; 483*a1596438SUma Shankar } 484*a1596438SUma Shankar 485*a1596438SUma Shankar void ext4fs_close(void) 486*a1596438SUma Shankar { 487*a1596438SUma Shankar if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) { 488*a1596438SUma Shankar ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen); 489*a1596438SUma Shankar ext4fs_file = NULL; 490*a1596438SUma Shankar } 491*a1596438SUma Shankar if (ext4fs_root != NULL) { 492*a1596438SUma Shankar free(ext4fs_root); 493*a1596438SUma Shankar ext4fs_root = NULL; 494*a1596438SUma Shankar } 495*a1596438SUma Shankar if (ext4fs_indir1_block != NULL) { 496*a1596438SUma Shankar free(ext4fs_indir1_block); 497*a1596438SUma Shankar ext4fs_indir1_block = NULL; 498*a1596438SUma Shankar ext4fs_indir1_size = 0; 499*a1596438SUma Shankar ext4fs_indir1_blkno = -1; 500*a1596438SUma Shankar } 501*a1596438SUma Shankar if (ext4fs_indir2_block != NULL) { 502*a1596438SUma Shankar free(ext4fs_indir2_block); 503*a1596438SUma Shankar ext4fs_indir2_block = NULL; 504*a1596438SUma Shankar ext4fs_indir2_size = 0; 505*a1596438SUma Shankar ext4fs_indir2_blkno = -1; 506*a1596438SUma Shankar } 507*a1596438SUma Shankar if (ext4fs_indir3_block != NULL) { 508*a1596438SUma Shankar free(ext4fs_indir3_block); 509*a1596438SUma Shankar ext4fs_indir3_block = NULL; 510*a1596438SUma Shankar ext4fs_indir3_size = 0; 511*a1596438SUma Shankar ext4fs_indir3_blkno = -1; 512*a1596438SUma Shankar } 513*a1596438SUma Shankar } 514*a1596438SUma Shankar 515*a1596438SUma Shankar int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, 516*a1596438SUma Shankar struct ext2fs_node **fnode, int *ftype) 517*a1596438SUma Shankar { 518*a1596438SUma Shankar unsigned int fpos = 0; 519*a1596438SUma Shankar int status; 520*a1596438SUma Shankar struct ext2fs_node *diro = (struct ext2fs_node *) dir; 521*a1596438SUma Shankar 522*a1596438SUma Shankar #ifdef DEBUG 523*a1596438SUma Shankar if (name != NULL) 524*a1596438SUma Shankar printf("Iterate dir %s\n", name); 525*a1596438SUma Shankar #endif /* of DEBUG */ 526*a1596438SUma Shankar if (!diro->inode_read) { 527*a1596438SUma Shankar status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); 528*a1596438SUma Shankar if (status == 0) 529*a1596438SUma Shankar return 0; 530*a1596438SUma Shankar } 531*a1596438SUma Shankar /* Search the file. */ 532*a1596438SUma Shankar while (fpos < __le32_to_cpu(diro->inode.size)) { 533*a1596438SUma Shankar struct ext2_dirent dirent; 534*a1596438SUma Shankar 535*a1596438SUma Shankar status = ext4fs_read_file(diro, fpos, 536*a1596438SUma Shankar sizeof(struct ext2_dirent), 537*a1596438SUma Shankar (char *) &dirent); 538*a1596438SUma Shankar if (status < 1) 539*a1596438SUma Shankar return 0; 540*a1596438SUma Shankar 541*a1596438SUma Shankar if (dirent.namelen != 0) { 542*a1596438SUma Shankar char filename[dirent.namelen + 1]; 543*a1596438SUma Shankar struct ext2fs_node *fdiro; 544*a1596438SUma Shankar int type = FILETYPE_UNKNOWN; 545*a1596438SUma Shankar 546*a1596438SUma Shankar status = ext4fs_read_file(diro, 547*a1596438SUma Shankar fpos + 548*a1596438SUma Shankar sizeof(struct ext2_dirent), 549*a1596438SUma Shankar dirent.namelen, filename); 550*a1596438SUma Shankar if (status < 1) 551*a1596438SUma Shankar return 0; 552*a1596438SUma Shankar 553*a1596438SUma Shankar fdiro = zalloc(sizeof(struct ext2fs_node)); 554*a1596438SUma Shankar if (!fdiro) 555*a1596438SUma Shankar return 0; 556*a1596438SUma Shankar 557*a1596438SUma Shankar fdiro->data = diro->data; 558*a1596438SUma Shankar fdiro->ino = __le32_to_cpu(dirent.inode); 559*a1596438SUma Shankar 560*a1596438SUma Shankar filename[dirent.namelen] = '\0'; 561*a1596438SUma Shankar 562*a1596438SUma Shankar if (dirent.filetype != FILETYPE_UNKNOWN) { 563*a1596438SUma Shankar fdiro->inode_read = 0; 564*a1596438SUma Shankar 565*a1596438SUma Shankar if (dirent.filetype == FILETYPE_DIRECTORY) 566*a1596438SUma Shankar type = FILETYPE_DIRECTORY; 567*a1596438SUma Shankar else if (dirent.filetype == FILETYPE_SYMLINK) 568*a1596438SUma Shankar type = FILETYPE_SYMLINK; 569*a1596438SUma Shankar else if (dirent.filetype == FILETYPE_REG) 570*a1596438SUma Shankar type = FILETYPE_REG; 571*a1596438SUma Shankar } else { 572*a1596438SUma Shankar status = ext4fs_read_inode(diro->data, 573*a1596438SUma Shankar __le32_to_cpu 574*a1596438SUma Shankar (dirent.inode), 575*a1596438SUma Shankar &fdiro->inode); 576*a1596438SUma Shankar if (status == 0) { 577*a1596438SUma Shankar free(fdiro); 578*a1596438SUma Shankar return 0; 579*a1596438SUma Shankar } 580*a1596438SUma Shankar fdiro->inode_read = 1; 581*a1596438SUma Shankar 582*a1596438SUma Shankar if ((__le16_to_cpu(fdiro->inode.mode) & 583*a1596438SUma Shankar FILETYPE_INO_MASK) == 584*a1596438SUma Shankar FILETYPE_INO_DIRECTORY) { 585*a1596438SUma Shankar type = FILETYPE_DIRECTORY; 586*a1596438SUma Shankar } else if ((__le16_to_cpu(fdiro->inode.mode) 587*a1596438SUma Shankar & FILETYPE_INO_MASK) == 588*a1596438SUma Shankar FILETYPE_INO_SYMLINK) { 589*a1596438SUma Shankar type = FILETYPE_SYMLINK; 590*a1596438SUma Shankar } else if ((__le16_to_cpu(fdiro->inode.mode) 591*a1596438SUma Shankar & FILETYPE_INO_MASK) == 592*a1596438SUma Shankar FILETYPE_INO_REG) { 593*a1596438SUma Shankar type = FILETYPE_REG; 594*a1596438SUma Shankar } 595*a1596438SUma Shankar } 596*a1596438SUma Shankar #ifdef DEBUG 597*a1596438SUma Shankar printf("iterate >%s<\n", filename); 598*a1596438SUma Shankar #endif /* of DEBUG */ 599*a1596438SUma Shankar if ((name != NULL) && (fnode != NULL) 600*a1596438SUma Shankar && (ftype != NULL)) { 601*a1596438SUma Shankar if (strcmp(filename, name) == 0) { 602*a1596438SUma Shankar *ftype = type; 603*a1596438SUma Shankar *fnode = fdiro; 604*a1596438SUma Shankar return 1; 605*a1596438SUma Shankar } 606*a1596438SUma Shankar } else { 607*a1596438SUma Shankar if (fdiro->inode_read == 0) { 608*a1596438SUma Shankar status = ext4fs_read_inode(diro->data, 609*a1596438SUma Shankar __le32_to_cpu( 610*a1596438SUma Shankar dirent.inode), 611*a1596438SUma Shankar &fdiro->inode); 612*a1596438SUma Shankar if (status == 0) { 613*a1596438SUma Shankar free(fdiro); 614*a1596438SUma Shankar return 0; 615*a1596438SUma Shankar } 616*a1596438SUma Shankar fdiro->inode_read = 1; 617*a1596438SUma Shankar } 618*a1596438SUma Shankar switch (type) { 619*a1596438SUma Shankar case FILETYPE_DIRECTORY: 620*a1596438SUma Shankar printf("<DIR> "); 621*a1596438SUma Shankar break; 622*a1596438SUma Shankar case FILETYPE_SYMLINK: 623*a1596438SUma Shankar printf("<SYM> "); 624*a1596438SUma Shankar break; 625*a1596438SUma Shankar case FILETYPE_REG: 626*a1596438SUma Shankar printf(" "); 627*a1596438SUma Shankar break; 628*a1596438SUma Shankar default: 629*a1596438SUma Shankar printf("< ? > "); 630*a1596438SUma Shankar break; 631*a1596438SUma Shankar } 632*a1596438SUma Shankar printf("%10d %s\n", 633*a1596438SUma Shankar __le32_to_cpu(fdiro->inode.size), 634*a1596438SUma Shankar filename); 635*a1596438SUma Shankar } 636*a1596438SUma Shankar free(fdiro); 637*a1596438SUma Shankar } 638*a1596438SUma Shankar fpos += __le16_to_cpu(dirent.direntlen); 639*a1596438SUma Shankar } 640*a1596438SUma Shankar return 0; 641*a1596438SUma Shankar } 642*a1596438SUma Shankar 643*a1596438SUma Shankar static char *ext4fs_read_symlink(struct ext2fs_node *node) 644*a1596438SUma Shankar { 645*a1596438SUma Shankar char *symlink; 646*a1596438SUma Shankar struct ext2fs_node *diro = node; 647*a1596438SUma Shankar int status; 648*a1596438SUma Shankar 649*a1596438SUma Shankar if (!diro->inode_read) { 650*a1596438SUma Shankar status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); 651*a1596438SUma Shankar if (status == 0) 652*a1596438SUma Shankar return 0; 653*a1596438SUma Shankar } 654*a1596438SUma Shankar symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); 655*a1596438SUma Shankar if (!symlink) 656*a1596438SUma Shankar return 0; 657*a1596438SUma Shankar 658*a1596438SUma Shankar if (__le32_to_cpu(diro->inode.size) <= 60) { 659*a1596438SUma Shankar strncpy(symlink, diro->inode.b.symlink, 660*a1596438SUma Shankar __le32_to_cpu(diro->inode.size)); 661*a1596438SUma Shankar } else { 662*a1596438SUma Shankar status = ext4fs_read_file(diro, 0, 663*a1596438SUma Shankar __le32_to_cpu(diro->inode.size), 664*a1596438SUma Shankar symlink); 665*a1596438SUma Shankar if (status == 0) { 666*a1596438SUma Shankar free(symlink); 667*a1596438SUma Shankar return 0; 668*a1596438SUma Shankar } 669*a1596438SUma Shankar } 670*a1596438SUma Shankar symlink[__le32_to_cpu(diro->inode.size)] = '\0'; 671*a1596438SUma Shankar return symlink; 672*a1596438SUma Shankar } 673*a1596438SUma Shankar 674*a1596438SUma Shankar static int ext4fs_find_file1(const char *currpath, 675*a1596438SUma Shankar struct ext2fs_node *currroot, 676*a1596438SUma Shankar struct ext2fs_node **currfound, int *foundtype) 677*a1596438SUma Shankar { 678*a1596438SUma Shankar char fpath[strlen(currpath) + 1]; 679*a1596438SUma Shankar char *name = fpath; 680*a1596438SUma Shankar char *next; 681*a1596438SUma Shankar int status; 682*a1596438SUma Shankar int type = FILETYPE_DIRECTORY; 683*a1596438SUma Shankar struct ext2fs_node *currnode = currroot; 684*a1596438SUma Shankar struct ext2fs_node *oldnode = currroot; 685*a1596438SUma Shankar 686*a1596438SUma Shankar strncpy(fpath, currpath, strlen(currpath) + 1); 687*a1596438SUma Shankar 688*a1596438SUma Shankar /* Remove all leading slashes. */ 689*a1596438SUma Shankar while (*name == '/') 690*a1596438SUma Shankar name++; 691*a1596438SUma Shankar 692*a1596438SUma Shankar if (!*name) { 693*a1596438SUma Shankar *currfound = currnode; 694*a1596438SUma Shankar return 1; 695*a1596438SUma Shankar } 696*a1596438SUma Shankar 697*a1596438SUma Shankar for (;;) { 698*a1596438SUma Shankar int found; 699*a1596438SUma Shankar 700*a1596438SUma Shankar /* Extract the actual part from the pathname. */ 701*a1596438SUma Shankar next = strchr(name, '/'); 702*a1596438SUma Shankar if (next) { 703*a1596438SUma Shankar /* Remove all leading slashes. */ 704*a1596438SUma Shankar while (*next == '/') 705*a1596438SUma Shankar *(next++) = '\0'; 706*a1596438SUma Shankar } 707*a1596438SUma Shankar 708*a1596438SUma Shankar if (type != FILETYPE_DIRECTORY) { 709*a1596438SUma Shankar ext4fs_free_node(currnode, currroot); 710*a1596438SUma Shankar return 0; 711*a1596438SUma Shankar } 712*a1596438SUma Shankar 713*a1596438SUma Shankar oldnode = currnode; 714*a1596438SUma Shankar 715*a1596438SUma Shankar /* Iterate over the directory. */ 716*a1596438SUma Shankar found = ext4fs_iterate_dir(currnode, name, &currnode, &type); 717*a1596438SUma Shankar if (found == 0) 718*a1596438SUma Shankar return 0; 719*a1596438SUma Shankar 720*a1596438SUma Shankar if (found == -1) 721*a1596438SUma Shankar break; 722*a1596438SUma Shankar 723*a1596438SUma Shankar /* Read in the symlink and follow it. */ 724*a1596438SUma Shankar if (type == FILETYPE_SYMLINK) { 725*a1596438SUma Shankar char *symlink; 726*a1596438SUma Shankar 727*a1596438SUma Shankar /* Test if the symlink does not loop. */ 728*a1596438SUma Shankar if (++symlinknest == 8) { 729*a1596438SUma Shankar ext4fs_free_node(currnode, currroot); 730*a1596438SUma Shankar ext4fs_free_node(oldnode, currroot); 731*a1596438SUma Shankar return 0; 732*a1596438SUma Shankar } 733*a1596438SUma Shankar 734*a1596438SUma Shankar symlink = ext4fs_read_symlink(currnode); 735*a1596438SUma Shankar ext4fs_free_node(currnode, currroot); 736*a1596438SUma Shankar 737*a1596438SUma Shankar if (!symlink) { 738*a1596438SUma Shankar ext4fs_free_node(oldnode, currroot); 739*a1596438SUma Shankar return 0; 740*a1596438SUma Shankar } 741*a1596438SUma Shankar 742*a1596438SUma Shankar debug("Got symlink >%s<\n", symlink); 743*a1596438SUma Shankar 744*a1596438SUma Shankar if (symlink[0] == '/') { 745*a1596438SUma Shankar ext4fs_free_node(oldnode, currroot); 746*a1596438SUma Shankar oldnode = &ext4fs_root->diropen; 747*a1596438SUma Shankar } 748*a1596438SUma Shankar 749*a1596438SUma Shankar /* Lookup the node the symlink points to. */ 750*a1596438SUma Shankar status = ext4fs_find_file1(symlink, oldnode, 751*a1596438SUma Shankar &currnode, &type); 752*a1596438SUma Shankar 753*a1596438SUma Shankar free(symlink); 754*a1596438SUma Shankar 755*a1596438SUma Shankar if (status == 0) { 756*a1596438SUma Shankar ext4fs_free_node(oldnode, currroot); 757*a1596438SUma Shankar return 0; 758*a1596438SUma Shankar } 759*a1596438SUma Shankar } 760*a1596438SUma Shankar 761*a1596438SUma Shankar ext4fs_free_node(oldnode, currroot); 762*a1596438SUma Shankar 763*a1596438SUma Shankar /* Found the node! */ 764*a1596438SUma Shankar if (!next || *next == '\0') { 765*a1596438SUma Shankar *currfound = currnode; 766*a1596438SUma Shankar *foundtype = type; 767*a1596438SUma Shankar return 1; 768*a1596438SUma Shankar } 769*a1596438SUma Shankar name = next; 770*a1596438SUma Shankar } 771*a1596438SUma Shankar return -1; 772*a1596438SUma Shankar } 773*a1596438SUma Shankar 774*a1596438SUma Shankar int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode, 775*a1596438SUma Shankar struct ext2fs_node **foundnode, int expecttype) 776*a1596438SUma Shankar { 777*a1596438SUma Shankar int status; 778*a1596438SUma Shankar int foundtype = FILETYPE_DIRECTORY; 779*a1596438SUma Shankar 780*a1596438SUma Shankar symlinknest = 0; 781*a1596438SUma Shankar if (!path) 782*a1596438SUma Shankar return 0; 783*a1596438SUma Shankar 784*a1596438SUma Shankar status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype); 785*a1596438SUma Shankar if (status == 0) 786*a1596438SUma Shankar return 0; 787*a1596438SUma Shankar 788*a1596438SUma Shankar /* Check if the node that was found was of the expected type. */ 789*a1596438SUma Shankar if ((expecttype == FILETYPE_REG) && (foundtype != expecttype)) 790*a1596438SUma Shankar return 0; 791*a1596438SUma Shankar else if ((expecttype == FILETYPE_DIRECTORY) 792*a1596438SUma Shankar && (foundtype != expecttype)) 793*a1596438SUma Shankar return 0; 794*a1596438SUma Shankar 795*a1596438SUma Shankar return 1; 796*a1596438SUma Shankar } 797*a1596438SUma Shankar 798*a1596438SUma Shankar int ext4fs_open(const char *filename) 799*a1596438SUma Shankar { 800*a1596438SUma Shankar struct ext2fs_node *fdiro = NULL; 801*a1596438SUma Shankar int status; 802*a1596438SUma Shankar int len; 803*a1596438SUma Shankar 804*a1596438SUma Shankar if (ext4fs_root == NULL) 805*a1596438SUma Shankar return -1; 806*a1596438SUma Shankar 807*a1596438SUma Shankar ext4fs_file = NULL; 808*a1596438SUma Shankar status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro, 809*a1596438SUma Shankar FILETYPE_REG); 810*a1596438SUma Shankar if (status == 0) 811*a1596438SUma Shankar goto fail; 812*a1596438SUma Shankar 813*a1596438SUma Shankar if (!fdiro->inode_read) { 814*a1596438SUma Shankar status = ext4fs_read_inode(fdiro->data, fdiro->ino, 815*a1596438SUma Shankar &fdiro->inode); 816*a1596438SUma Shankar if (status == 0) 817*a1596438SUma Shankar goto fail; 818*a1596438SUma Shankar } 819*a1596438SUma Shankar len = __le32_to_cpu(fdiro->inode.size); 820*a1596438SUma Shankar ext4fs_file = fdiro; 821*a1596438SUma Shankar 822*a1596438SUma Shankar return len; 823*a1596438SUma Shankar fail: 824*a1596438SUma Shankar ext4fs_free_node(fdiro, &ext4fs_root->diropen); 825*a1596438SUma Shankar 826*a1596438SUma Shankar return -1; 827*a1596438SUma Shankar } 828*a1596438SUma Shankar 829*a1596438SUma Shankar int ext4fs_mount(unsigned part_length) 830*a1596438SUma Shankar { 831*a1596438SUma Shankar struct ext2_data *data; 832*a1596438SUma Shankar int status; 833*a1596438SUma Shankar struct ext_filesystem *fs = get_fs(); 834*a1596438SUma Shankar data = zalloc(sizeof(struct ext2_data)); 835*a1596438SUma Shankar if (!data) 836*a1596438SUma Shankar return 0; 837*a1596438SUma Shankar 838*a1596438SUma Shankar /* Read the superblock. */ 839*a1596438SUma Shankar status = ext4fs_devread(1 * 2, 0, sizeof(struct ext2_sblock), 840*a1596438SUma Shankar (char *)&data->sblock); 841*a1596438SUma Shankar 842*a1596438SUma Shankar if (status == 0) 843*a1596438SUma Shankar goto fail; 844*a1596438SUma Shankar 845*a1596438SUma Shankar /* Make sure this is an ext2 filesystem. */ 846*a1596438SUma Shankar if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) 847*a1596438SUma Shankar goto fail; 848*a1596438SUma Shankar 849*a1596438SUma Shankar if (__le32_to_cpu(data->sblock.revision_level == 0)) 850*a1596438SUma Shankar fs->inodesz = 128; 851*a1596438SUma Shankar else 852*a1596438SUma Shankar fs->inodesz = __le16_to_cpu(data->sblock.inode_size); 853*a1596438SUma Shankar 854*a1596438SUma Shankar debug("EXT2 rev %d, inode_size %d\n", 855*a1596438SUma Shankar __le32_to_cpu(data->sblock.revision_level), fs->inodesz); 856*a1596438SUma Shankar 857*a1596438SUma Shankar data->diropen.data = data; 858*a1596438SUma Shankar data->diropen.ino = 2; 859*a1596438SUma Shankar data->diropen.inode_read = 1; 860*a1596438SUma Shankar data->inode = &data->diropen.inode; 861*a1596438SUma Shankar 862*a1596438SUma Shankar status = ext4fs_read_inode(data, 2, data->inode); 863*a1596438SUma Shankar if (status == 0) 864*a1596438SUma Shankar goto fail; 865*a1596438SUma Shankar 866*a1596438SUma Shankar ext4fs_root = data; 867*a1596438SUma Shankar 868*a1596438SUma Shankar return 1; 869*a1596438SUma Shankar fail: 870*a1596438SUma Shankar printf("Failed to mount ext2 filesystem...\n"); 871*a1596438SUma Shankar free(data); 872*a1596438SUma Shankar ext4fs_root = NULL; 873*a1596438SUma Shankar 874*a1596438SUma Shankar return 0; 875*a1596438SUma Shankar } 876