Example #1
0
errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
				 void *inbuf)
{
	errcode_t	retval;
	char		*p, *end, *write_buf;
	char		*buf = 0;
	struct ext2_dir_entry *dirent;

	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) {
		write_buf = buf = malloc(fs->blocksize);
		if (!buf)
			return ENOMEM;
		memcpy(buf, inbuf, fs->blocksize);
		p = buf;
		end = buf + fs->blocksize;
		while (p < end) {
			dirent = (struct ext2_dir_entry *) p;
			p += (dirent->rec_len < 8) ? 8 : dirent->rec_len;
			dirent->inode = ext2fs_swab32(dirent->inode);
			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
			dirent->name_len = ext2fs_swab16(dirent->name_len);
		}
	} else
		write_buf = inbuf;
 	retval = io_channel_write_blk(fs->io, block, 1, write_buf);
	if (buf)
		free(buf);
	return retval;
}
Example #2
0
void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
{
	/* Do the 32-bit parts first */
	gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
	gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
	gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
	gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
	gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
	gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
	gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused);
	gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
	/* If we're 32-bit, we're done */
	if (fs && (!fs->super->s_desc_size ||
		   (fs->super->s_desc_size < EXT2_MIN_DESC_SIZE_64BIT)))
		return;

	/* Swap the 64-bit parts */
	struct ext4_group_desc *gdp4 = (struct ext4_group_desc *) gdp;
	gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi);
	gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi);
	gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi);
	gdp4->bg_free_blocks_count_hi =
		ext2fs_swab16(gdp4->bg_free_blocks_count_hi);
	gdp4->bg_free_inodes_count_hi =
		ext2fs_swab16(gdp4->bg_free_inodes_count_hi);
	gdp4->bg_used_dirs_count_hi =
		ext2fs_swab16(gdp4->bg_used_dirs_count_hi);
	gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi);
}
Example #3
0
void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
{
	gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
	gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
	gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
	gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
	gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
}
errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
				  void *inbuf, int flags EXT2FS_ATTR((unused)))
{
#if BB_BIG_ENDIAN
	int		do_swap = 0;
	errcode_t	retval;
	char		*p, *end;
	char		*buf = 0;
	struct ext2_dir_entry *dirent;

	if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
	    (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
		do_swap = 1;

#ifndef WORDS_BIGENDIAN
	if (!do_swap)
		return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
#endif

	retval = ext2fs_get_mem(fs->blocksize, &buf);
	if (retval)
		return retval;
	memcpy(buf, inbuf, fs->blocksize);
	p = buf;
	end = buf + fs->blocksize;
	while (p < end) {
		dirent = (struct ext2_dir_entry *) p;
		if ((dirent->rec_len < 8) ||
		    (dirent->rec_len % 4)) {
			ext2fs_free_mem(&buf);
			return EXT2_ET_DIR_CORRUPTED;
		}
		p += dirent->rec_len;
		if (do_swap) {
			dirent->inode = ext2fs_swab32(dirent->inode);
			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
			dirent->name_len = ext2fs_swab16(dirent->name_len);
		}
#ifdef WORDS_BIGENDIAN
		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
			dirent->name_len = ext2fs_swab16(dirent->name_len);
#endif
	}
	retval = io_channel_write_blk(fs->io, block, 1, buf);
	ext2fs_free_mem(&buf);
	return retval;
#else
	return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
#endif
}
Example #5
0
void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from)
{
	struct ext2_ext_attr_header *from_header =
		(struct ext2_ext_attr_header *)from;
	struct ext2_ext_attr_header *to_header =
		(struct ext2_ext_attr_header *)to;
	struct ext2_ext_attr_entry *from_entry, *to_entry;
	char *from_end = (char *)from_header + fs->blocksize;
	int n;

	if (to_header != from_header)
		memcpy(to_header, from_header, fs->blocksize);

	to_header->h_magic    = ext2fs_swab32(from_header->h_magic);
	to_header->h_blocks   = ext2fs_swab32(from_header->h_blocks);
	to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
	for (n=0; n<4; n++)
		to_header->h_reserved[n] =
			ext2fs_swab32(from_header->h_reserved[n]);
	
	from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
	to_entry   = (struct ext2_ext_attr_entry *)(to_header+1);
	while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
		to_entry->e_value_offs  =	
			ext2fs_swab16(from_entry->e_value_offs);
		to_entry->e_value_block =	
			ext2fs_swab32(from_entry->e_value_block);
		to_entry->e_value_size  =	
			ext2fs_swab32(from_entry->e_value_size);
		from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
		to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);
	}
}
void ext2fs_swap_mmp(struct mmp_struct *mmp)
{
	mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic);
	mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq);
	mmp->mmp_time = ext2fs_swab64(mmp->mmp_time);
	mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval);
}
int main(int argc, char **argv)
{
	int	i;
	int	errors = 0;

	printf("Testing ext2fs_swab16\n");
	i=0;
	do {
		printf("swab16(0x%04x) = 0x%04x\n", test1[i],
		       ext2fs_swab16(test1[i]));
		if (ext2fs_swab16(test1[i]) != test1[i+1]) {
			printf("Error!!!   %04x != %04x\n",
			       ext2fs_swab16(test1[i]), test1[i+1]);
			errors++;
		}
		if (ext2fs_swab16(test1[i+1]) != test1[i]) {
			printf("Error!!!   %04x != %04x\n",
			       ext2fs_swab16(test1[i+1]), test1[i]);
			errors++;
		}
		i += 2;
	} while (test1[i] != 0);

	printf("Testing ext2fs_swab32\n");
	i = 0;
	do {
		printf("swab32(0x%08x) = 0x%08x\n", test2[i],
		       ext2fs_swab32(test2[i]));
		if (ext2fs_swab32(test2[i]) != test2[i+1]) {
			printf("Error!!!   %04x != %04x\n",
			       ext2fs_swab32(test2[i]), test2[i+1]);
			errors++;
		}
		if (ext2fs_swab32(test2[i+1]) != test2[i]) {
			printf("Error!!!   %04x != %04x\n",
			       ext2fs_swab32(test2[i+1]), test2[i]);
			errors++;
		}
		i += 2;
	} while (test2[i] != 0);

	if (!errors)
		printf("No errors found in the byteswap implementation!\n");

	return errors;
}
Example #8
0
void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
				struct ext2_ext_attr_entry *from_entry)
{
	to_entry->e_value_offs  = ext2fs_swab16(from_entry->e_value_offs);
	to_entry->e_value_block = ext2fs_swab32(from_entry->e_value_block);
	to_entry->e_value_size  = ext2fs_swab32(from_entry->e_value_size);
	to_entry->e_hash	= ext2fs_swab32(from_entry->e_hash);
}
errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
				 void *buf, int flags EXT2FS_ATTR((unused)))
{
	errcode_t	retval;
	char		*p, *end;
	struct ext2_dir_entry *dirent;
	unsigned int	name_len, rec_len;
#if BB_BIG_ENDIAN
	unsigned int do_swap;
#endif

	retval = io_channel_read_blk(fs->io, block, 1, buf);
	if (retval)
		return retval;
#if BB_BIG_ENDIAN
	do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
				EXT2_FLAG_SWAP_BYTES_READ)) != 0;
