Example #1
0
static int 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;
	int status;

	unsigned int blkno;
	unsigned int blkoff;

	/* It is easier to calculate if the first inode is 0.  */
	ino--;
#ifdef DEBUG
	printf ("ext2fs read inode %d\n", ino);
#endif
	status = ext2fs_blockgroup (data,
				    ino /
				    __le32_to_cpu (sblock->inodes_per_group),
				    &blkgrp);
	if (status == 0) {
		return (0);
	}
#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
       inodes_per_block = EXT2_BLOCK_SIZE (data) / ext2_inode_size;
#else
        inodes_per_block = EXT2_BLOCK_SIZE (data) / 128;
#endif
	blkno = (ino % __le32_to_cpu (sblock->inodes_per_group)) /
		inodes_per_block;
	blkoff = (ino % __le32_to_cpu (sblock->inodes_per_group)) %
		inodes_per_block;
#ifdef DEBUG
	printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff);
#endif
	/* Read the inode.  */
#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
    status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) +
              blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
            ext2_inode_size * blkoff,
            sizeof (struct ext2_inode), (char *) inode);
#else

	status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) +
				   blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
				 sizeof (struct ext2_inode) * blkoff,
				 sizeof (struct ext2_inode), (char *) inode);
#endif
	if (status == 0) {
		return (0);
	}
	return (1);
}
Example #2
0
int ext2fs_read_file
    (struct ext2fs_node *node, int pos, unsigned int len, char *buf)
{
    int i;
    int blockcnt;
    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++) {
        int blknr;
        int blockoff = pos % blocksize;
        int blockend = blocksize;

        int skipfirst = 0;

        blknr = ext2fs_read_block (node, i);
        if (blknr < 0) {
            return (-1);
        }
        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) {
            int status;

            status = ext2fs_devread (blknr, skipfirst, blockend, buf);
            if (status == 0) {
                return (-1);
            }
        } else {
            memset (buf, 0, blocksize - skipfirst);
        }
        buf += blocksize - skipfirst;
    }
    return (len);
}
Example #3
0
static int ext2fs_blockgroup
	(struct ext2_data *data, int group, struct ext2_block_group *blkgrp) {
#ifdef DEBUG
	printf ("ext2fs read blockgroup\n");
#endif
	return (ext2fs_devread
		(((__le32_to_cpu (data->sblock.first_data_block) +
		   1) << LOG2_EXT2_BLOCK_SIZE (data)),
		 group * sizeof (struct ext2_block_group),
		 sizeof (struct ext2_block_group), (char *) blkgrp));
}
Example #4
0
int ext2fs_mount (unsigned part_length) {
	struct ext2_data *data;
	int status;

	data = malloc (sizeof (struct ext2_data));
	if (!data) {
		return (0);
	}
	/* Read the superblock.  */
	status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock),
				 (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;
	}
#ifdef CFG_EXT2_SUPPORT_DYNAMIC_REV
#ifdef DEBUG
       printf("revision_level = 0x%x, inode_size = 0x%x\n", data->sblock.revision_level, data->sblock.inode_size);
#endif
       if (__le32_to_cpu (data->sblock.revision_level) == EXT2_GOOD_OLD_REV) {
               ext2_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
       } else {
               ext2_inode_size = __le16_to_cpu (data->sblock.inode_size);
       }
#endif
       

	data->diropen.data = data;
	data->diropen.ino = 2;
	data->diropen.inode_read = 1;
	data->inode = &data->diropen.inode;

	status = ext2fs_read_inode (data, 2, data->inode);
	if (status == 0) {
		goto fail;
	}

	ext2fs_root = data;

	return (1);

fail:
	printf ("Failed to mount ext2 filesystem...\n");
	free (data);
	ext2fs_root = NULL;
	return (0);
}
Example #5
0
int ext2fs_mount (unsigned part_length) {
    struct ext2_data *data;
    int status;

    data = malloc (sizeof (struct ext2_data));
    if (!data) {
        return (0);
    }
    /* Read the superblock.  */
    status = ext2fs_devread (1 * 2, 0, sizeof (struct ext2_sblock),
                 (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)) {
        inode_size = 128;
    } else {
        inode_size = __le16_to_cpu(data->sblock.inode_size);
    }
#ifdef DEBUG
    printf("EXT2 rev %d, inode_size %d\n",
            __le32_to_cpu(data->sblock.revision_level), inode_size);
#endif
    data->diropen.data = data;
    data->diropen.ino = 2;
    data->diropen.inode_read = 1;
    data->inode = &data->diropen.inode;

    status = ext2fs_read_inode (data, 2, data->inode);
    if (status == 0) {
        goto fail;
    }

    ext2fs_root = data;

    return (1);

fail:
    printf ("Failed to mount ext2 filesystem...\n");
    free (data);
    ext2fs_root = NULL;
    return (0);
}
Example #6
0
static int 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
    printf ("ext2fs read %d group descriptor (blkno %d blkoff %d)\n",
        group, blkno, blkoff);
