Beispiel #1
0
static int ext4_read_super(struct super_block *sb, void *data, int flags)
{
	int ret;
	struct inode *in;
	struct dentry *root;

	ret = ext4_fill_super(sb);
	if (ret < 0) {
		// ...
		return ret;
	}

	GEN_DBG("\n");

	in = ext4_iget(sb, 2);
	if (!in) {
		// ...
		return -EINVAL;
	}

	root = d_make_root(in);
	if (!root)
		return EINVAL;

	sb->s_root = root;

	return 0;
}
Beispiel #2
0
static int __flash_erase(struct mtd_info *mtd, struct erase_info *opt)
{
	int ret;
#if 0
	struct erase_info opt;

	memset(&opt, 0, sizeof(opt));

	opt.estart = start;
	opt.esize  = size;
	opt.flags  = flags;
#endif

	if (opt->len & (mtd->erase_size - 1)) {
#ifdef CONFIG_DEBUG
		size_t size = opt->len;
#endif

		ALIGN_UP(opt->len, mtd->erase_size);
		GEN_DBG("size (0x%08x) not aligned with mtd erase size (0x%08x)!"
			" adjusted to 0x%08x\n",
			size, mtd->erase_size, opt->len);
	}

	ret = mtd->erase(mtd, opt);

#ifdef CONFIG_DEBUG
	if (ret < 0)
		printf("%s() failed! (errno = %d)\n", __func__, ret);
#endif

	return ret;
}
Beispiel #3
0
static int __extent_idx(struct ext4_extent_header *extent_header)
{
	// fixme
	GEN_DBG("extent_idx not support\n");

	return 0;
}
Beispiel #4
0
static int ext4_dx_readdir(struct file *fp, void *dirent, filldir_t filldir)
{
	// fixme

	GEN_DBG("Not support dx read!\n");

	return 0;
}
Beispiel #5
0
static int ext4_get_extent_blkbums(struct inode *in, size_t skip, __le32 block[], size_t nums)
{
	struct ext4_inode *ext4_in;
	struct ext4_inode_info *ext4_ini;
	struct ext4_extent_header *extent_header;
	struct ext4_extent *extent;
	struct ext4_extent_idx *extent_idx;
	int i;
	int iter;

	ext4_ini = EXT4_I(in);
	ext4_in  = ext4_ini->i_e4in;

	extent_header = (struct ext4_extent_header *)ext4_in->i_block;
	if (extent_header->eh_magic != EXT4_EXT_MAGIC) {
		GEN_DBG("check extent magic num error!\n");
		return -EINVAL;
	}

	if (extent_header->eh_depth > 0) {
		extent_idx = (void *)extent_header + sizeof(*extent_header);
		for (i = 0; i < extent_header->eh_entries; i++) {
			// ...
			__extent_idx(extent_header);
			extent_idx += sizeof(*extent_idx);
		}

		return 0;
	}

	extent = (void *)extent_header + sizeof(*extent_header);
	i = 0;
	iter = 0;

	while (i < extent_header->eh_entries) {
		size_t start = extent->ee_block;
		size_t len   = extent->ee_len;
		size_t addr  = extent->ee_start_lo; // fixme

		while (iter < nums &&
				(iter + skip) >= start &&
				(iter + skip) < (start + len)) {
			block[iter] = addr + (iter + skip - start);
			iter++;
		}

		if (iter == nums) {
			break;
		}

		extent += sizeof(*extent);
		i++;
	}

	return 0;
}
Beispiel #6
0
char * GAPI getcwd(char *buff, size_t size)
{
	long ret;
	size_t max_size = min(size, PATH_MAX);

	ret = sys_getcwd(buff, max_size);
	if (ret < 0) {
		GEN_DBG("ret = %d\n", ret);
		return NULL;
	}

	return buff;
}
Beispiel #7
0
static ssize_t ext4_read(struct file *fp, void *buff, size_t size, loff_t *off)
{
	struct inode *in;
	struct dentry *de;
	size_t cur_blk;
	size_t offset;
	size_t blks;
	__le32 blk_num[(size - 1) / fp->f_dentry->d_sb->s_blocksize + 2];
	size_t blk_size = fp->f_dentry->d_sb->s_blocksize;
	int ret;
	int i = 0;
	size_t count = 0;

	de = fp->f_dentry;
	in = de->d_inode;

	if (fp->f_pos >= in->i_size)
		return 0;

	cur_blk = fp->f_pos / in->i_sb->s_blocksize;
	offset  = fp->f_pos % in->i_sb->s_blocksize;

	if (offset != 0) {
		blks = (size - (blk_size - offset) - 1) / blk_size + 2;
	} else {
		blks = (size - 1) / blk_size + 1;
	}

	ret = ext4_get_blknums(in, cur_blk, blk_num, blks);
	if (ret < 0) {
		GEN_DBG("Fail to get blk num 0x%x\n", cur_blk);
		return ret;
	}

	if (offset != 0) {
		__ext4_read_buff(in->i_sb, blk_num[0] * blk_size, buff, blk_size - (offset + 1));
		count += blk_size - (offset + 1);
		i = 1;
	}

	for (; i < blks - 1; i++) {
		__ext4_read_block(in->i_sb, buff + i * blk_size, blk_num[i]);
		count += blk_size;
	}

	__ext4_read_buff(in->i_sb, blk_num[i] * blk_size, buff + count, size - count);

	fp->f_pos += size;

	return size;
}
Beispiel #8
0
static unsigned long ext4_inode_by_name(struct inode *inode, struct qstr *unit)
{
	struct super_block *sb = inode->i_sb;
	struct ext4_sb_info *e4_sbi;
	struct ext4_inode_info *e4_ini = EXT4_I(inode);
	struct ext4_dir_entry_2 *e4_de;
	struct ext4_inode *parent = e4_ini->i_e4in;
	char buff[inode->i_sb->s_blocksize];
	size_t len = 0;
	int blocks, i;
	size_t block_size;

	e4_sbi = sb->s_fs_info;
	block_size = 1024 << e4_sbi->e4_sb.s_log_block_size;

	blocks = (parent->i_size_lo + block_size - 1) / block_size;
	__le32 block_indexs[blocks];

	ext4_get_blknums(inode, 0, block_indexs, blocks);

	for (i = 0; i < blocks; i++) {
		__ext4_read_block(sb, buff, block_indexs[i]);

		e4_de = (struct ext4_dir_entry_2 *)buff;

		while (e4_de->rec_len > 0 && len < parent->i_size_lo && len < (i + 1) * block_size) {
			e4_de->name[e4_de->name_len] = '\0';

			DPRINT("%s: inode = %d, e4_de size = %d, name size = %d, block = %d\n",
				e4_de->name, e4_de->inode, e4_de->rec_len, e4_de->name_len, i);

			if (unit->len == e4_de->name_len && \
				!strncmp(e4_de->name, unit->name, e4_de->name_len))
				return  e4_de->inode;

			e4_de = (struct ext4_dir_entry_2 *)((char *)e4_de + e4_de->rec_len);
			len += e4_de->rec_len;
		}
	}

	GEN_DBG("\"%s\" not found!\n", unit->name);

	return 0;
}
Beispiel #9
0
static int ext4_readdir(struct file *fp, void *dirent, filldir_t filldir)
{
	struct inode *in;
	struct dentry *de;
	size_t cur_blk;
	size_t offset;
	__le32 blk_num;
	int ret;
	char blk_buff[fp->f_dentry->d_sb->s_blocksize];
	struct ext4_dir_entry_2 *ext4_de;

	de = fp->f_dentry;
	in = de->d_inode;

	if (is_hbtree_dir(in)) {
		return ext4_dx_readdir(fp, dirent, filldir);
	}

	if (fp->f_pos >= in->i_size)
		return 0;

	cur_blk = fp->f_pos / in->i_sb->s_blocksize;
	offset  = fp->f_pos % in->i_sb->s_blocksize;

	ret = ext4_get_blknums(in, cur_blk, &blk_num, 1);
	if (ret < 0) {
		GEN_DBG("Fail to get blk num 0x%x\n", cur_blk);
		return ret;
	}

	__ext4_read_block(in->i_sb, blk_buff, blk_num);

	ext4_de = (struct ext4_dir_entry_2 *)(blk_buff + offset);
	filldir(dirent, ext4_de->name, ext4_de->name_len, ext4_de->rec_len, ext4_de->inode, ext4_de->file_type);

	fp->f_pos += ext4_de->rec_len;

	return ext4_de->rec_len;
}
Beispiel #10
0
image_t image_type_detect(const void *data, size_t size)
{
    if (GTH_MAGIC == *(const __u32 *)(data + GTH_MAGIC_OFFSET)) {
        GEN_DBG("witrom image\n");
        return IMG_GTH;
    }

    if (GBH_MAGIC == *(const __u32 *)(data + GBH_MAGIC_OFFSET)) {
        GEN_DBG("g-bios image\n");
        return IMG_GBH;
    }

    if (LINUX_MAGIC == *(const __u32 *)(data + LINUX_MAGIC_OFFSET)) {
        GEN_DBG("Linux kernel image\n");
        return IMG_LINUX;
    }

    if (JFFS2_MAGIC == *(const __u16 *)(data + JFFS2_MAGIC_OFFSET)) {
        GEN_DBG("JFFS2 image\n");
        return IMG_JFFS2;
    }

    if (UBIFS_MAGIC == *(const __u32 *)(data + UBIFS_MAGIC_OFFSET)) {
        GEN_DBG("UBIFS image\n");
        return IMG_UBIFS;
    }

    if (check_yaffs1_image(data + YAFFS_OOB_SIZE)) {
        GEN_DBG("YAFFS1 image\n");
        return IMG_YAFFS1;
    }

    // TODO: check other image types
    GEN_DBG("Unknown image type!\n");
    return IMG_UNKNOWN;
}
Beispiel #11
0
int i2c_write_byte (__u8 addr, __u8 reg, __u8 val)
{
	int errno = 0, to;
	__u16 stat;

	omap_i2c_outw(0xFFFF, I2C_STAT);

	for (to = 0; to < I2C_TIMEOUT; to++) {
		stat = omap_i2c_inw(I2C_STAT);
		if (!(stat & I2C_STAT_BB))
			break;

		omap_i2c_outw(stat, I2C_STAT);
		udelay (50000);
	}

	if (I2C_TIMEOUT == to) {
		GEN_DBG("I2C bus busy! stat = 0x%08x\n", stat);
		return -EBUSY;
	}

	omap_i2c_outw(0xFFFF, I2C_STAT);

	omap_i2c_outw(2, I2C_CNT);
	omap_i2c_outw(addr, I2C_SA);
	omap_i2c_outw(0x8603, I2C_CON);

	stat = i2c_wait_ready();
	if (!(stat & I2C_STAT_XRDY))
		return -ETIMEDOUT;

	omap_i2c_outb(reg, I2C_DATA);
	omap_i2c_outw(I2C_STAT_XRDY, I2C_STAT);

	stat = i2c_wait_ready();
	if (!(stat & I2C_STAT_XRDY))
		return -ETIMEDOUT;

	omap_i2c_outb(val, I2C_DATA);
	omap_i2c_outw(I2C_STAT_XRDY, I2C_STAT);

	udelay (50000);
	stat = omap_i2c_inw(I2C_STAT);
	if (stat & I2C_STAT_NACK)
		return -EIO;

	to = 200;
	omap_i2c_outw(I2C_CON_EN, I2C_CON);
	while ((stat = omap_i2c_inw(I2C_STAT)) || \
		(omap_i2c_inw(I2C_CON) & I2C_CON_MST)) {
		udelay (1000);
		omap_i2c_outw(0xFFFF, I2C_STAT);

		to--;
		if(to == 0)
			break;
	}

	i2c_flush();
	omap_i2c_outw(0xFFFF, I2C_STAT);
	omap_i2c_outw(0, I2C_CNT);

	return errno;
}
Beispiel #12
0
static int ext4_fill_super(struct super_block *sb)
{
	int ret;
	int group_count;
	unsigned int bpg; // blocks per groups
	char buff[KB(1)];
	struct ext4_sb_info *e4_sbi;
	struct ext4_super_block *e4_sb;
	struct ext4_group_desc *gdt;
	struct bio *bio;
	size_t off;

	bio = bio_alloc();
	if (!bio)
		return -ENOMEM;

	bio->bdev = sb->s_bdev;
	bio->sect = 1024 / SECT_SIZE;
	bio->size = sizeof(buff);
	bio->data = buff;
	submit_bio(READ, bio);
	// TODO: check flags here
	bio_free(bio);

	if (ext4_check_fstype(buff, sizeof(struct ext4_super_block)) == false) {
		GEN_DBG("Invalid EXT4 magic number!\n"); // ((struct ext4_super_block *)buff)->s_magic);
		ret = -EINVAL;
		goto L1;
	}

	e4_sbi = zalloc(sizeof(*e4_sbi));
	if (!e4_sbi) {
		ret = -ENOMEM;
		goto L1;
	}

#if 1 // fixme
	e4_sb = &e4_sbi->e4_sb;
	memcpy(e4_sb, buff, sizeof(*e4_sb));
#endif

	sb->s_fs_info = e4_sbi;
	sb->s_blocksize = 1024 << e4_sb->s_log_block_size;

	bpg = e4_sb->s_blocks_per_group;
	group_count = (e4_sb->s_blocks_count_lo + bpg - 1) / bpg;
	DPRINT("super block information:\n"
		"label = \"%s\", inode size = %d, block size = %d\n",
		e4_sb->s_volume_name[0] ? e4_sb->s_volume_name : "<N/A>",
		e4_sb->s_inode_size, sb->s_blocksize);

	gdt = malloc(group_count * sizeof(struct ext4_group_desc));
	if (NULL == gdt) {
		ret = -ENOMEM;
		goto L2;
	}
	e4_sbi->gdt = gdt;
	off = (e4_sb->s_first_data_block + 1) * sb->s_blocksize;

	__ext4_read_buff(sb, off, gdt, group_count * sizeof(struct ext4_group_desc));

	DPRINT("group descrition:\n"
		"block groups = %d, free blocks = %d, free inodes = %d\n",
		group_count, gdt->bg_free_blocks_count_lo, gdt->bg_free_inodes_count_lo);

	return 0;

L2:
	free(e4_sbi);
L1:
	return ret;
}