quik_err_t ext2fs_mount(part_t *part) { struct ext2_data *data; quik_err_t err; data = malloc(sizeof(struct ext2_data)); if (!data) { return ERR_NO_MEM; } /* Read the superblock. */ err = part_read(part, 1 * 2, 0, sizeof(struct ext2_sblock), (char *) &data->sblock); if (err != ERR_NONE) { goto fail; } /* Make sure this is an ext2 filesystem. */ if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC) { err = ERR_FS_NOT_EXT2; goto fail; } if (__le32_to_cpu(data->sblock.revision_level == 0)) { inode_size = 128; } else { inode_size = __le16_to_cpu(data->sblock.inode_size); } #ifdef DEBUG printk("EXT2 rev %d, inode_size %d\n", __le32_to_cpu(data->sblock.revision_level), inode_size); #endif data->part = part; data->diropen.data = data; data->diropen.ino = 2; data->diropen.inode_read = 1; data->inode = &data->diropen.inode; err = ext2fs_read_inode(data, 2, data->inode); if (err != ERR_NONE) { goto fail; } ext2fs_root = data; return ERR_NONE; fail: free(data); ext2fs_root = NULL; return err; }
static quik_err_t ext2fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode) { struct ext2_block_group blkgrp; struct ext2_sblock *sblock = &data->sblock; int inodes_per_block; quik_err_t err; unsigned int blkno; unsigned int blkoff; #ifdef DEBUG printk ("ext2fs read inode %d, inode_size %d\n", ino, inode_size); #endif /* It is easier to calculate if the first inode is 0. */ ino--; err = ext2fs_blockgroup(data, ino / __le32_to_cpu (sblock->inodes_per_group), &blkgrp); if (err != ERR_NONE) { return err; } inodes_per_block = EXT2_BLOCK_SIZE(data) / inode_size; blkno = __le32_to_cpu(blkgrp.inode_table_id) + (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block; blkoff = (ino % inodes_per_block) * inode_size; #ifdef DEBUG printk ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff); #endif /* Read the inode. */ err = part_read(data->part, blkno << LOG2_EXT2_BLOCK_SIZE (data), blkoff, sizeof(struct ext2_inode), (char *) inode); if (err != ERR_NONE) { return err; } return ERR_NONE; }
/* for creating srs proc entry ... */ int create_srs_proc_entry(struct mtd_info *mtd) { struct proc_dir_entry *entry = NULL; int len = 0; int i =0; unsigned int ori_checksum=0, real_checksum=0; buffer_dinfo = kzalloc(DINFO_LENGTH, GFP_KERNEL); for(i=0; i< DINFO_BLOCK_TOTAL; i++){ if(!part_block_isbad(mtd, i*DINFO_LENGTH)){ part_read(mtd, i*DINFO_LENGTH, DINFO_LENGTH, &len, buffer_dinfo); pr_debug("SRS: Read dinfo partition block %d len=%d\n", i, len); break; } } if(i == DINFO_BLOCK_TOTAL){ printk(KERN_ERR"SRS: All dinfo blocks are bad!\n"); return -1; } if(len <= 0){ printk(KERN_ERR"SRS: Cannot read dinfo partition!\n"); return -2; } ori_checksum = read_checksum(buffer_dinfo, len); real_checksum = calc_checksum(buffer_dinfo, len); if(ori_checksum != real_checksum){ printk(KERN_ERR"SRS: Checksum Error! ori_checksum=0x%08X, real_checksum=0x%08X\n", ori_checksum, real_checksum); return -3; } entry = create_proc_entry(SRS_PROC_ENTRY_NAME,S_IRUSR | S_IRGRP | S_IROTH ,NULL); if(!entry) { printk(KERN_ERR"SRS: Cannot create /proc/%s\n", SRS_PROC_ENTRY_NAME); return -4; } entry->proc_fops = &srs_fops; pr_debug("SRS: /proc/%s successfully created!\n", SRS_PROC_ENTRY_NAME); return 0; }
static int partool_read(part_block_t block, char *partition) { int err; err = part_read(partition); if (err<0) { goto error; } err = part_block_write(block, 0, part_tmp, partool_size); if (err<0) { goto error; } err = 0; error: return err; }
static quik_err_t ext2fs_blockgroup(struct ext2_data *data, int group, struct ext2_block_group *blkgrp) { unsigned int blkno; unsigned int blkoff; unsigned int desc_per_blk; 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); #ifdef DEBUG printk ("ext2fs read %d group descriptor (blkno %d blkoff %d)\n", group, blkno, blkoff); #endif return part_read(data->part, blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff, sizeof(struct ext2_block_group), (char *)blkgrp); }
quik_err_t ext2fs_read_file(ext2fs_node_t node, unsigned pos, length_t len, char *buf) { unsigned i; unsigned blockcnt; quik_err_t err; int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data); int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS); unsigned int filesize = __le32_to_cpu(node->inode.size); /* 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++) { unsigned blknr; unsigned blockoff = pos % blocksize; length_t blockend = blocksize; spinner(5); int skipfirst = 0; err = ext2fs_read_block(node, i, &blknr); if (err != ERR_NONE) { return err; } blknr = blknr << log2blocksize; /* 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 the block number is 0 this block is not stored on disk but is zero filled instead. */ if (blknr) { err = part_read(node->data->part, blknr, skipfirst, blockend, buf); if (err != ERR_NONE) { return err; } } else { memset(buf, 0, blocksize - skipfirst); } buf += blocksize - skipfirst; } return ERR_NONE; }
static quik_err_t ext2fs_read_block(ext2fs_node_t node, int fileblock, unsigned *block_nr) { struct ext2_data *data = node->data; struct ext2_inode *inode = &node->inode; unsigned blknr; int blksz = EXT2_BLOCK_SIZE(data); int log2_blksz = LOG2_EXT2_BLOCK_SIZE(data); quik_err_t err; /* 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 (indir1_block == NULL) { indir1_block = (uint32_t *) malloc(blksz); if (indir1_block == NULL) { return ERR_NO_MEM; } indir1_size = blksz; indir1_blkno = -1; } if (blksz != indir1_size) { free(indir1_block); indir1_block = NULL; indir1_size = 0; indir1_blkno = -1; indir1_block = (uint32_t *) malloc(blksz); if (indir1_block == NULL) { return ERR_NO_MEM; } indir1_size = blksz; } if ((__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz) != indir1_blkno) { err = part_read(data->part, __le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz, 0, blksz, (char *) indir1_block); if (err != ERR_NONE) { return err; } indir1_blkno = __le32_to_cpu(inode->b.blocks. indir_block) << log2_blksz; } blknr = __le32_to_cpu(indir1_block [fileblock - INDIRECT_BLOCKS]); } /* Double indirect. */ else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 * (blksz / 4 + 1)))) { unsigned int perblock = blksz / 4; unsigned int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4); if (indir1_block == NULL) { indir1_block = (uint32_t *) malloc(blksz); if (indir1_block == NULL) { return ERR_NO_MEM; } indir1_size = blksz; indir1_blkno = -1; } if (blksz != indir1_size) { free(indir1_block); indir1_block = NULL; indir1_size = 0; indir1_blkno = -1; indir1_block = (uint32_t *) malloc(blksz); if (indir1_block == NULL) { return ERR_NO_MEM; } indir1_size = blksz; } if ((__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz) != indir1_blkno) { err = part_read(data->part, __le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz, 0, blksz, (char *) indir1_block); if (err != ERR_NONE) { return err; } indir1_blkno = __le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz; } if (indir2_block == NULL) { indir2_block = (uint32_t *) malloc(blksz); if (indir2_block == NULL) { return ERR_NO_MEM; } indir2_size = blksz; indir2_blkno = -1; } if (blksz != indir2_size) { free(indir2_block); indir2_block = NULL; indir2_size = 0; indir2_blkno = -1; indir2_block = (uint32_t *) malloc(blksz); if (indir2_block == NULL) { return ERR_NO_MEM; } indir2_size = blksz; } if ((__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz) != indir2_blkno) { err = part_read(data->part, __le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz, 0, blksz, (char *) indir2_block); if (err != ERR_NONE) { return err; } indir2_blkno = __le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz; } blknr = __le32_to_cpu(indir2_block[rblock % perblock]); } /* Triple indirect. */ else { return ERR_FS_CORRUPT; } #ifdef DEBUG printk("ext2fs_read_block %x\n", blknr); #endif *block_nr = blknr; return ERR_NONE; }