#endif
    return (ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE(data),
        blkoff, sizeof(struct ext2_block_group), (char *)blkgrp));

}
Example #7
0
static int 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;
    int status;

    unsigned int blkno;
    unsigned int blkoff;

#ifdef DEBUG
    printf ("ext2fs read inode %d, inode_size %d\n", ino, inode_size);
#endif
    /* It is easier to calculate if the first inode is 0.  */
    ino--;
    status = ext2fs_blockgroup (data, ino / __le32_to_cpu
                    (sblock->inodes_per_group), &blkgrp);
    if (status == 0) {
        return (0);
    }

    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
    printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff);
#endif
    /* Read the inode.  */
    status = ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE (data), blkoff,
                 sizeof (struct ext2_inode), (char *) inode);
    if (status == 0) {
        return (0);
    }

    return (1);
}
Example #8
0
static int ext2fs_read_block(struct ext2fs_node *node, int fileblock)
{
    struct ext2_data *data = node->data;
    struct ext2_inode *inode = &node->inode;
    int blknr;
    int blksz = EXT2_BLOCK_SIZE (data);
    int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
    int status;

    /* 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) {
                printf ("** ext2fs read block (indir 1) malloc failed. **\n");
                return (-1);
            }
            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) {
                printf ("** ext2fs read block (indir 1) malloc failed. **\n");
                return (-1);
            }
            indir1_size = blksz;
        }
        if ((__le32_to_cpu (inode->b.blocks.indir_block) <<
             log2_blksz) != indir1_blkno) {
            status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz,
                         0, blksz,
                         (char *) indir1_block);
            if (status == 0) {
                printf ("** ext2fs read block (indir 1) failed. **\n");
                return (0);
            }
            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) {
                printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
                return (-1);
            }
            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) {
                printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
                return (-1);
            }
            indir1_size = blksz;
        }
        if ((__le32_to_cpu (inode->b.blocks.double_indir_block) <<
             log2_blksz) != indir1_blkno) {
            status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz,
                        0, blksz,
                        (char *) indir1_block);
            if (status == 0) {
                printf ("** ext2fs read block (indir 2 1) failed. **\n");
                return (-1);
            }
            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) {
                printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
                return (-1);
            }
            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) {
                printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
                return (-1);
            }
            indir2_size = blksz;
        }
        if ((__le32_to_cpu (indir1_block[rblock / perblock]) <<
             log2_blksz) != indir2_blkno) {
            status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz,
                         0, blksz,
                         (char *) indir2_block);
            if (status == 0) {
                printf ("** ext2fs read block (indir 2 2) failed. **\n");
                return (-1);
            }
            indir2_blkno =
                __le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz;
        }
        blknr = __le32_to_cpu (indir2_block[rblock % perblock]);
    }
    /* Tripple indirect.  */
    else {
        printf ("** ext2fs doesn't support tripple indirect blocks. **\n");
        return (-1);
    }
#ifdef DEBUG
    printf ("ext2fs_read_block %08x\n", blknr);
#endif
    return (blknr);
}
Example #9
0
static int ext2fs_read_block (ext2fs_node_t node, int fileblock, int *stream) {
#else
static int ext2fs_read_block (ext2fs_node_t node, int fileblock) {
#endif
	struct ext2_data *data = node->data;
	struct ext2_inode *inode = &node->inode;
	int blknr;
	int blksz = EXT2_BLOCK_SIZE (data);
	int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
	int status;

#ifdef CFG_OPTIMIZE_EXT2_READ
       *stream = 1;/* itself */
#endif

	/* Direct blocks.  */
	if (fileblock < INDIRECT_BLOCKS) {
		blknr = __le32_to_cpu (inode->b.blocks.dir_blocks[fileblock]);
#ifdef CFG_OPTIMIZE_EXT2_READ
               while(((inode->b.blocks.dir_blocks[fileblock + 1] - 
                       inode->b.blocks.dir_blocks[fileblock]) == 1) && 
                        (fileblock < INDIRECT_BLOCKS - 1)) {
                       fileblock++;
                       *stream += 1;
               }
#endif
	}
	/* Indirect.  */
	else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
		if (indir1_block == NULL) {
			indir1_block = (uint32_t *) malloc (blksz);
			if (indir1_block == NULL) {
				printf ("** ext2fs read block (indir 1) malloc failed. **\n");
				return (-1);
			}
			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) {
				printf ("** ext2fs read block (indir 1) malloc failed. **\n");
				return (-1);
			}
			indir1_size = blksz;
		}
		if ((__le32_to_cpu (inode->b.blocks.indir_block) <<
		     log2_blksz) != indir1_blkno) {
			status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.indir_block) << log2_blksz,
						 0, blksz,
						 (char *) indir1_block);
			if (status == 0) {
				printf ("** ext2fs read block (indir 1) failed. **\n");
				return (0);
			}
			indir1_blkno =
				__le32_to_cpu (inode->b.blocks.
					       indir_block) << log2_blksz;
		}
		blknr = __le32_to_cpu (indir1_block
				       [fileblock - INDIRECT_BLOCKS]);