#endif
	p = (char *) buf;
	end = (char *) buf + fs->blocksize;
	while (p < end-8) {
		dirent = (struct ext2_dir_entry *) p;
#if BB_BIG_ENDIAN
		if (do_swap) {
			dirent->inode = ext2fs_swab32(dirent->inode);
			dirent->rec_len = ext2fs_swab16(dirent->rec_len);
			dirent->name_len = ext2fs_swab16(dirent->name_len);
		}
#endif
		name_len = dirent->name_len;
#ifdef WORDS_BIGENDIAN
		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
			dirent->name_len = ext2fs_swab16(dirent->name_len);
#endif
		rec_len = dirent->rec_len;
		if ((rec_len < 8) || (rec_len % 4)) {
			rec_len = 8;
			retval = EXT2_ET_DIR_CORRUPTED;
		}
		if (((name_len & 0xFF) + 8) > dirent->rec_len)
			retval = EXT2_ET_DIR_CORRUPTED;
		p += rec_len;
	}
	return retval;
}
Example #10
0
void ext2fs_swap_super(struct ext2_super_block * sb)
{
  	int i;
	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
	sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
	sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
	sb->s_magic = ext2fs_swab16(sb->s_magic);
	sb->s_state = ext2fs_swab16(sb->s_state);
	sb->s_errors = ext2fs_swab16(sb->s_errors);
	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
	sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
	sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
	sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
	for (i=0; i < 4; i++)
		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
}
Example #11
0
errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
				  void *inbuf, int flags EXT2FS_ATTR((unused)))
{
#ifdef WORDS_BIGENDIAN
	errcode_t	retval;
	char		*p, *end;
	char		*buf = 0;
	unsigned int	rec_len;
	struct ext2_dir_entry *dirent;

	retval = ext2fs_get_mem(fs->blocksize, &buf);
	if (retval)
		return retval;
	memcpy(buf, inbuf, fs->blocksize);
	p = buf;
	end = buf + fs->blocksize;
	while (p < end) {
		dirent = (struct ext2_dir_entry *) p;
		if ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
			return retval;
		if ((rec_len < 8) ||
		    (rec_len % 4)) {
			ext2fs_free_mem(&buf);
			return (EXT2_ET_DIR_CORRUPTED);
		}
		p += rec_len;
		dirent->inode = ext2fs_swab32(dirent->inode);
		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
		dirent->name_len = ext2fs_swab16(dirent->name_len);

		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
			dirent->name_len = ext2fs_swab16(dirent->name_len);
	}
	retval = io_channel_write_blk64(fs->io, block, 1, buf);
	ext2fs_free_mem(&buf);
	return retval;
#else
	return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
#endif
}
Example #12
0
errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
				 void *buf, int flags EXT2FS_ATTR((unused)))
{
	errcode_t	retval;
	char		*p, *end;
	struct ext2_dir_entry *dirent;
	unsigned int	name_len, rec_len;


	retval = io_channel_read_blk64(fs->io, block, 1, buf);
	if (retval)
		return retval;

	p = (char *) buf;
	end = (char *) buf + fs->blocksize;
	while (p < end-8) {
		dirent = (struct ext2_dir_entry *) p;
#ifdef WORDS_BIGENDIAN
		dirent->inode = ext2fs_swab32(dirent->inode);
		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
		dirent->name_len = ext2fs_swab16(dirent->name_len);
#endif
		name_len = dirent->name_len;
#ifdef WORDS_BIGENDIAN
		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
			dirent->name_len = ext2fs_swab16(dirent->name_len);
#endif
		if ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
			return retval;
		if ((rec_len < 8) || (rec_len % 4)) {
			rec_len = 8;
			retval = EXT2_ET_DIR_CORRUPTED;
		} else if (((name_len & 0xFF) + 8) > rec_len)
			retval = EXT2_ET_DIR_CORRUPTED;
		p += rec_len;
	}
	return retval;
}
Example #13
0
errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
				void *buf)
{
	errcode_t	retval;
	char		*p, *end;
	struct ext2_dir_entry *dirent;

 	retval = io_channel_read_blk(fs->io, block, 1, buf);
	if (retval)
		return retval;
	if ((fs->flags & (EXT2_FLAG_SWAP_BYTES|
			  EXT2_FLAG_SWAP_BYTES_READ)) == 0)
		return 0;
	p = buf;
	end = (char *) buf + fs->blocksize;
	while (p < end) {
		dirent = (struct ext2_dir_entry *) p;
		dirent->inode = ext2fs_swab32(dirent->inode);
		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
		dirent->name_len = ext2fs_swab16(dirent->name_len);
		p += (dirent->rec_len < 8) ? 8 : dirent->rec_len;
	}
	return 0;
}
Example #14
0
static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
				    blk_t group_block,
				    struct ext2_super_block *super_shadow)
{
	dgrp_t	sgrp = group;

	if (sgrp > ((1 << 16) - 1))
		sgrp = (1 << 16) - 1;
#if defined(WORDS_BIGENDIAN) || (BYTE_ORDER == BIG_ENDIAN)
	super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
#else
	fs->super->s_block_group_nr = sgrp;
#endif

	return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE,
				    super_shadow);
}
Example #15
0
static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
				    blk_t group_block,
				    struct ext2_super_block *super_shadow)
{
	dgrp_t	sgrp = group;

	if (sgrp > ((1 << 16) - 1))
		sgrp = (1 << 16) - 1;
#if BB_BIG_ENDIAN
	if (fs->flags & EXT2_FLAG_SWAP_BYTES)
		super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
	else
#endif
		fs->super->s_block_group_nr = sgrp;

	return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE,
				    super_shadow);
}
Example #16
0
void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
		       struct ext2_inode *f, int hostorder)
{
	unsigned i;
	int islnk = 0;
	
	if (hostorder && LINUX_S_ISLNK(f->i_mode))
		islnk = 1;
	t->i_mode = ext2fs_swab16(f->i_mode);
	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
		islnk = 1;
	t->i_uid = ext2fs_swab16(f->i_uid);
	t->i_size = ext2fs_swab32(f->i_size);
	t->i_atime = ext2fs_swab32(f->i_atime);
	t->i_ctime = ext2fs_swab32(f->i_ctime);
	t->i_mtime = ext2fs_swab32(f->i_mtime);
	t->i_dtime = ext2fs_swab32(f->i_dtime);
	t->i_gid = ext2fs_swab16(f->i_gid);
	t->i_links_count = ext2fs_swab16(f->i_links_count);
	t->i_blocks = ext2fs_swab32(f->i_blocks);
	t->i_flags = ext2fs_swab32(f->i_flags);
	if (!islnk || f->i_blocks) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
	} else if (t != f) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = f->i_block[i];
	}
	t->i_generation = ext2fs_swab32(f->i_generation);
	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
	t->i_faddr = ext2fs_swab32(f->i_faddr);

	switch (fs->super->s_creator_os) {
	case EXT2_OS_LINUX:
		t->osd1.linux1.l_i_reserved1 =
			ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
		t->osd2.linux2.l_i_uid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
		t->osd2.linux2.l_i_gid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
		t->osd2.linux2.l_i_reserved2 =
			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
		break;
	case EXT2_OS_HURD:
		t->osd1.hurd1.h_i_translator =
		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
		t->osd2.hurd2.h_i_mode_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
		t->osd2.hurd2.h_i_uid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
		t->osd2.hurd2.h_i_gid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
		t->osd2.hurd2.h_i_author =
		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
		break;
	case EXT2_OS_MASIX:
		t->osd1.masix1.m_i_reserved1 =
			ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
		t->osd2.masix2.m_i_reserved2[0] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
		t->osd2.masix2.m_i_reserved2[1] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
		break;
	}
}
Example #17
0
static void dump_journal(char *cmdname, FILE *out_file, 
			 struct journal_source *source)
{
	struct ext2_super_block *sb;
	char			jsb_buffer[1024];
	char			buf[8192];
	journal_superblock_t	*jsb;
	unsigned int		blocksize = 1024;
	unsigned int		got;
	int			retval;
	__u32			magic, sequence, blocktype;
	journal_header_t	*header;
	
