예제 #1
0
void mess_up_inode_alloc(ocfs2_filesys *fs, enum fsck_type type,
			 uint16_t slotnum)
{
	errcode_t ret;
	uint64_t tmpblkno;
	char *buf = NULL;
	struct ocfs2_dinode *di;

	ret = ocfs2_new_inode(fs, &tmpblkno, S_IFREG | 0755);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, tmpblkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	di->i_flags &= ~OCFS2_VALID_FL;

	ret = ocfs2_write_inode(fs, tmpblkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	fprintf(stdout, "INODE_ALLOC_REPAIR: "
		"Create an inode#%"PRIu64" and invalidate it.\n", tmpblkno);

	if (buf)
		ocfs2_free(&buf);
	return;
}
예제 #2
0
static void create_named_directory(ocfs2_filesys *fs, char *dirname,
				   uint64_t *blkno)
{
	errcode_t ret;
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);

	ret = ocfs2_lookup(fs, sb->s_root_blkno, dirname, strlen(dirname), NULL,
			   blkno);
	if (!ret)
		return;
	else if (ret != OCFS2_ET_FILE_NOT_FOUND)
		FSWRK_COM_FATAL(progname, ret);

	ret  = ocfs2_new_inode(fs, blkno, S_IFDIR | 0755);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_init_dir(fs, *blkno, fs->fs_root_blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_link(fs, fs->fs_root_blkno, dirname, *blkno, OCFS2_FT_DIR);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	return;
}
예제 #3
0
static void create_local_alloc(ocfs2_filesys *fs, uint64_t blkno)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_local_alloc *la;
	uint32_t la_size, found;
	uint64_t la_off;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		FSWRK_FATAL("not a file");

	if (!(di->i_flags & OCFS2_LOCAL_ALLOC_FL))
		FSWRK_FATAL("not a local alloc file");

	if (di->id1.bitmap1.i_total > 0) {
		FSWRK_WARN("local alloc#%"PRIu64" file not empty."
				"Can't create a new one.\n", blkno);
		goto bail;
	}

	la_size = get_local_alloc_window_bits();

	ret = ocfs2_new_clusters(fs, 1, la_size, &la_off, &found);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);
	if(la_size != found)
		FSWRK_FATAL("can't allocate enough clusters for local alloc");

	la = &(di->id2.i_lab);

	la->la_bm_off = la_off;
	di->id1.bitmap1.i_total = la_size;
	di->id1.bitmap1.i_used = 0;
	memset(la->la_bitmap, 0, la->la_size);
	
	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

