Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #4
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;
}
Пример #5
0
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);

}
Пример #6
0
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;
}
Пример #7
0
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;
}