	tid_t			transaction;
	unsigned int		blocknr = 0;
	
	/* First, check to see if there's an ext2 superblock header */
	retval = read_journal_block(cmdname, source, 0, 
				    buf, 2048, &got);
	if (retval)
		return;

	jsb = (journal_superblock_t *) buf;
	sb = (struct ext2_super_block *) (buf+1024);
#ifdef ENABLE_SWAPFS
	if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) 
		ext2fs_swap_super(sb);
#endif
	
	if ((be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) &&
	    (sb->s_magic == EXT2_SUPER_MAGIC) &&
	    (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
		blocksize = EXT2_BLOCK_SIZE(sb);
		blocknr = (blocksize == 1024) ? 2 : 1;
		uuid_unparse(sb->s_uuid, jsb_buffer);
		fprintf(out_file, "Ext2 superblock header found.\n");
		if (dump_all) {
			fprintf(out_file, "\tuuid=%s\n", jsb_buffer);
			fprintf(out_file, "\tblocksize=%d\n", blocksize);
			fprintf(out_file, "\tjournal data size %ld\n",
				(long) sb->s_blocks_count);
		}
	}
	
	/* Next, read the journal superblock */

	retval = read_journal_block(cmdname, source, blocknr*blocksize, 
				    jsb_buffer, 1024, &got);
	if (retval)
		return;

	jsb = (journal_superblock_t *) jsb_buffer;
	if (be32_to_cpu(jsb->s_header.h_magic) != JFS_MAGIC_NUMBER) {
		fprintf(out_file,
			"Journal superblock magic number invalid!\n");
		return;
	}
	blocksize = be32_to_cpu(jsb->s_blocksize);
	transaction = be32_to_cpu(jsb->s_sequence);
	blocknr = be32_to_cpu(jsb->s_start);

	fprintf(out_file, "Journal starts at block %u, transaction %u\n",
		blocknr, transaction);

	if (!blocknr)
		/* Empty journal, nothing to do. */
		return;
		
	while (1) {
		retval = read_journal_block(cmdname, source, 
					    blocknr*blocksize, buf,
					    blocksize, &got);
		if (retval || got != blocksize)
			return;
	
		header = (journal_header_t *) buf;

		magic = be32_to_cpu(header->h_magic);
		sequence = be32_to_cpu(header->h_sequence);
		blocktype = be32_to_cpu(header->h_blocktype);
		
		if (magic != JFS_MAGIC_NUMBER) {
			fprintf (out_file, "No magic number at block %u: "
				 "end of journal.\n", blocknr);
			return;
		}
		
		if (sequence != transaction) {
			fprintf (out_file, "Found sequence %u (not %u) at "
				 "block %u: end of journal.\n", 
				 sequence, transaction, blocknr);
			return;
		}

		if (dump_descriptors) {
			fprintf (out_file, "Found expected sequence %u, "
				 "type %u (%s) at block %u\n",
				 sequence, blocktype, 
				 type_to_name(blocktype), blocknr);
		}
		
		switch (blocktype) {
		case JFS_DESCRIPTOR_BLOCK:
			dump_descriptor_block(out_file, source, buf, jsb, 
					      &blocknr, blocksize,
					      transaction);
			continue;

		case JFS_COMMIT_BLOCK:
			transaction++;
			blocknr++;
			WRAP(jsb, blocknr);
			continue;
			
		case JFS_REVOKE_BLOCK:
			dump_revoke_block(out_file, buf, jsb,
					  blocknr, blocksize, 
					  transaction);
			blocknr++;
			WRAP(jsb, blocknr);
			continue;

		default:
			fprintf (out_file, "Unexpected block type %u at "
				 "block %u.\n", blocktype, blocknr);
			return;
		}
	}
}
Example #18
0
static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
{
	struct process_block_struct pb;
	struct ext2_super_block *sb = ctx->fs->super;
	struct ext2_super_block jsuper;
	struct problem_context	pctx;
	struct buffer_head 	*bh;
	struct inode		*j_inode = NULL;
	struct kdev_s		*dev_fs = NULL, *dev_journal;
	const char		*journal_name = 0;
	journal_t		*journal = NULL;
	errcode_t		retval = 0;
	io_manager		io_ptr = 0;
	unsigned long long	start = 0;
	int			ext_journal = 0;
	int			tried_backup_jnl = 0;

	clear_problem_context(&pctx);

	journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
	if (!journal) {
		return EXT2_ET_NO_MEMORY;
	}

	dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
	if (!dev_fs) {
		retval = EXT2_ET_NO_MEMORY;
		goto errout;
	}
	dev_journal = dev_fs+1;

	dev_fs->k_ctx = dev_journal->k_ctx = ctx;
	dev_fs->k_dev = K_DEV_FS;
	dev_journal->k_dev = K_DEV_JOURNAL;

	journal->j_dev = dev_journal;
	journal->j_fs_dev = dev_fs;
	journal->j_inode = NULL;
	journal->j_blocksize = ctx->fs->blocksize;

	if (uuid_is_null(sb->s_journal_uuid)) {
		if (!sb->s_journal_inum) {
			retval = EXT2_ET_BAD_INODE_NUM;
			goto errout;
		}
		j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
						 "journal inode");
		if (!j_inode) {
			retval = EXT2_ET_NO_MEMORY;
			goto errout;
		}

		j_inode->i_ctx = ctx;
		j_inode->i_ino = sb->s_journal_inum;

		if ((retval = ext2fs_read_inode(ctx->fs,
						sb->s_journal_inum,
						&j_inode->i_ext2))) {
		try_backup_journal:
			if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
			    tried_backup_jnl)
				goto errout;
			memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
			memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
			       EXT2_N_BLOCKS*4);
			j_inode->i_ext2.i_size_high = sb->s_jnl_blocks[15];
			j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
			j_inode->i_ext2.i_links_count = 1;
			j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
			e2fsck_use_inode_shortcuts(ctx, 1);
			ctx->stashed_ino = j_inode->i_ino;
			ctx->stashed_inode = &j_inode->i_ext2;
			tried_backup_jnl++;
		}
		if (!j_inode->i_ext2.i_links_count ||
		    !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
			retval = EXT2_ET_NO_JOURNAL;
			goto try_backup_journal;
		}
		if (EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize <
		    JFS_MIN_JOURNAL_BLOCKS) {
			retval = EXT2_ET_JOURNAL_TOO_SMALL;
			goto try_backup_journal;
		}
		pb.last_block = -1;
		retval = ext2fs_block_iterate3(ctx->fs, j_inode->i_ino,
					       BLOCK_FLAG_HOLE, 0,
					       process_journal_block, &pb);
		if ((pb.last_block + 1) * ctx->fs->blocksize <
		    (int) EXT2_I_SIZE(&j_inode->i_ext2)) {
			retval = EXT2_ET_JOURNAL_TOO_SMALL;
			goto try_backup_journal;
		}
		if (tried_backup_jnl && !(ctx->options & E2F_OPT_READONLY)) {
			retval = ext2fs_write_inode(ctx->fs, sb->s_journal_inum,
						    &j_inode->i_ext2);
			if (retval)
				goto errout;
		}

		journal->j_maxlen = EXT2_I_SIZE(&j_inode->i_ext2) /
			journal->j_blocksize;