bail:
	if(buf)
		ocfs2_free(&buf);
	return;
}
예제 #4
0
void mess_up_inode_field(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno)
{
	errcode_t ret;
	uint64_t tmpblkno;
	uint32_t clusters = 10;

	char *buf = NULL;
	struct ocfs2_dinode *di;

	create_file(fs, blkno, &tmpblkno);

	if ((type == INODE_SPARSE_SIZE) || (type == INODE_SPARSE_CLUSTERS)) {

		if (!ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super)))
			FSWRK_FATAL("should specfiy a sparse file supported "
				    "volume to do this corruption\n");

		ret = ocfs2_malloc_block(fs->fs_io, &buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		ret = ocfs2_read_inode(fs, tmpblkno, buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		di = (struct ocfs2_dinode *)buf;

		di->i_size = fs->fs_clustersize * 2;

		ret = ocfs2_write_inode(fs, tmpblkno, buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		if (buf)
			ocfs2_free(&buf);
	}

	if ((type == INODE_CLUSTERS) || (type == INODE_SPARSE_CLUSTERS) ||
	    (type == INODE_SPARSE_SIZE)) {
		ret = ocfs2_extend_allocation(fs, tmpblkno, clusters);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);
	}

	if (type == REFCOUNT_FLAG_INVALID &&
	    ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super)))
		FSWRK_FATAL("should specfiy a norefcount volume\n");
	if (type == REFCOUNT_LOC_INVALID &&
	    !ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super)))
		FSWRK_FATAL("Should specify a refcount supported volume\n");

	damage_inode(fs, tmpblkno, type);
	return;
}
예제 #5
0
void mess_up_inline_flag(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno)
{

	int i;
	errcode_t ret;
	char *buf = NULL, file_type[20];
	uint64_t inline_blkno;
	struct ocfs2_dinode *di;
	struct ocfs2_super_block *osb;

	osb = OCFS2_RAW_SB(fs->fs_super);
	if (ocfs2_support_inline_data(osb))
		FSWRK_FATAL("should specfiy a noinline-data supported "
			    "volume to do this corruption\n");

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	for (i = 0; i < 2; i++) {
		if (i == 0) {
			create_file(fs, blkno, &inline_blkno);
			snprintf(file_type, 20, "%s", "Regular file");
		} else {
			create_directory(fs, blkno, &inline_blkno);
			snprintf(file_type, 20, "%s", "Diectory");
		}

		ret = ocfs2_read_inode(fs, inline_blkno, buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		di = (struct ocfs2_dinode *)buf;
		if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL)) {
			di->i_dyn_features |= OCFS2_INLINE_DATA_FL;
			ret = ocfs2_write_inode(fs, inline_blkno, buf);
			if (ret)
				FSWRK_COM_FATAL(progname, ret);
		}

		fprintf(stdout, "INLINE_DATA_FLAG_INVALID: "
			"Create an inlined inode#%"PRIu64"(%s) "
			"on a noinline-data supported volume\n",
			inline_blkno, file_type);
	}

	if (buf)
		ocfs2_free(&buf);
	return;
}
예제 #6
0
void mess_up_local_alloc_used(ocfs2_filesys *fs, enum fsck_type type,
			      uint16_t slotnum)
{
	errcode_t ret;
	uint64_t blkno;
	char alloc_inode[OCFS2_MAX_FILENAME_LEN];
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
  
	if (slotnum == UINT16_MAX)
		slotnum = 0;
	
	snprintf(alloc_inode, sizeof(alloc_inode), 	
		 ocfs2_system_inodes[LOCAL_ALLOC_SYSTEM_INODE].si_name,slotnum);
	
	ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, alloc_inode,
			   strlen(alloc_inode), NULL, &blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	create_local_alloc(fs, blkno);

	damage_local_alloc(fs, blkno, type);
		
	return;
}
예제 #7
0
void mess_up_inode_orphaned(ocfs2_filesys *fs, enum fsck_type type,
			    uint16_t slotnum)
{
	errcode_t ret;
	uint64_t blkno, tmpblkno;
	char parentdir[OCFS2_MAX_FILENAME_LEN];
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);

	if (slotnum == UINT16_MAX)
		slotnum = 0;
	snprintf(parentdir, sizeof(parentdir),
		 ocfs2_system_inodes[ORPHAN_DIR_SYSTEM_INODE].si_name, slotnum);

	ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, parentdir,
			   strlen(parentdir), NULL, &blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	create_file(fs, blkno, &tmpblkno);

	fprintf(stdout, "INODE_ORPHANED: "
		"Create an inode#%"PRIu64" under directory %s\n",
		tmpblkno, parentdir);
	return;
}
예제 #8
0
파일: chain.c 프로젝트: pepe5/ocfs2-tools
static void mess_up_sys_chains(ocfs2_filesys *fs, uint16_t slotnum,
			       enum fsck_type type)
{
	errcode_t ret;
	char sysfile[OCFS2_MAX_FILENAME_LEN];
	uint64_t blkno;
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
	