#ifdef CFG_OPTIMIZE_EXT2_READ
               while(((__le32_to_cpu (indir1_block[fileblock - INDIRECT_BLOCKS + 1]) - \
                       __le32_to_cpu (indir1_block[fileblock - INDIRECT_BLOCKS])) == 1) && (fileblock < (blksz - 1))) {
                       fileblock++;
                       *stream += 1;
               }
#endif
	}
	/* 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);
#ifdef CFG_OPTIMIZE_EXT2_READ
        int rbcnt = 0;
#endif

		if (indir1_block == NULL) {
			indir1_block = (uint32_t *) malloc (blksz);
			if (indir1_block == NULL) {
				printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
				return (-1);
			}
			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) {
				printf ("** ext2fs read block (indir 2 1) malloc failed. **\n");
				return (-1);
			}
			indir1_size = blksz;
		}
		if ((__le32_to_cpu (inode->b.blocks.double_indir_block) <<
		     log2_blksz) != indir1_blkno) {
			status = ext2fs_devread (__le32_to_cpu(inode->b.blocks.double_indir_block) << log2_blksz,
						0, blksz,
						(char *) indir1_block);
			if (status == 0) {
				printf ("** ext2fs read block (indir 2 1) failed. **\n");
				return (-1);
			}
			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) {
				printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
				return (-1);
			}
			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) {
				printf ("** ext2fs read block (indir 2 2) malloc failed. **\n");
				return (-1);
			}
			indir2_size = blksz;
		}
		if ((__le32_to_cpu (indir1_block[rblock / perblock]) <<
		     log2_blksz) != indir1_blkno) {
			status = ext2fs_devread (__le32_to_cpu(indir1_block[rblock / perblock]) << log2_blksz,
						 0, blksz,
						 (char *) indir2_block);
			if (status == 0) {
				printf ("** ext2fs read block (indir 2 2) failed. **\n");
				return (-1);
			}
			indir2_blkno =
				__le32_to_cpu (indir1_block[rblock / perblock]) << log2_blksz;
		}
		blknr = __le32_to_cpu (indir2_block[rblock % perblock]);
#ifdef CFG_OPTIMIZE_EXT2_READ
               rbcnt = rblock % perblock;
               while(((__le32_to_cpu (indir2_block[rbcnt + 1]) - \
                       __le32_to_cpu (indir2_block[rbcnt])) == 1) && (rbcnt < (blksz - 1))) {
                       rbcnt++;
                       *stream += 1;
               }
#endif
	}
	/* Tripple indirect.  */
	else {
		printf ("** ext2fs doesn't support tripple indirect blocks. **\n");
		return (-1);
	}
#ifdef DEBUG
	printf ("ext2fs_read_block %08x\n", blknr);
#endif
	return (blknr);
}

#ifdef CFG_OPTIMIZE_EXT2_READ
int ext2fs_read_file
       (ext2fs_node_t node, int pos, unsigned int len, char *buf) {
       int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data);
       int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
       unsigned int filesize = __le32_to_cpu(node->inode.size);
       int blknr;
       int blockend;
       int status;
       int remain = len;
       char *buffer = buf;
       int stream = 0;
       int cur = pos / blocksize;
       int blockoff = pos % blocksize;

       /* Adjust len so it we can't read past the end of the file.  */
       if (len > filesize) {
               len = filesize;
       }

       while (remain > 0) {
               blknr = ext2fs_read_block (node, cur, &stream);
               if (blknr < 0) {
                       return (-1);
               }
               blknr = blknr << log2blocksize; 
       
               if(remain < blocksize * stream) {
                       blockend = remain;
               } else {
                       blockend = blocksize * stream;
               }
               
               status = ext2fs_devread (blknr, blockoff, blockend, buffer);
               if (status == 0) {
                       return (-1);
               }
       
               remain -= blockend;
               buffer += blockend;
               cur += stream;
               blockoff = 0;
       
               if(remain == 0)
                       return (len);
               else if(remain < 0)
                       return (-1);
       }
       return (len);
}