#ifdef USE_INODE_IO
		retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
						 &j_inode->i_ext2,
						 &journal_name);
		if (retval)
			goto errout;

		io_ptr = inode_io_manager;
#else
		journal->j_inode = j_inode;
		ctx->journal_io = ctx->fs->io;
		if ((retval = (errcode_t) journal_bmap(journal, 0, &start)) != 0)
			goto errout;
#endif
	} else {
		ext_journal = 1;
		if (!ctx->journal_name) {
			char uuid[37];

			uuid_unparse(sb->s_journal_uuid, uuid);
			ctx->journal_name = blkid_get_devname(ctx->blkid,
							      "UUID", uuid);
			if (!ctx->journal_name)
				ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
		}
		journal_name = ctx->journal_name;

		if (!journal_name) {
			fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			goto errout;
		}

		jfs_debug(1, "Using journal file %s\n", journal_name);
		io_ptr = unix_io_manager;
	}

#if 0
	test_io_backing_manager = io_ptr;
	io_ptr = test_io_manager;
#endif
#ifndef USE_INODE_IO
	if (ext_journal)
#endif
	{
		int flags = IO_FLAG_RW;
		if (!(ctx->mount_flags & EXT2_MF_ISROOT &&
		      ctx->mount_flags & EXT2_MF_READONLY))
			flags |= IO_FLAG_EXCLUSIVE;
		if ((ctx->mount_flags & EXT2_MF_READONLY) &&
		    (ctx->options & E2F_OPT_FORCE))
			flags &= ~IO_FLAG_EXCLUSIVE;


		retval = io_ptr->open(journal_name, flags,
				      &ctx->journal_io);
	}
	if (retval)
		goto errout;

	io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);

	if (ext_journal) {
		blk64_t maxlen;

		start = ext2fs_journal_sb_start(ctx->fs->blocksize) - 1;
		bh = getblk(dev_journal, start, ctx->fs->blocksize);
		if (!bh) {
			retval = EXT2_ET_NO_MEMORY;
			goto errout;
		}
		ll_rw_block(READ, 1, &bh);
		if ((retval = bh->b_err) != 0) {
			brelse(bh);
			goto errout;
		}
		memcpy(&jsuper, start ? bh->b_data :  bh->b_data + SUPERBLOCK_OFFSET,
		       sizeof(jsuper));
#ifdef WORDS_BIGENDIAN
		if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
			ext2fs_swap_super(&jsuper);
#endif
		if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
		    !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
			fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			brelse(bh);
			goto errout;
		}
		/* Make sure the journal UUID is correct */
		if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
			   sizeof(jsuper.s_uuid))) {
			fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			brelse(bh);
			goto errout;
		}

		/* Check the superblock checksum */
		if (jsuper.s_feature_ro_compat &
		    EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
			struct struct_ext2_filsys fsx;
			struct ext2_super_block	superx;
			void *p;

			p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET;
			memcpy(&fsx, ctx->fs, sizeof(fsx));
			memcpy(&superx, ctx->fs->super, sizeof(superx));
			fsx.super = &superx;
			fsx.super->s_feature_ro_compat |=
					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
			if (!ext2fs_superblock_csum_verify(&fsx, p) &&
			    fix_problem(ctx, PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
					&pctx)) {
				ext2fs_superblock_csum_set(&fsx, p);
				mark_buffer_dirty(bh);
			}
		}
		brelse(bh);

		maxlen = ext2fs_blocks_count(&jsuper);
		journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1;
		start++;
	}

	if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
		retval = EXT2_ET_NO_MEMORY;
		goto errout;
	}

	journal->j_sb_buffer = bh;
	journal->j_superblock = (journal_superblock_t *)bh->b_data;

#ifdef USE_INODE_IO
	if (j_inode)
		ext2fs_free_mem(&j_inode);
#endif

	*ret_journal = journal;
	e2fsck_use_inode_shortcuts(ctx, 0);
	return 0;

errout:
	e2fsck_use_inode_shortcuts(ctx, 0);
	if (dev_fs)
		ext2fs_free_mem(&dev_fs);
	if (j_inode)
		ext2fs_free_mem(&j_inode);
	if (journal)
		ext2fs_free_mem(&journal);
	return retval;
}
Example #19
0
/*
 *  Note: if superblock is non-zero, block-size must also be non-zero.
 * 	Superblock and block_size can be zero to use the default size.
 *
 * Valid flags for ext2fs_open()
 * 
 * 	EXT2_FLAG_RW	- Open the filesystem for read/write.
 * 	EXT2_FLAG_FORCE - Open the filesystem even if some of the
 *				features aren't supported.
 *	EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
 */
errcode_t ext2fs_open2(const char *name, const char *io_options,
		       int flags, int superblock,
		       unsigned int block_size, io_manager manager, 
		       ext2_filsys *ret_fs)
{
	ext2_filsys	fs;
	errcode_t	retval;
	unsigned long	i;
	int		groups_per_block, blocks_per_group;
	blk_t		group_block, blk;
	char		*dest, *cp;
#ifdef EXT2FS_ENABLE_SWAPFS
	int j;
	struct ext2_group_desc *gdp;
#endif
	
	EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);

	retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
	if (retval)
		return retval;
	
	memset(fs, 0, sizeof(struct struct_ext2_filsys));
	fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
	fs->flags = flags;
	fs->umask = 022;
	retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
	if (retval)
		goto cleanup;
	strcpy(fs->device_name, name);
	cp = strchr(fs->device_name, '?');
	if (!io_options && cp) {
		*cp++ = 0;
		io_options = cp;
	}
		
	retval = manager->open(fs->device_name, 
			       (flags & EXT2_FLAG_RW) ? IO_FLAG_RW : 0,
			       &fs->io);
	if (retval)
		goto cleanup;
	if (io_options && 
	    (retval = io_channel_set_options(fs->io, io_options)))
		goto cleanup;
	fs->image_io = fs->io;
	fs->io->app_data = fs;
	retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
	if (retval)
		goto cleanup;
	if (flags & EXT2_FLAG_IMAGE_FILE) {
		retval = ext2fs_get_mem(sizeof(struct ext2_image_hdr),
					&fs->image_header);
		if (retval)
			goto cleanup;
		retval = io_channel_read_blk(fs->io, 0,
					     -(int)sizeof(struct ext2_image_hdr),
					     fs->image_header);
		if (retval)
			goto cleanup;
		if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
			return EXT2_ET_MAGIC_E2IMAGE;
		superblock = 1;
		block_size = fs->image_header->fs_blocksize;
	}

	/*
	 * If the user specifies a specific block # for the
	 * superblock, then he/she must also specify the block size!
	 * Otherwise, read the master superblock located at offset
	 * SUPERBLOCK_OFFSET from the start of the partition.
	 *
	 * Note: we only save a backup copy of the superblock if we
	 * are reading the superblock from the primary superblock location.
	 */
	if (superblock) {
		if (!block_size) {
			retval = EXT2_ET_INVALID_ARGUMENT;
			goto cleanup;
		}
		io_channel_set_blksize(fs->io, block_size);
		group_block = superblock;
		fs->orig_super = 0;
	} else {
		io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
		superblock = 1;
		group_block = 0;
		retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
		if (retval)
			goto cleanup;
	}
	retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
				     fs->super);
	if (retval)
		goto cleanup;
	if (fs->orig_super)
		memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);