	if (slotnum == UINT16_MAX)
		snprintf(sysfile, sizeof(sysfile), "%s",
		ocfs2_system_inodes[GLOBAL_BITMAP_SYSTEM_INODE].si_name);
	else
		snprintf(sysfile, sizeof(sysfile),
			ocfs2_system_inodes[INODE_ALLOC_SYSTEM_INODE].si_name,
			slotnum);

	ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, sysfile,
				   strlen(sysfile), NULL, &blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);
	
	mess_up_sys_file(fs, blkno, type);

	return ;
}
예제 #9
0
파일: chain.c 프로젝트: pepe5/ocfs2-tools
static void mess_up_superblock_clusters(ocfs2_filesys *fs, int excess)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di = fs->fs_super;
	uint32_t new_clusters, cpg, wrong;

	/* corrupt superblock, just copy the
	 * superblock, change it and
	 * write it back to disk.
	 */
	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	memcpy(buf, (char *)di, fs->fs_blocksize);

	di = (struct ocfs2_dinode *)buf;

	cpg = 8 * ocfs2_group_bitmap_size(fs->fs_blocksize, 0,
				OCFS2_RAW_SB(fs->fs_super)->s_feature_incompat);

	/* make the wrong value to 2.5 times of cluster_per_group. */
	wrong = cpg * 2 + cpg / 2;
	if (excess)
		new_clusters = di->i_clusters + wrong;
	else
		new_clusters = di->i_clusters - wrong;

	fprintf(stdout, "Corrupt SUPERBLOCK_CLUSTERS: "
		"change superblock i_clusters from %u to %u.\n",
		di->i_clusters, new_clusters);
	di->i_clusters = new_clusters;

	ret = io_write_block(fs->fs_io, di->i_blkno, 1, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	if(buf)
		ocfs2_free(&buf);
	return;
}
예제 #10
0
void mess_up_inode_not_connected(ocfs2_filesys *fs, enum fsck_type type,
				 uint64_t blkno)
{
	errcode_t ret;
	uint64_t tmpblkno;

	ret = ocfs2_new_inode(fs, &tmpblkno, S_IFREG | 0755);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	fprintf(stdout, "INODE_NOT_CONNECTED: "
		"Create an inode#%"PRIu64" which has no links\n", tmpblkno);
	return ;
}
예제 #11
0
static void get_truncate_log(ocfs2_filesys *fs, 
					uint16_t slotnum, uint64_t *blkno)
{
	errcode_t ret;
	char truncate_log[OCFS2_MAX_FILENAME_LEN];
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);

	if (slotnum == UINT16_MAX)
		slotnum = 0;
	
	snprintf(truncate_log, sizeof(truncate_log), 	
		 ocfs2_system_inodes[TRUNCATE_LOG_SYSTEM_INODE].si_name,
		 slotnum);
	
	ret = ocfs2_lookup(fs, sb->s_system_dir_blkno, truncate_log,
			   strlen(truncate_log), NULL, blkno);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	return;
}
예제 #12
0
static void damage_truncate_log(ocfs2_filesys *fs,
				uint64_t blkno, enum fsck_type type, int recnum)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_truncate_log *tl;
	struct ocfs2_truncate_rec *tr;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		FSWRK_FATAL("not a valid file");

	if (!(di->i_flags & OCFS2_DEALLOC_FL))
		FSWRK_FATAL("not a valid truncate log");
	
	tl = &di->id2.i_dealloc;

	/* For TRUNCATE_REC_START_RANGE, TRUNCATE_REC_WRAP, TRUNCATE_REC_RANGE,
	 * tl_used must be greater than 0 and recnum must be less than tl_used.
	 * So check it first.
	 */
	if (type == TRUNCATE_REC_START_RANGE || type == TRUNCATE_REC_WRAP ||
		type == TRUNCATE_REC_RANGE) {
		if (tl->tl_used == 0) {
			FSWRK_WARN("truncate log#%"PRIu64" is empty, so can't"
					"corrupt it for type[%d]\n",
					blkno, type);
			goto bail;
		}
		
		if(tl->tl_used <= recnum) {
			FSWRK_WARN("truncate log#%"PRIu64" can't corrupt "
					"item[%d] corrupt it for type[%d]\n",
					blkno, recnum, type);
			goto bail;
		}
	}
	
	switch (type) {
	case DEALLOC_COUNT:
		fprintf(stdout, "DEALLOC_COUNT: "
			"Corrupt truncate log inode#%"PRIu64", change tl_count"
			" from %u to %u\n",
			blkno, tl->tl_count, (tl->tl_count + 10));
		tl->tl_count += 10;
		break;
	case DEALLOC_USED:
		fprintf(stdout, "DEALLOC_USED: "
			"Corrupt truncate log inode#%"PRIu64", change tl_used"
			" from %u to %u\n",
			blkno, tl->tl_used, (tl->tl_count + 10));
		tl->tl_used = tl->tl_count + 10;
		break;
	case TRUNCATE_REC_START_RANGE:
		tr = &tl->tl_recs[recnum];
		fprintf(stdout, "TRUNCATE_REC_START_RANGE: "
			"Corrupt truncate log inode#%"PRIu64",rec#%d "
			"change t_start from %u to %u\n",
			blkno, recnum, tr->t_start, (fs->fs_clusters + 10));
		tr->t_start = fs->fs_clusters + 10;
		break;
	case TRUNCATE_REC_WRAP:
		tr = &tl->tl_recs[recnum];
		fprintf(stdout, "TRUNCATE_REC_WRAP: "
			"Corrupt truncate log inode#%"PRIu64",rec#%d "
			"change t_start from %u to 10000\n,"
			"change t_clusters from %u to %u\n",
			blkno, recnum,
			tr->t_start,tr->t_clusters, (UINT32_MAX - 10));
		tr->t_start = 10000;
		tr->t_clusters = UINT32_MAX - 10;
		break;
	case TRUNCATE_REC_RANGE:
		tr = &tl->tl_recs[recnum];
		fprintf(stdout, "TRUNCATE_REC_RANGE: "
			"Corrupt truncate log inode#%"PRIu64",rec#%d "
			"change t_clusters from %u to %u\n",
			blkno, recnum, tr->t_clusters, (fs->fs_clusters + 10));
		tr->t_clusters = fs->fs_clusters + 10;
		break;
	default:
		FSWRK_FATAL("Unknown type = %d", type);
	}
	
	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);