#ifdef EXT2FS_ENABLE_SWAPFS
	if ((fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) ||
	    (fs->flags & EXT2_FLAG_SWAP_BYTES)) {
		fs->flags |= EXT2_FLAG_SWAP_BYTES;

		ext2fs_swap_super(fs->super);
	}
#endif
	
	if (fs->super->s_magic != EXT2_SUPER_MAGIC) {
		retval = EXT2_ET_BAD_MAGIC;
		goto cleanup;
	}
	if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
		retval = EXT2_ET_REV_TOO_HIGH;
		goto cleanup;
	}

	/*
	 * Check for feature set incompatibility
	 */
	if (!(flags & EXT2_FLAG_FORCE)) {
		if (fs->super->s_feature_incompat &
		    ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
			retval = EXT2_ET_UNSUPP_FEATURE;
			goto cleanup;
		}
		if ((flags & EXT2_FLAG_RW) &&
		    (fs->super->s_feature_ro_compat &
		     ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
			retval = EXT2_ET_RO_UNSUPP_FEATURE;
			goto cleanup;
		}
		if (!(flags & EXT2_FLAG_JOURNAL_DEV_OK) &&
		    (fs->super->s_feature_incompat &
		     EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
			retval = EXT2_ET_UNSUPP_FEATURE;
			goto cleanup;
		}
	}
	
	fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
	if (fs->blocksize == 0) {
		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
		goto cleanup;
	}
	fs->fragsize = EXT2_FRAG_SIZE(fs->super);
	fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
				       EXT2_INODE_SIZE(fs->super) +
				       EXT2_BLOCK_SIZE(fs->super) - 1) /
				      EXT2_BLOCK_SIZE(fs->super));
	if (block_size) {
		if (block_size != fs->blocksize) {
			retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
			goto cleanup;
		}
	}
	/*
	 * Set the blocksize to the filesystem's blocksize.
	 */
	io_channel_set_blksize(fs->io, fs->blocksize);

	/*
	 * If this is an external journal device, don't try to read
	 * the group descriptors, because they're not there.
	 */
	if (fs->super->s_feature_incompat &
	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
		fs->group_desc_count = 0;
		*ret_fs = fs;
		return 0;
	}
	
	/*
	 * Read group descriptors
	 */
	blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
	if (blocks_per_group == 0 ||
	    blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
	    fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
		retval = EXT2_ET_CORRUPT_SUPERBLOCK;
		goto cleanup;
	}
	fs->group_desc_count = (fs->super->s_blocks_count -
				fs->super->s_first_data_block +
				blocks_per_group - 1) / blocks_per_group;
	fs->desc_blocks = (fs->group_desc_count +
			   EXT2_DESC_PER_BLOCK(fs->super) - 1)
		/ EXT2_DESC_PER_BLOCK(fs->super);
	retval = ext2fs_get_mem(fs->desc_blocks * fs->blocksize,
				&fs->group_desc);
	if (retval)
		goto cleanup;
	if (!group_block)
		group_block = fs->super->s_first_data_block;
	dest = (char *) fs->group_desc;
	groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
	for (i=0 ; i < fs->desc_blocks; i++) {
		blk = ext2fs_descriptor_block_loc(fs, group_block, i);
		retval = io_channel_read_blk(fs->io, blk, 1, dest);
		if (retval)
			goto cleanup;
#ifdef EXT2FS_ENABLE_SWAPFS
		if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
			gdp = (struct ext2_group_desc *) dest;
			for (j=0; j < groups_per_block; j++)
				ext2fs_swap_group_desc(gdp++);
		}
#endif
		dest += fs->blocksize;
	}

	*ret_fs = fs;
	return 0;