bail:
	if (buf)
		ocfs2_free(&buf);
	return;
}
예제 #13
0
static void create_truncate_log(ocfs2_filesys *fs, uint64_t blkno,
				uint16_t used, uint32_t clusters)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_truncate_log *tl;
	uint16_t i, max;
	uint32_t found;
	uint64_t begin;

	max = ocfs2_truncate_recs_per_inode(fs->fs_blocksize);
	if (used > max)
		FSWRK_FATAL("recnum exceeds the limit of truncate log");

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		FSWRK_FATAL("not a valid file");

	if (!(di->i_flags & OCFS2_DEALLOC_FL))
		FSWRK_FATAL("not a valid truncate log");
	
	tl = &di->id2.i_dealloc;

	if (tl->tl_used > 0) {
		FSWRK_WARN("truncate log#%"PRIu64" file not empty."
				"Can't create a new one.\n", blkno);
		goto bail;
	}

	used = min(used, tl->tl_count);
	tl->tl_used = used;

	for (i = 0; i < tl->tl_used; i++) {
		ret = ocfs2_new_clusters(fs, 1, clusters, &begin, &found);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);
		
		tl->tl_recs[i].t_start = 
			cpu_to_le32(ocfs2_blocks_to_clusters(fs, begin));
		tl->tl_recs[i].t_clusters = cpu_to_le32(found);
	}

	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