cleanup:
	ext2fs_free(fs);
	return retval;
}
Example #20
0
void ext2fs_swap_super(struct ext2_super_block * sb)
{
  	int i;
	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
	sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
	sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
	sb->s_magic = ext2fs_swab16(sb->s_magic);
	sb->s_state = ext2fs_swab16(sb->s_state);
	sb->s_errors = ext2fs_swab16(sb->s_errors);
	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
	sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
	sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
	sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
	sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
	sb->s_desc_size = ext2fs_swab16(sb->s_desc_size);
	sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
	sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
	sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
	sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
	sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi);
	sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
	sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
	sb->s_flags = ext2fs_swab32(sb->s_flags);
	sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
	for (i=0; i < 4; i++)
		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);

	/* if journal backup is for a valid extent-based journal... */
	if (!ext2fs_extent_header_verify(sb->s_jnl_blocks,
					 sizeof(sb->s_jnl_blocks))) {
		/* ... swap only the journal i_size */
		sb->s_jnl_blocks[16] = ext2fs_swab32(sb->s_jnl_blocks[16]);
		/* and the extent data is not swapped on read */
		return;
	}

	/* direct/indirect journal: swap it all */
	for (i=0; i < 17; i++)
		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
}
Example #21
0
void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
			    struct ext2_inode_large *f, int hostorder,
			    int bufsize)
{
	unsigned i;
	int islnk = 0;
	__u32 *eaf, *eat;

	if (hostorder && LINUX_S_ISLNK(f->i_mode))
		islnk = 1;
	t->i_mode = ext2fs_swab16(f->i_mode);
	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
		islnk = 1;
	t->i_uid = ext2fs_swab16(f->i_uid);
	t->i_size = ext2fs_swab32(f->i_size);
	t->i_atime = ext2fs_swab32(f->i_atime);
	t->i_ctime = ext2fs_swab32(f->i_ctime);
	t->i_mtime = ext2fs_swab32(f->i_mtime);
	t->i_dtime = ext2fs_swab32(f->i_dtime);
	t->i_gid = ext2fs_swab16(f->i_gid);
	t->i_links_count = ext2fs_swab16(f->i_links_count);
	t->i_blocks = ext2fs_swab32(f->i_blocks);
	t->i_flags = ext2fs_swab32(f->i_flags);
	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
	if (!islnk || ext2fs_inode_data_blocks(fs, (struct ext2_inode *)t)) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
	} else if (t != f) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = f->i_block[i];
	}
	t->i_generation = ext2fs_swab32(f->i_generation);
	t->i_faddr = ext2fs_swab32(f->i_faddr);

	switch (fs->super->s_creator_os) {
	case EXT2_OS_LINUX:
		t->osd1.linux1.l_i_reserved1 =
			ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
		t->osd2.linux2.l_i_uid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
		t->osd2.linux2.l_i_gid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
		t->osd2.linux2.l_i_reserved2 =
			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
		break;
	case EXT2_OS_HURD:
		t->osd1.hurd1.h_i_translator =
		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
		t->osd2.hurd2.h_i_mode_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
		t->osd2.hurd2.h_i_uid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
		t->osd2.hurd2.h_i_gid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
		t->osd2.hurd2.h_i_author =
		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
		break;
	case EXT2_OS_MASIX:
		t->osd1.masix1.m_i_reserved1 =
			ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
		t->osd2.masix2.m_i_reserved2[0] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
		t->osd2.masix2.m_i_reserved2[1] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
		break;
	}

	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
		return; /* no i_extra_isize field */

	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
	if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) -
				sizeof(struct ext2_inode)) {
		/* this is error case: i_extra_size is too large */
		return;
	}

	i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32);
	if (bufsize < (int) i)
		return; /* no space for EA magic */

	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
					f->i_extra_isize);

	if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC)
		return; /* it seems no magic here */

	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
					f->i_extra_isize);
	*eat = ext2fs_swab32(*eaf);

	/* convert EA(s) */
	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
			     bufsize - sizeof(struct ext2_inode) -
			     t->i_extra_isize - sizeof(__u32), 0);

}
Example #22
0
void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
			    struct ext2_inode_large *f, int hostorder,
			    int bufsize)
{
	unsigned i, has_data_blocks, extra_isize, attr_magic;
	int has_extents = 0;
	int islnk = 0;
	__u32 *eaf, *eat;

	if (hostorder && LINUX_S_ISLNK(f->i_mode))
		islnk = 1;
	t->i_mode = ext2fs_swab16(f->i_mode);
	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
		islnk = 1;
	t->i_uid = ext2fs_swab16(f->i_uid);
	t->i_size = ext2fs_swab32(f->i_size);
	t->i_atime = ext2fs_swab32(f->i_atime);
	t->i_ctime = ext2fs_swab32(f->i_ctime);
	t->i_mtime = ext2fs_swab32(f->i_mtime);
	t->i_dtime = ext2fs_swab32(f->i_dtime);
	t->i_gid = ext2fs_swab16(f->i_gid);
	t->i_links_count = ext2fs_swab16(f->i_links_count);
	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
	if (hostorder)
		has_data_blocks = ext2fs_inode_data_blocks(fs,
					   (struct ext2_inode *) f);
	t->i_blocks = ext2fs_swab32(f->i_blocks);
	if (!hostorder)
		has_data_blocks = ext2fs_inode_data_blocks(fs,
					   (struct ext2_inode *) t);
	if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
		has_extents = 1;
	t->i_flags = ext2fs_swab32(f->i_flags);
	if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
		has_extents = 1;
	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
	
	if (!has_extents && (!islnk || has_data_blocks)) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
	} else if (t != f) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = f->i_block[i];
	}
	t->i_generation = ext2fs_swab32(f->i_generation);
	t->i_faddr = ext2fs_swab32(f->i_faddr);

	switch (fs->super->s_creator_os) {
	case EXT2_OS_LINUX:
		t->osd1.linux1.l_i_version =
			ext2fs_swab32(f->osd1.linux1.l_i_version);
		t->osd2.linux2.l_i_blocks_hi =
			ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
		t->osd2.linux2.l_i_file_acl_high =
			ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high);
		t->osd2.linux2.l_i_uid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
		t->osd2.linux2.l_i_gid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
		t->osd2.linux2.l_i_reserved2 =
			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
		break;
	case EXT2_OS_HURD:
		t->osd1.hurd1.h_i_translator =
		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
		t->osd2.hurd2.h_i_mode_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
		t->osd2.hurd2.h_i_uid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
		t->osd2.hurd2.h_i_gid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
		t->osd2.hurd2.h_i_author =
		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
		break;
	default:
		break;
	}

	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
		return; 

	if (hostorder)
		extra_isize = f->i_extra_isize;
	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
	if (!hostorder)
		extra_isize = t->i_extra_isize;
	if (extra_isize > EXT2_INODE_SIZE(fs->super) -
				sizeof(struct ext2_inode)) {
		
		return;
	}

	i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
	if (bufsize < (int) i)
		return; 

	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
					extra_isize);

	attr_magic = *eaf;
	if (!hostorder)
		attr_magic = ext2fs_swab32(attr_magic);

	if (attr_magic != EXT2_EXT_ATTR_MAGIC)
		return; 

	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
					extra_isize);
	*eat = ext2fs_swab32(*eaf);

	
	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
			     bufsize - sizeof(struct ext2_inode) -
			     extra_isize - sizeof(__u32), 0);

}
Example #23
0
blk64_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
		      io_manager manager)
{
	struct ext2_super_block *sb;
	io_channel		io = NULL;
	void			*buf = NULL;
	int			blocksize;
	blk64_t			superblock, ret_sb = 8193;

	if (fs && fs->super) {
		ret_sb = (fs->super->s_blocks_per_group +
			  fs->super->s_first_data_block);
		if (ctx) {
			ctx->superblock = ret_sb;
			ctx->blocksize = fs->blocksize;
		}
		return ret_sb;
	}

	if (ctx) {
		if (ctx->blocksize) {
			ret_sb = ctx->blocksize * 8;
			if (ctx->blocksize == 1024)
				ret_sb++;
			ctx->superblock = ret_sb;
			return ret_sb;
		}
		ctx->superblock = ret_sb;
		ctx->blocksize = 1024;
	}

	if (!name || !manager)
		goto cleanup;

	if (manager->open(name, 0, &io) != 0)
		goto cleanup;

	if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
		goto cleanup;
	sb = (struct ext2_super_block *) buf;

	for (blocksize = EXT2_MIN_BLOCK_SIZE;
	     blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
		superblock = blocksize*8;
		if (blocksize == 1024)
			superblock++;
		io_channel_set_blksize(io, blocksize);
		if (io_channel_read_blk64(io, superblock,
					-SUPERBLOCK_SIZE, buf))
			continue;
#ifdef WORDS_BIGENDIAN
		if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
			ext2fs_swap_super(sb);
#endif
		if ((sb->s_magic == EXT2_SUPER_MAGIC) &&
		    (EXT2_BLOCK_SIZE(sb) == blocksize)) {
			ret_sb = superblock;
			if (ctx) {
				ctx->superblock = superblock;
				ctx->blocksize = blocksize;
			}
			break;
		}
	}

cleanup:
	if (io)
		io_channel_close(io);
	if (buf)
		ext2fs_free_mem(&buf);
	return (ret_sb);
}
Example #24
0
void ext2fs_swap_super(struct ext2_super_block * sb)
{
  	int i;
	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
	sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
	sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
	sb->s_magic = ext2fs_swab16(sb->s_magic);
	sb->s_state = ext2fs_swab16(sb->s_state);
	sb->s_errors = ext2fs_swab16(sb->s_errors);
	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
	sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
	sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
	sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
	sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
	sb->s_desc_size = ext2fs_swab16(sb->s_desc_size);
	sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
	sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
	sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
	sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
	sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi);
	sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
	sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
	sb->s_flags = ext2fs_swab32(sb->s_flags);
	sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
	sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
	sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
	sb->s_snapshot_r_blocks_count =
		ext2fs_swab64(sb->s_snapshot_r_blocks_count);
	sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);

	for (i=0; i < 4; i++)
		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);

	
	if (!ext2fs_extent_header_verify(sb->s_jnl_blocks,
					 sizeof(sb->s_jnl_blocks))) {
		
		sb->s_jnl_blocks[16] = ext2fs_swab32(sb->s_jnl_blocks[16]);
		
		return;
	}

	
	for (i=0; i < 17; i++)
		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
}
Example #25
0
static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
{
	struct ext2_super_block *sb = ctx->fs->super;
	struct ext2_super_block jsuper;
	struct problem_context	pctx;
	struct buffer_head 	*bh;
	struct inode		*j_inode = NULL;
	struct kdev_s		*dev_fs = NULL, *dev_journal;
	const char		*journal_name = 0;
	journal_t		*journal = NULL;
	errcode_t		retval = 0;
	io_manager		io_ptr = 0;
	unsigned long		start = 0;
	blk_t			blk;
	int			ext_journal = 0;
	int			tried_backup_jnl = 0;
	int			i;
		
	clear_problem_context(&pctx);
	
	journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
	if (!journal) {
		return EXT2_ET_NO_MEMORY;
	}

	dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
	if (!dev_fs) {
		retval = EXT2_ET_NO_MEMORY;
		goto errout;
	}
	dev_journal = dev_fs+1;
	
	dev_fs->k_ctx = dev_journal->k_ctx = ctx;
	dev_fs->k_dev = K_DEV_FS;
	dev_journal->k_dev = K_DEV_JOURNAL;
	
	journal->j_dev = dev_journal;
	journal->j_fs_dev = dev_fs;
	journal->j_inode = NULL;
	journal->j_blocksize = ctx->fs->blocksize;

	if (uuid_is_null(sb->s_journal_uuid)) {
		if (!sb->s_journal_inum)
			return EXT2_ET_BAD_INODE_NUM;
		j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
						 "journal inode");
		if (!j_inode) {
			retval = EXT2_ET_NO_MEMORY;
			goto errout;
		}

		j_inode->i_ctx = ctx;
		j_inode->i_ino = sb->s_journal_inum;
		
		if ((retval = ext2fs_read_inode(ctx->fs,
						sb->s_journal_inum,
						&j_inode->i_ext2))) {
		try_backup_journal:
			if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
			    tried_backup_jnl)
				goto errout;
			memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
			memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks, 
			       EXT2_N_BLOCKS*4);
			j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
			j_inode->i_ext2.i_links_count = 1;
			j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
			tried_backup_jnl++;
		}
		if (!j_inode->i_ext2.i_links_count ||
		    !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
			retval = EXT2_ET_NO_JOURNAL;
			goto try_backup_journal;
		}
		if (j_inode->i_ext2.i_size / journal->j_blocksize <
		    JFS_MIN_JOURNAL_BLOCKS) {
			retval = EXT2_ET_JOURNAL_TOO_SMALL;
			goto try_backup_journal;
		}
		for (i=0; i < EXT2_N_BLOCKS; i++) {
			blk = j_inode->i_ext2.i_block[i];
			if (!blk) {
				if (i < EXT2_NDIR_BLOCKS) {
					retval = EXT2_ET_JOURNAL_TOO_SMALL;
					goto try_backup_journal;
				}
				continue;
			}
			if (blk < sb->s_first_data_block ||
			    blk >= sb->s_blocks_count) {
				retval = EXT2_ET_BAD_BLOCK_NUM;
				goto try_backup_journal;
			}
		}
		journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;