bail:
	if(buf)
		ocfs2_free(&buf);
	return;
}
예제 #14
0
static void damage_inode(ocfs2_filesys *fs, uint64_t blkno,
				enum fsck_type type)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		FSWRK_FATAL("not a file");

	switch (type) {
	case INODE_GEN:
		fprintf(stdout, "INODE_GEN: "
			"Corrupt inode#%"PRIu64", change generation "
			" from %u to 0x1234\n", blkno, di->i_fs_generation);
		di->i_fs_generation = 0x1234;
		break;
	case INODE_GEN_FIX:
		fprintf(stdout, "INODE_GEN_FIX: "
			"Corrupt inode#%"PRIu64", change generation "
			" from %u to 0x1234, please answer 'n' when "
			"INODE_GEN error shows in fsck.ocfs2\n",
			blkno, di->i_fs_generation);
		di->i_fs_generation = 0x1234;
		break;
	case INODE_BLKNO:
		fprintf(stdout, "INODE_BLKNO: "
			"Corrupt inode#%"PRIu64", change i_blkno from %"PRIu64
			" to %"PRIu64"\n",
			blkno, di->i_blkno, (di->i_blkno + 100));
		di->i_blkno += 100;
		break;
	case INODE_NZ_DTIME:
		fprintf(stdout, "INODE_NZ_DTIME: "
			"Corrupt inode#%"PRIu64", change i_dtime from %"PRIu64
			" to 100\n", blkno, di->i_dtime);
		di->i_dtime = 100;
		break;
	case INODE_SUBALLOC:
		fprintf(stdout, "INODE_SUBALLOC: "
			"Corrupt inode#%"PRIu64", change i_suballoc_slot"
			" from %u to %u\n", blkno, di->i_suballoc_slot,
			(di->i_suballoc_slot + 10));
		di->i_suballoc_slot += 10;
		break;
	case INODE_SIZE:
		fprintf(stdout, "INODE_SIZE: "
			"Corrupt inode#%"PRIu64", change i_size"
			" from %"PRIu64" to %"PRIu64"\n",
			 blkno, di->i_size, (di->i_size + 100));
		di->i_size += 100;
		break;
	case INODE_SPARSE_SIZE:
		fprintf(stdout, "INODE_SPARSE_SIZE: "
			"Corrupt inode#%"PRIu64", change i_size "
			"from %"PRIu64" to %u\n",
			 blkno, di->i_size, fs->fs_clustersize);
		di->i_size = fs->fs_clustersize;
		break;
	case INODE_CLUSTERS:
		fprintf(stdout, "INODE_CLUSTERS: "
			"Corrupt inode#%"PRIu64", change i_clusters"
			" from %u to 0\n", blkno, di->i_clusters);
		di->i_clusters = 0;
		break;
	case INODE_SPARSE_CLUSTERS:
		fprintf(stdout, "INODE_SPARSE_CLUSTERS: "
			"Corrupt inode#%"PRIu64", change i_clusters"
			" from %u to 0\n", blkno, di->i_clusters);
		di->i_clusters = 0;
		break;
	case INODE_COUNT:
		di->i_links_count = 0;
		fprintf(stdout, "INODE_COUNT: "
			"Corrupte inode#%"PRIu64", set link count to 0\n",
			blkno);
		break;
	case INODE_BLOCK_ECC:
		fprintf(stdout, "INODE_BLOCK_ECC: "
			"Corrupte inode#%"PRIu64", set both i_check.bc_crc32e"
			"=%"PRIu64" and i_check.bc_ecc=%"PRIu64" to 0x1234\n",
			blkno, di->i_check.bc_crc32e, di->i_check.bc_ecc);
		di->i_check.bc_crc32e = 0x1234;
		di->i_check.bc_ecc = 0x1234;
		break;
	case INODE_VALID_FLAG:
		fprintf(stdout, "INODE_VALID_FLAG: "
			"Corrupt inode#%"PRIu64", clear inode valid flag\n",
			blkno);
		di->i_flags &= ~OCFS2_VALID_FL;
		break;
	case REFCOUNT_FLAG_INVALID:
		di->i_dyn_features |= OCFS2_HAS_REFCOUNT_FL;
		fprintf(stdout, "REFCOUNT_FLAG_INVALD: "
			"Corrupt inode#%"PRIu64", add refcount feature\n",
			blkno);
		break;
	case REFCOUNT_LOC_INVALID:
		di->i_refcount_loc = 100;
		fprintf(stdout, "REFCOUNT_LOC_INVALID: "
			"Create an inode#%"PRIu64","
			"whose i_refcount_loc has been messed up.\n",
			blkno);
		break;
	default:
		FSWRK_FATAL("Invalid type[%d]\n", type);
	}

	if (type != INODE_BLOCK_ECC)
		ret = ocfs2_write_inode(fs, blkno, buf);
	else
		ret = ocfs2_write_inode_without_meta_ecc(fs, blkno, buf);

	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	if (buf)
		ocfs2_free(&buf);
	return;
}
예제 #15
0
void mess_up_dup_clusters(ocfs2_filesys *fs, enum fsck_type type,
			  uint64_t blkno)
{
	errcode_t err;
	char *buf = NULL;
	uint64_t inode1_blkno, inode2_blkno;
	struct ocfs2_dinode *di1, *di2;
	struct ocfs2_extent_list *el1, *el2;

	err = ocfs2_malloc_blocks(fs->fs_io, 2, &buf);
	if (err)
		FSWRK_COM_FATAL(progname, err);

	create_file(fs, blkno, &inode1_blkno);

	di1 = (struct ocfs2_dinode *)buf;
	err = ocfs2_read_inode(fs, inode1_blkno, (char *)di1);
	if (err)
		FSWRK_COM_FATAL(progname, err);

	if (ocfs2_support_inline_data(OCFS2_RAW_SB(fs->fs_super))) {
		if (di1->i_dyn_features & OCFS2_INLINE_DATA_FL) {
			di1->i_dyn_features &= ~OCFS2_INLINE_DATA_FL;
			err = ocfs2_write_inode(fs, inode1_blkno, (char *)di1);
			if (err)
				FSWRK_COM_FATAL(progname, err);
		}
	}

	if (type != DUP_CLUSTERS_SYSFILE_CLONE) {

		create_file(fs, blkno, &inode2_blkno);
		di2 = (struct ocfs2_dinode *)(buf + fs->fs_blocksize);
		err = ocfs2_read_inode(fs, inode2_blkno, (char *)di2);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		if (ocfs2_support_inline_data(OCFS2_RAW_SB(fs->fs_super))) {
			if (di2->i_dyn_features & OCFS2_INLINE_DATA_FL) {
				di2->i_dyn_features &= ~OCFS2_INLINE_DATA_FL;
				err = ocfs2_write_inode(fs, inode2_blkno,
							(char *)di2);
				if (err)
					FSWRK_COM_FATAL(progname, err);
			}
		}

		err = ocfs2_extend_allocation(fs, inode2_blkno, 1);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		/* Re-read the inode with the allocation */
		err = ocfs2_read_inode(fs, inode2_blkno, (char *)di2);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		/* Set i_size to non-zero so that the allocation is valid */
		di2->i_size = fs->fs_clustersize;
		err = ocfs2_write_inode(fs, inode2_blkno, (char *)di2);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		if (type == DUP_CLUSTERS_CLONE)
			fprintf(stdout, "DUP_CLUSTERS_CLONE: "
				"Create two inodes #%"PRIu64" and #%"PRIu64
				" by allocating same cluster to them.\n",
				inode1_blkno, inode2_blkno);
		else
			fprintf(stdout, "DUP_CLUSTERS_DELETE: "
				"Create two inodes #%"PRIu64" and #%"PRIu64
				" by allocating same cluster to them.\n",
				inode1_blkno, inode2_blkno);
	} else {
		/* Here use journal file*/
		err = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE, 0,
						&inode2_blkno);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		di2 = (struct ocfs2_dinode *)(buf + fs->fs_blocksize);
		err = ocfs2_read_inode(fs, inode2_blkno, (char *)di2);
		if (err)
			FSWRK_COM_FATAL(progname, err);

		if (di2->id2.i_list.l_tree_depth)
			FSWRK_FATAL("Journal inode has non-zero tree "
				    "depth.  fswreck can't use it for "
				    "DUP_CLUSTERS_SYSFILE_CLONE\n");

		fprintf(stdout, "DUP_CLUSTERS_SYSFILE_CLONE: "
			"Allocate same cluster to journal file "
			"#%"PRIu64" and regular file #%"PRIu64".\n",
			inode1_blkno, inode2_blkno);
	}

	el1 = &(di1->id2.i_list);
	el2 = &(di2->id2.i_list);


	el1->l_next_free_rec = 1;
	el1->l_recs[0] = el2->l_recs[0];

	di1->i_size =
		ocfs2_clusters_to_bytes(fs, el1->l_recs[0].e_leaf_clusters);
	di1->i_clusters = di2->i_clusters;

	err = ocfs2_write_inode(fs, inode1_blkno, (char *)di1);
	if (err)
		FSWRK_COM_FATAL(progname, err);

	ocfs2_free(&buf);
}
예제 #16
0
void mess_up_inline_inode(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno)
{
	int i;
	errcode_t ret;
	char *buf = NULL, file_type[20];
	uint64_t inline_blkno;
	struct ocfs2_dinode *di;
	uint16_t max_inline_sz;
	struct ocfs2_super_block *osb;

	osb = OCFS2_RAW_SB(fs->fs_super);
	if (!ocfs2_support_inline_data(osb))
		FSWRK_FATAL("Should specify a inline-data supported "
			    "volume to do this corruption\n");

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	for (i = 0; i < 2; i++) {
		if (i == 0) {
			create_file(fs, blkno, &inline_blkno);
			snprintf(file_type, 20, "%s", "Regular file");
		} else {
			create_directory(fs, blkno, &inline_blkno);
			snprintf(file_type, 20, "%s", "Diectroy");
		}

		ret = ocfs2_read_inode(fs, inline_blkno, buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		di = (struct ocfs2_dinode *)buf;
		max_inline_sz =
			ocfs2_max_inline_data_with_xattr(fs->fs_blocksize, di);

		if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL))
			di->i_dyn_features |= OCFS2_INLINE_DATA_FL;

		switch (type) {
		case INLINE_DATA_COUNT_INVALID:
			di->id2.i_data.id_count = 0;
			fprintf(stdout, "INLINE_DATA_COUNT_INVALID: "
				"Create an inlined inode#%"PRIu64"(%s),"
				"whose id_count has been messed up.\n",
				inline_blkno, file_type);
			break;
		case INODE_INLINE_SIZE:
			di->i_size = max_inline_sz + 1;
			fprintf(stdout, "INODE_INLINE_SIZE: "
				"Create an inlined inode#%"PRIu64"(%s),"
				"whose i_size has been messed up.\n",
				inline_blkno, file_type);
			break;
		case INODE_INLINE_CLUSTERS:
			di->i_clusters = 1;
			fprintf(stdout, "INODE_INLINE_CLUSTERS: "
				"Create an inlined inode#%"PRIu64"(%s),"
				"whose i_clusters has been messed up.\n",
				inline_blkno, file_type);
			break;

		default:
			FSWRK_FATAL("Invalid type[%d]\n", type);
		}

		ret = ocfs2_write_inode(fs, inline_blkno, buf);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);
	}

	if (buf)
		ocfs2_free(&buf);

	return;
}
예제 #17
0
파일: chain.c 프로젝트: pepe5/ocfs2-tools
static void mess_up_sys_file(ocfs2_filesys *fs, uint64_t blkno,
				enum fsck_type type)
{
	errcode_t ret;
	char *buf = NULL, *bufgroup = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_chain_list *cl;
	struct ocfs2_chain_rec *cr;
	uint64_t oldblkno;
	struct ocfs2_group_desc *bg = NULL;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_BITMAP_FL))
		FSWRK_COM_FATAL(progname, ret);

	if (!(di->i_flags & OCFS2_CHAIN_FL))
		FSWRK_COM_FATAL(progname, ret);

	cl = &(di->id2.i_chain);

	/* for CHAIN_EMPTY, CHAIN_HEAD_LINK_RANGE, CHAIN_LINK_RANGE,
	 * CHAIN_BITS, CHAIN_LINK_GEN, CHAIN_LINK_MAGIC,
	 * we need to corrupt some chain rec, so check it first.
	 */
	if (type == CHAIN_EMPTY || type == CHAIN_HEAD_LINK_RANGE ||
		type == CHAIN_LINK_RANGE || type == CHAIN_BITS 	||
		type == CHAIN_LINK_GEN	 || type == CHAIN_LINK_MAGIC)
		if (!cl->cl_next_free_rec) {
			FSWRK_WARN("No chain record found at block#%"PRIu64
				",so can't corrupt it for type[%d].\n",
				 blkno, type);
			goto bail;
		}

	switch (type) {
	case CHAIN_COUNT:
		fprintf(stdout, "Corrupt CHAIN_COUNT: "
			"Modified cl_count "
			"in block#%"PRIu64" from %u to %u\n",  blkno,
			cl->cl_count, (cl->cl_count + 100));
		cl->cl_count += 100;
		break;
	case CHAIN_NEXT_FREE:
		fprintf(stdout, "Corrupt CHAIN_NEXT_FREE:"
			" Modified cl_next_free_rec "
			"in block#%"PRIu64" from %u to %u\n", blkno,
			cl->cl_next_free_rec, (cl->cl_count + 10));
		cl->cl_next_free_rec = cl->cl_count + 10;
		break;
	case CHAIN_EMPTY:
		cr = cl->cl_recs;
		fprintf(stdout, "Corrupt CHAIN_EMPTY:"
			" Modified e_blkno "
			"in block#%"PRIu64" from %"PRIu64" to 0\n",
			 blkno,	(uint64_t)cr->c_blkno);
		cr->c_blkno = 0;
		break;
	case CHAIN_I_CLUSTERS:
		fprintf(stdout, "Corrupt CHAIN_I_CLUSTERS:"
			"change i_clusters in block#%"PRIu64" from %u to %u\n",
			 blkno, di->i_clusters, (di->i_clusters + 10));
		di->i_clusters += 10;
		break;
	case CHAIN_I_SIZE:
		fprintf(stdout, "Corrupt CHAIN_I_SIZE:"
			"change i_size "
			"in block#%"PRIu64" from %"PRIu64" to %"PRIu64"\n",
			 blkno, (uint64_t)di->i_size, ((uint64_t)di->i_size + 10));
		di->i_size += 10;
		break;
	case CHAIN_GROUP_BITS:
		fprintf(stdout, "Corrupt CHAIN_GROUP_BITS:"
			"change i_used of bitmap "
			"in block#%"PRIu64" from %u to %u\n", blkno, 
			di->id1.bitmap1.i_used, (di->id1.bitmap1.i_used + 10));
		di->id1.bitmap1.i_used += 10;
		break;
	case CHAIN_HEAD_LINK_RANGE:
		cr = cl->cl_recs;
		oldblkno = cr->c_blkno;
		cr->c_blkno = 
			ocfs2_clusters_to_blocks(fs, fs->fs_clusters) + 10;
		fprintf(stdout, "Corrupt CHAIN_HEAD_LINK_RANGE:"
			"change  "
			"in block#%"PRIu64" from %"PRIu64" to %"PRIu64"\n",
			 blkno, oldblkno, (uint64_t)cr->c_blkno);
		break;
	case CHAIN_LINK_GEN:
	case CHAIN_LINK_MAGIC:
	case CHAIN_LINK_RANGE:
		ret = ocfs2_malloc_block(fs->fs_io, &bufgroup);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);
		
		bg = (struct ocfs2_group_desc *)bufgroup;
		cr = cl->cl_recs;

		ret = ocfs2_read_group_desc(fs, cr->c_blkno, (char *)bg);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);

		if (type == CHAIN_LINK_GEN) {
			fprintf(stdout, "Corrupt CHAIN_LINK_GEN: "
				"change generation num from %u to 0x1234\n",
				bg->bg_generation);
			bg->bg_generation = 0x1234;
		} else if (type == CHAIN_LINK_MAGIC) {
			fprintf(stdout, "Corrupt CHAIN_LINK_MAGIC: "
				"change signature to '1234'\n");
			sprintf((char *)bg->bg_signature,"1234");
		} else {
			oldblkno = bg->bg_next_group;
			bg->bg_next_group = 
			    ocfs2_clusters_to_blocks(fs, fs->fs_clusters) + 10;
			fprintf(stdout, "Corrupt CHAIN_LINK_RANGE: "
				"change next group from %"PRIu64" to %"PRIu64
				" \n", oldblkno, (uint64_t)bg->bg_next_group);
		}
		
		ret = ocfs2_write_group_desc(fs, cr->c_blkno, (char *)bg);
		if (ret)
			FSWRK_COM_FATAL(progname, ret);
		break;	
	case CHAIN_BITS:
		cr = cl->cl_recs;
		fprintf(stdout, "Corrupt CHAIN_BITS:"
			"change inode#%"PRIu64" c_total from %u to %u\n",
			 blkno, cr->c_total, (cr->c_total + 10));
		cr->c_total += 10; 
		break;
	case CHAIN_CPG:
		fprintf(stdout, "Corrupt CHAIN_CPG: "
			"change cl_cpg of global_bitmap from %u to %u.\n",
			cl->cl_cpg, (cl->cl_cpg + 16));
		cl->cl_cpg += 16;
		cl->cl_next_free_rec = 1;
		break;
	default:
		FSWRK_FATAL("Unknown fsck_type[%d]\n", type);
	}

	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