#ifdef USE_INODE_IO
		retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
						 &j_inode->i_ext2,
						 &journal_name);
		if (retval)
			goto errout;

		io_ptr = inode_io_manager;
#else
		journal->j_inode = j_inode;
		ctx->journal_io = ctx->fs->io;
		if ((retval = journal_bmap(journal, 0, &start)) != 0)
			goto errout;
#endif
	} else {
		ext_journal = 1;
		if (!ctx->journal_name) {
			char uuid[37];

			uuid_unparse(sb->s_journal_uuid, uuid);
			ctx->journal_name = blkid_get_devname(ctx->blkid,
							      "UUID", uuid);
			if (!ctx->journal_name)
				ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
		}
		journal_name = ctx->journal_name;
			
		if (!journal_name) {
			fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
			return EXT2_ET_LOAD_EXT_JOURNAL;
		}
		
		jfs_debug(1, "Using journal file %s\n", journal_name);
		io_ptr = unix_io_manager;
	}

#if 0
	test_io_backing_manager = io_ptr;
	io_ptr = test_io_manager;
#endif
#ifndef USE_INODE_IO
	if (ext_journal)
#endif
		retval = io_ptr->open(journal_name, IO_FLAG_RW,
				      &ctx->journal_io);
	if (retval)
		goto errout;

	io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);

	if (ext_journal) {
		if (ctx->fs->blocksize == 1024)
			start = 1;
		bh = getblk(dev_journal, start, ctx->fs->blocksize);
		if (!bh) {
			retval = EXT2_ET_NO_MEMORY;
			goto errout;
		}
		ll_rw_block(READ, 1, &bh);
		if ((retval = bh->b_err) != 0) {
			brelse(bh);
			goto errout;
		}
		memcpy(&jsuper, start ? bh->b_data :  bh->b_data + 1024,
		       sizeof(jsuper));
		brelse(bh);
#ifdef EXT2FS_ENABLE_SWAPFS
		if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) 
			ext2fs_swap_super(&jsuper);
#endif
		if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
		    !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
			fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			goto errout;
		}
		/* Make sure the journal UUID is correct */
		if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
			   sizeof(jsuper.s_uuid))) {
			fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			goto errout;
		}
		
		journal->j_maxlen = jsuper.s_blocks_count;
		start++;
	}

	if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
		retval = EXT2_ET_NO_MEMORY;
		goto errout;
	}
	
	journal->j_sb_buffer = bh;
	journal->j_superblock = (journal_superblock_t *)bh->b_data;
	
#ifdef USE_INODE_IO
	if (j_inode)
		ext2fs_free_mem(&j_inode);
#endif

	*ret_journal = journal;
	return 0;

errout:
	if (dev_fs)
		ext2fs_free_mem(&dev_fs);
	if (j_inode)
		ext2fs_free_mem(&j_inode);
	if (journal)
		ext2fs_free_mem(&journal);
	return retval;
	
}
Example #26
0
static errcode_t ext2fs_get_journal(ext2_filsys fs, journal_t **ret_journal)
{
	struct process_block_struct pb;
	struct ext2_super_block *sb = fs->super;
	struct ext2_super_block jsuper;
	struct buffer_head	*bh;
	struct inode		*j_inode = NULL;
	struct kdev_s		*dev_fs = NULL, *dev_journal;
	const char		*journal_name = 0;
	journal_t		*journal = NULL;
	errcode_t		retval = 0;
	io_manager		io_ptr = 0;
	unsigned long long	start = 0;
	int			ext_journal = 0;
	int			tried_backup_jnl = 0;

	retval = ext2fs_get_memzero(sizeof(journal_t), &journal);
	if (retval)
		return retval;

	retval = ext2fs_get_memzero(2 * sizeof(struct kdev_s), &dev_fs);
	if (retval)
		goto errout;
	dev_journal = dev_fs+1;

	dev_fs->k_fs = dev_journal->k_fs = fs;
	dev_fs->k_dev = K_DEV_FS;
	dev_journal->k_dev = K_DEV_JOURNAL;

	journal->j_dev = dev_journal;
	journal->j_fs_dev = dev_fs;
	journal->j_inode = NULL;
	journal->j_blocksize = fs->blocksize;

	if (uuid_is_null(sb->s_journal_uuid)) {
		if (!sb->s_journal_inum) {
			retval = EXT2_ET_BAD_INODE_NUM;
			goto errout;
		}
		retval = ext2fs_get_memzero(sizeof(*j_inode), &j_inode);
		if (retval)
			goto errout;

		j_inode->i_fs = fs;
		j_inode->i_ino = sb->s_journal_inum;

		retval = ext2fs_read_inode(fs, sb->s_journal_inum,
					   &j_inode->i_ext2);
		if (retval) {
try_backup_journal:
			if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
			    tried_backup_jnl)
				goto errout;
			memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
			memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
			       EXT2_N_BLOCKS*4);
			j_inode->i_ext2.i_size_high = sb->s_jnl_blocks[15];
			j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
			j_inode->i_ext2.i_links_count = 1;
			j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
			tried_backup_jnl++;
		}
		if (!j_inode->i_ext2.i_links_count ||
		    !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
			retval = EXT2_ET_NO_JOURNAL;
			goto try_backup_journal;
		}
		if (EXT2_I_SIZE(&j_inode->i_ext2) / journal->j_blocksize <
		    JFS_MIN_JOURNAL_BLOCKS) {
			retval = EXT2_ET_JOURNAL_TOO_SMALL;
			goto try_backup_journal;
		}
		pb.last_block = -1;
		retval = ext2fs_block_iterate3(fs, j_inode->i_ino,
					       BLOCK_FLAG_HOLE, 0,
					       process_journal_block, &pb);
		if ((pb.last_block + 1) * fs->blocksize <
		    (int) EXT2_I_SIZE(&j_inode->i_ext2)) {
			retval = EXT2_ET_JOURNAL_TOO_SMALL;
			goto try_backup_journal;
		}
		if (tried_backup_jnl && (fs->flags & EXT2_FLAG_RW)) {
			retval = ext2fs_write_inode(fs, sb->s_journal_inum,
						    &j_inode->i_ext2);
			if (retval)
				goto errout;
		}

		journal->j_maxlen = EXT2_I_SIZE(&j_inode->i_ext2) /
			journal->j_blocksize;

#ifdef USE_INODE_IO
		retval = ext2fs_inode_io_intern2(fs, sb->s_journal_inum,
						 &j_inode->i_ext2,
						 &journal_name);
		if (retval)
			goto errout;

		io_ptr = inode_io_manager;
#else
		journal->j_inode = j_inode;
		fs->journal_io = fs->io;
		retval = (errcode_t)journal_bmap(journal, 0, &start);
		if (retval)
			goto errout;
#endif
	} else {
		ext_journal = 1;
		if (!fs->journal_name) {
			char uuid[37];
			blkid_cache blkid;

			blkid_get_cache(&blkid, NULL);
			uuid_unparse(sb->s_journal_uuid, uuid);
			fs->journal_name = blkid_get_devname(blkid,
							      "UUID", uuid);
			if (!fs->journal_name)
				fs->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
			blkid_put_cache(blkid);
		}
		journal_name = fs->journal_name;

		if (!journal_name) {
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			goto errout;
		}

		jfs_debug(1, "Using journal file %s\n", journal_name);
		io_ptr = unix_io_manager;
	}

#if 0
	test_io_backing_manager = io_ptr;
	io_ptr = test_io_manager;
#endif
#ifndef USE_INODE_IO
	if (ext_journal)
#endif
	{
		retval = io_ptr->open(journal_name, fs->flags & EXT2_FLAG_RW,
				      &fs->journal_io);
	}
	if (retval)
		goto errout;

	io_channel_set_blksize(fs->journal_io, fs->blocksize);

	if (ext_journal) {
		blk64_t maxlen;

		start = ext2fs_journal_sb_start(fs->blocksize) - 1;
		bh = getblk(dev_journal, start, fs->blocksize);
		if (!bh) {
			retval = EXT2_ET_NO_MEMORY;
			goto errout;
		}
		ll_rw_block(READ, 1, &bh);
		retval = bh->b_err;
		if (retval) {
			brelse(bh);
			goto errout;
		}
		memcpy(&jsuper, start ? bh->b_data :
				bh->b_data + SUPERBLOCK_OFFSET,
		       sizeof(jsuper));
#ifdef WORDS_BIGENDIAN
		if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
			ext2fs_swap_super(&jsuper);
#endif
		if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
		    !ext2fs_has_feature_journal_dev(&jsuper)) {
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			brelse(bh);
			goto errout;
		}
		/* Make sure the journal UUID is correct */
		if (memcmp(jsuper.s_uuid, fs->super->s_journal_uuid,
			   sizeof(jsuper.s_uuid))) {
			retval = EXT2_ET_LOAD_EXT_JOURNAL;
			brelse(bh);
			goto errout;
		}

		/* Check the superblock checksum */
		if (ext2fs_has_feature_metadata_csum(&jsuper)) {
			struct struct_ext2_filsys fsx;
			struct ext2_super_block	superx;
			void *p;

			p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET;
			memcpy(&fsx, fs, sizeof(fsx));
			memcpy(&superx, fs->super, sizeof(superx));
			fsx.super = &superx;
			ext2fs_set_feature_metadata_csum(fsx.super);
			if (!ext2fs_superblock_csum_verify(&fsx, p)) {
				retval = EXT2_ET_LOAD_EXT_JOURNAL;
				brelse(bh);
				goto errout;
			}
		}
		brelse(bh);

		maxlen = ext2fs_blocks_count(&jsuper);
		journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen :
				    (1ULL << 32) - 1;
		start++;
	}

	bh = getblk(dev_journal, start, journal->j_blocksize);
	if (!bh) {
		retval = EXT2_ET_NO_MEMORY;
		goto errout;
	}

	journal->j_sb_buffer = bh;
	journal->j_superblock = (journal_superblock_t *)bh->b_data;

#ifdef USE_INODE_IO
	if (j_inode)
		ext2fs_free_mem(&j_inode);
#endif

	*ret_journal = journal;
	return 0;

errout:
	if (dev_fs)
		ext2fs_free_mem(&dev_fs);
	if (j_inode)
		ext2fs_free_mem(&j_inode);
	if (journal)
		ext2fs_free_mem(&journal);
	return retval;
}