bail:
	if (bufgroup)
		ocfs2_free(&bufgroup);
	if (buf)
		ocfs2_free(&buf);

	return ;
}
예제 #18
0
static void damage_local_alloc(ocfs2_filesys *fs,
				uint64_t blkno, enum fsck_type type)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_local_alloc *la;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		FSWRK_FATAL("not a file");

	if (!(di->i_flags & OCFS2_LOCAL_ALLOC_FL))
		FSWRK_FATAL("not a local alloc file");
	
	la = &(di->id2.i_lab);

	/* For LALLOC_BM_OVERRUN, LALLOC_BM_STRADDLE,LALLOC_BM_SIZE,
	 * LALLOC_USED_OVERRUN, LALLOC_CLEAR, i_total must be greater than 0.
	 * So check it first.
	 */
	if (type == LALLOC_BM_OVERRUN || type == LALLOC_BM_STRADDLE ||
		type == LALLOC_BM_SIZE || type == LALLOC_USED_OVERRUN)
		if (di->id1.bitmap1.i_total == 0) {
			FSWRK_WARN("local inode#%"PRIu64" is empty, so can't"
					"corrupt it for type[%d]\n",
					blkno, type);
			goto bail;
		}
	
	switch (type) {
	case LALLOC_SIZE:
	case LALLOC_CLEAR:
		if (type == LALLOC_SIZE)
			fprintf(stdout, "LALLOC_SIZE: ");
		else
			fprintf(stdout, "LALLOC_CLEAR: ");
		fprintf(stdout,	"Corrupt local alloc inode#%"PRIu64
			", change size from %u to %u\n", blkno, la->la_size,
			(ocfs2_local_alloc_size(fs->fs_blocksize) + 10));
		la->la_size = ocfs2_local_alloc_size(fs->fs_blocksize) + 10;
		break;
	case LALLOC_NZ_USED:
		di->id1.bitmap1.i_total = 0;
		di->id1.bitmap1.i_used = 10;
		fprintf(stdout, "LALLOC_NZ_USED: "
			"Corrupt local alloc inode#%"PRIu64", total = %d "
			" used =  %d\n",blkno,  di->id1.bitmap1.i_total,
			di->id1.bitmap1.i_used);
		break;
	case LALLOC_NZ_BM:
		di->id1.bitmap1.i_total = 0;
		la->la_bm_off = 100;
		fprintf(stdout, "LALLOC_NZ_BM: "
			"Corrupt local alloc inode#%"PRIu64", total = %d "
			" la_bm_off =  %d\n",blkno,  di->id1.bitmap1.i_total,
			la->la_bm_off);
		break;
	case LALLOC_BM_OVERRUN:
	case LALLOC_BM_STRADDLE:
		la->la_bm_off = fs->fs_clusters + 10;
		if (type == LALLOC_BM_OVERRUN)
			fprintf(stdout, "LALLOC_BM_OVERRUN: ");
		else
			fprintf(stdout, "LALLOC_BM_STRADDLE: ");
		fprintf(stdout, "Corrupt local alloc inode#%"PRIu64
			", la_bm_off =%u\n", blkno,  la->la_bm_off);
		break;
	case LALLOC_BM_SIZE:
		fprintf(stdout, "LALLOC_SIZE: "
			"Corrupt local alloc inode#%"PRIu64", change i_total"
			" from %u to %u\n", blkno, di->id1.bitmap1.i_total,
			(la->la_size * 8 + 10));
		di->id1.bitmap1.i_total = la->la_size * 8 + 10;
		break;
	case LALLOC_USED_OVERRUN:
		fprintf(stdout, "LALLOC_USED_OVERRUN: "
			"Corrupt local alloc inode#%"PRIu64", change i_used"
			" from %u to %u\n", blkno, di->id1.bitmap1.i_used,
			(di->id1.bitmap1.i_total + 10));
		di->id1.bitmap1.i_used = di->id1.bitmap1.i_total + 10;
		break;
	default:
		FSWRK_FATAL("Unknown type = %d", type);
	}
	
	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		FSWRK_COM_FATAL(progname, ret);
bail:
	if (buf)
		ocfs2_free(&buf);
	return;
}