Esempio n. 1
0
errcode_t ocfs2_block_iterate(ocfs2_filesys *fs,
			      uint64_t blkno,
			      int flags,
			      int (*func)(ocfs2_filesys *fs,
					  uint64_t blkno,
					  uint64_t bcount,
					  uint16_t ext_flags,
					  void *priv_data),
			      void *priv_data)
{
	struct ocfs2_dinode *inode;
	errcode_t ret;
	char *buf;

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

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto out_buf;

	inode = (struct ocfs2_dinode *)buf;

	ret = ocfs2_block_iterate_inode(fs, inode, flags, func, priv_data);

out_buf:
	ocfs2_free(&buf);
	return ret;
}
Esempio n. 2
0
errcode_t ocfs2_extent_iterate(ocfs2_filesys *fs,
			       uint64_t blkno,
			       int flags,
			       char *block_buf,
			       int (*func)(ocfs2_filesys *fs,
					   struct ocfs2_extent_rec *rec,
					   int tree_depth,
					   uint32_t ccount,
					   uint64_t ref_blkno,
					   int ref_recno,
					   void *priv_data),
			       void *priv_data)
{
	char *buf = NULL;
	struct ocfs2_dinode *inode;
	errcode_t ret;

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

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto out_buf;

	inode = (struct ocfs2_dinode *)buf;

	ret = ocfs2_extent_iterate_inode(fs, inode, flags, block_buf,
					 func, priv_data);

out_buf:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 3
0
errcode_t o2fsck_type_from_dinode(o2fsck_state *ost, uint64_t ino,
                                  uint8_t *type)
{
    char *buf = NULL;
    errcode_t ret;
    struct ocfs2_dinode *dinode;
    const char *whoami = __FUNCTION__;

    *type = 0;

    ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &buf);
    if (ret) {
        com_err(whoami, ret, "while allocating an inode buffer to "
                "read and discover the type of inode %"PRIu64, ino);
        goto out;
    }

    ret = ocfs2_read_inode(ost->ost_fs, ino, buf);
    if (ret) {
        com_err(whoami, ret, "while reading inode %"PRIu64" to "
                "discover its file type", ino);
        goto out;
    }

    dinode = (struct ocfs2_dinode *)buf;
    *type = ocfs2_type_by_mode[(dinode->i_mode & S_IFMT)>>S_SHIFT];

out:
    if (buf)
        ocfs2_free(&buf);
    return ret;
}
Esempio n. 4
0
errcode_t ocfs2_write_backup_super(ocfs2_filesys *fs, uint64_t blkno)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;

	if (!(fs->fs_flags & OCFS2_FLAG_RW))
		return OCFS2_ET_RO_FILESYS;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		goto out_blk;

	memcpy(buf, (char *)fs->fs_super, fs->fs_blocksize);
	di = (struct ocfs2_dinode *)buf;

	ret = OCFS2_ET_BAD_MAGIC;
	if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
		   strlen(OCFS2_SUPER_BLOCK_SIGNATURE)))
		goto out_blk;

	di->i_blkno = blkno;
	OCFS2_SET_COMPAT_FEATURE(OCFS2_RAW_SB(di),
				 OCFS2_FEATURE_COMPAT_BACKUP_SB);
	ret = ocfs2_write_inode(fs, blkno, buf);
	if (ret)
		goto out_blk;

	ret = 0;

out_blk:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 5
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;
}
Esempio n. 6
0
/*
 * Emtpy the blocks on the disk.
 */
static errcode_t empty_blocks(ocfs2_filesys *fs,
			      uint64_t start_blk,
			      uint64_t num_blocks)
{
	errcode_t ret;
	char *buf = NULL;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		goto bail;

	memset(buf, 0, fs->fs_blocksize);

	while (num_blocks) {
		ret = io_write_block(fs->fs_io, start_blk, 1, buf);
		if (ret)
			goto bail;

		num_blocks--;
		start_blk++;
	}

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

	return ret;
}
Esempio n. 7
0
errcode_t ocfs2_extend_file(ocfs2_filesys *fs, uint64_t ino, uint64_t new_size)
{
	errcode_t ret = 0;
	char *buf = NULL;
	struct ocfs2_dinode* di = NULL;

	if (!(fs->fs_flags & OCFS2_FLAG_RW))
		return OCFS2_ET_RO_FILESYS;
	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		return ret;

	ret = ocfs2_read_inode(fs, ino, buf);
	if (ret)
		goto out_free_buf;

	di = (struct ocfs2_dinode *)buf;
	if (di->i_size >= new_size) {
		ret = EINVAL;
		goto out_free_buf;
	}

	di->i_size = new_size;

	ret = ocfs2_write_inode(fs, ino, buf);

out_free_buf:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 8
0
void dump_dx_entries(FILE *out, struct ocfs2_dinode *inode)
{
    struct ocfs2_dx_root_block *dx_root;
    uint64_t dx_blkno;
    char *buf = NULL;
    errcode_t ret = 0;

    if (ocfs2_malloc_block(gbls.fs->fs_io, &buf))
        return;

    if (!(ocfs2_dir_indexed(inode)))
        return;

    dx_blkno = (uint64_t) inode->i_dx_root;

    ret = ocfs2_read_dx_root(gbls.fs, dx_blkno, buf);
    if (ret)
        return;

    dx_root = (struct ocfs2_dx_root_block *)buf;
    dump_dx_root(out, dx_root);

    ocfs2_dx_entries_iterate(gbls.fs, inode, 0, entries_iter, out);
    return;
}
Esempio n. 9
0
static errcode_t ocfs2_validate_ocfs1_header(ocfs2_filesys *fs)
{
	errcode_t ret;
	char *blk;
	struct ocfs1_vol_disk_hdr *hdr;
	
	ret = ocfs2_malloc_block(fs->fs_io, &blk);
	if (ret)
		return ret;

	ret = ocfs2_read_blocks(fs, 0, 1, blk);
	if (ret)
		goto out;
	hdr = (struct ocfs1_vol_disk_hdr *)blk;

	ret = OCFS2_ET_OCFS_REV;
	if (le32_to_cpu(hdr->major_version) == OCFS1_MAJOR_VERSION)
		goto out;
	if (!memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE,
		    strlen(OCFS1_VOLUME_SIGNATURE)))
		goto out;

	ret = 0;

out:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 10
0
static errcode_t create_local_alloc(ocfs2_filesys *fs, uint16_t slot)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_local_alloc *la;
	uint32_t la_size, found;
	uint64_t la_off, blkno;

	ret = ocfs2_lookup_system_inode(fs, LOCAL_ALLOC_SYSTEM_INODE,
					slot, &blkno);
	if (ret)
		goto bail;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		goto bail;

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto bail;

	di = (struct ocfs2_dinode *)buf;

	if (!(di->i_flags & OCFS2_VALID_FL))
		goto bail;

	if (!(di->i_flags & OCFS2_LOCAL_ALLOC_FL))
		goto bail;

	if (di->id1.bitmap1.i_total > 0) {
		fprintf(stderr, "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)
		goto bail;

	if(la_size != found)
		goto bail;

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

	la->la_bm_off = ocfs2_blocks_to_clusters(fs, 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);

bail:
	if(buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 11
0
errcode_t ocfs2_chain_iterate(ocfs2_filesys *fs,
			      uint64_t blkno,
			      int (*func)(ocfs2_filesys *fs,
					  uint64_t gd_blkno,
					  int chain_num,
					  void *priv_data),
			       void *priv_data)
{
	int iret = 0;
	char *buf;
	struct ocfs2_dinode *inode;
	errcode_t ret;
	struct chain_context ctxt;

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

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto out_buf;

	inode = (struct ocfs2_dinode *)buf;

	ret = OCFS2_ET_INODE_NOT_VALID;
	if (!(inode->i_flags & OCFS2_VALID_FL))
		goto out_buf;

	ret = OCFS2_ET_INODE_CANNOT_BE_ITERATED;
	if (!(inode->i_flags & OCFS2_CHAIN_FL))
		goto out_buf;

	ret = ocfs2_malloc0(fs->fs_blocksize, &ctxt.gd_buf);
	if (ret)
		goto out_gd_buf;

	ctxt.fs = fs;
	ctxt.func = func;
	ctxt.priv_data = priv_data;

	ret = 0;
	iret |= chain_iterate_cl(&inode->id2.i_chain, &ctxt);
	if (iret & OCFS2_EXTENT_ERROR)
		ret = ctxt.errcode;

	if (iret & OCFS2_EXTENT_CHANGED) {
		/* Do something */
	}

out_gd_buf:
	if (ctxt.gd_buf)
		ocfs2_free(&ctxt.gd_buf);

out_buf:
	ocfs2_free(&buf);

	return ret;
}
Esempio n. 12
0
static errcode_t truncate_log_check(ocfs2_filesys *fs,
				    uint16_t new_slots)
{
	errcode_t ret = 0;
	uint16_t i;
	uint64_t blkno;
	char *buf = NULL;
	struct ocfs2_dinode *di = NULL;

	uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret) {
		verbosef(VL_APP,
			 "%s while allocating inode buffer for "
			 "truncate log check\n",
			 error_message(ret));
		goto bail;
	}

	for (i = new_slots; i < max_slots; ++i) {
		ret = ocfs2_lookup_system_inode(fs, TRUNCATE_LOG_SYSTEM_INODE,
						i, &blkno);
		if (ret) {
			verbosef(VL_APP,
				 "%s while looking up truncate log for "
				 "slot %u during truncate log check\n",
				 error_message(ret), i);
			goto bail;
		}

		ret = ocfs2_read_inode(fs, blkno, buf);
		if (ret) {
			verbosef(VL_APP,
				 "%s while reading inode %"PRIu64" "
				 "during truncate log check\n",
				 error_message(ret), blkno);
			goto bail;
		}

		di = (struct ocfs2_dinode *)buf;

		if (di->id2.i_dealloc.tl_used > 0) {
			ret = TUNEFS_ET_TRUNCATE_LOG_NOT_EMPTY;
			verbosef(VL_APP,
				 "Truncate log for slot %u is not empty\n",
				 i);
			goto bail;
		}
	}

bail:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 13
0
static errcode_t local_alloc_check(ocfs2_filesys *fs,
				   uint16_t new_slots)
{
	errcode_t ret = 0;
	uint16_t i;
	uint64_t blkno;
	char *buf = NULL;
	struct ocfs2_dinode *di = NULL;

	uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret) {
		verbosef(VL_APP,
			 "%s while allocating inode buffer for local "
			 "alloc check\n",
			 error_message(ret));
		goto bail;
	}

	for (i = new_slots ; i < max_slots; ++i) {
		ret = ocfs2_lookup_system_inode(fs, LOCAL_ALLOC_SYSTEM_INODE,
						i, &blkno);
		if (ret) {
			verbosef(VL_APP,
				 "%s while looking up local alloc for "
				 "slot %u during local alloc check\n",
				 error_message(ret), i);
			break;
		}

		ret = ocfs2_read_inode(fs, blkno, buf);
		if (ret) {
			verbosef(VL_APP,
				 "%s while reading inode %"PRIu64" "
				 "during local alloc check\n",
				 error_message(ret), blkno);
			break;
		}

		di = (struct ocfs2_dinode *)buf;
		if (di->id1.bitmap1.i_total > 0) {
			ret = TUNEFS_ET_LOCAL_ALLOC_NOT_EMPTY;
			verbosef(VL_APP,
				 "Local alloc for slot %u is not empty\n",
				 i);
			break;
		}
	}

bail:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 14
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;
}
Esempio n. 15
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;
}
Esempio n. 16
0
int is_dir_inlined(char *dirent_name, unsigned long *i_size,
			   unsigned int *id_count)
{
	int ret;
	uint64_t workplace_blk_no = 1;
	uint64_t testdir_blk_no = 1;
	char *buf = NULL;
	struct ocfs2_dinode *di;
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);

	sync();

	ocfs2_malloc_block(fs->fs_io, &buf);

	/*lookup worksplace inode*/
	ret = ocfs2_lookup(fs, sb->s_root_blkno, WORK_PLACE,
			   strlen(WORK_PLACE), NULL, &workplace_blk_no);
	if (ret < 0) {
		fprintf(stderr, "failed to lookup work_place(%s)'s"
			" inode blkno\n", work_place);
		ocfs2_free(&buf);
		exit(ret);
	}

	/*lookup file inode,then read*/
	ret = ocfs2_lookup(fs, workplace_blk_no, dirent_name,
			   strlen(dirent_name), NULL, &testdir_blk_no);
	if (ret < 0) {
		fprintf(stderr, "failed to lookup file(%s/%s)'s"
			" inode blkno\n", work_place, dirent_name);
		ocfs2_free(&buf);
		exit(ret);
	}

	ret = ocfs2_read_inode(fs, testdir_blk_no, buf);
	if (ret < 0) {
		fprintf(stderr, "failed to read file(%s/%s/%s)'s"
			" inode.\n", mount_point, WORK_PLACE, dirent_name);
		ocfs2_free(&buf);
		exit(ret);
	}

	di = (struct ocfs2_dinode *)buf;
	*i_size = di->i_size;
	*id_count = ((di->id2).i_data).id_count;

	if (di->i_dyn_features & OCFS2_INLINE_DATA_FL)
		ret = 1;
	else
		ret = 0;

	ocfs2_free(&buf);
	return ret;
}
Esempio n. 17
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;
}
Esempio n. 18
0
/*
 * NOTE: ocfs2_truncate_inline() also handles fast symlink,
 * since truncating for inline file and fasy symlink are
 * almost the same thing per se.
 */
errcode_t ocfs2_truncate_inline(ocfs2_filesys *fs, uint64_t ino,
				uint64_t new_i_size)
{
	errcode_t ret = 0;
	char *buf = NULL;
	struct ocfs2_dinode *di = NULL;
	struct ocfs2_inline_data *idata = NULL;

	if (!(fs->fs_flags & OCFS2_FLAG_RW))
		return OCFS2_ET_RO_FILESYS;

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

	ret = ocfs2_read_inode(fs, ino, buf);
	if (ret)
		goto out_free_buf;

	di = (struct ocfs2_dinode *)buf;
	if (di->i_size < new_i_size) {
		ret = EINVAL;
		goto out_free_buf;
	}

	idata = &di->id2.i_data;

	if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL) &&
	    !(S_ISLNK(di->i_mode) && !di->i_clusters)) {
		ret = EINVAL;
		goto out_free_buf;
	}

	if (di->i_dyn_features & OCFS2_INLINE_DATA_FL)
		memset(idata->id_data + new_i_size, 0, di->i_size - new_i_size);
	else
		memset(di->id2.i_symlink + new_i_size, 0,
		       di->i_size - new_i_size);

	di->i_size = new_i_size;

	ret = ocfs2_write_inode(fs, ino, buf);

out_free_buf:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 19
0
static errcode_t remove_slot_entry(ocfs2_filesys *fs, uint16_t removed_slot)
{
	struct remove_slot_ctxt ctxt = {
		.fs = fs,
		.removed_slot = removed_slot,
		.errcode = 0
	};

	ocfs2_dir_iterate(fs, fs->fs_sysdir_blkno,
			  OCFS2_DIRENT_FLAG_EXCLUDE_DOTS, NULL,
			  remove_slot_iterate, &ctxt);

	return ctxt.errcode;
}

static errcode_t decrease_link_count(ocfs2_filesys *fs, uint16_t blkno)
{
	errcode_t ret;
	char *buf = NULL;
	struct ocfs2_dinode *di  = NULL;

	ret = ocfs2_malloc_block(fs->fs_io, &buf);
	if (ret)
		goto bail;

	ret = ocfs2_read_inode(fs, blkno, buf);
	if (ret)
		goto bail;

	di = (struct ocfs2_dinode *)buf;

	if (di->i_links_count > 0)
		di->i_links_count--;
	else {
		ret = OCFS2_ET_INODE_NOT_VALID;
		goto bail;
	}

	ret = ocfs2_write_inode(fs, blkno, buf);
bail:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 20
0
errcode_t handle_slots_system_file(ocfs2_filesys *fs,
                                   int type,
                                   errcode_t (*func)(ocfs2_filesys *fs,
                                           struct ocfs2_dinode *di,
                                           int slot))
{
    errcode_t ret;
    uint64_t blkno;
    int slot, max_slots;
    char *buf = NULL;
    struct ocfs2_dinode *di;

    ret = ocfs2_malloc_block(fs->fs_io, &buf);
    if (ret)
        goto bail;

    di = (struct ocfs2_dinode *)buf;

    max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;

    for (slot = 0; slot < max_slots; slot++) {
        ret = ocfs2_lookup_system_inode(fs,
                                        type,
                                        slot, &blkno);
        if (ret)
            goto bail;

        ret = ocfs2_read_inode(fs, blkno, buf);
        if (ret)
            goto bail;

        if (func) {
            ret = func(fs, di, slot);
            if (ret)
                goto bail;
        }
    }

bail:

    if (buf)
        ocfs2_free(&buf);
    return ret;
}
Esempio n. 21
0
errcode_t ocfs2_get_last_cluster_offset(ocfs2_filesys *fs,
					struct ocfs2_dinode *di,
					uint32_t *v_cluster)
{
	errcode_t ret = 0;
	char *buf = NULL;
	struct ocfs2_extent_list *el = NULL;
	struct ocfs2_extent_rec *er = NULL;

	el = &di->id2.i_list;

	*v_cluster = 0;
	if (!el->l_next_free_rec)
		return 0;

	if (el->l_tree_depth) {
		ret = ocfs2_malloc_block(fs->fs_io, &buf);
		if (ret)
			goto bail;

		ret = ocfs2_read_extent_block(fs, di->i_last_eb_blk, buf);
		if (ret)
			goto bail;

		el = &((struct ocfs2_extent_block *)buf)->h_list;

		if (!el->l_next_free_rec ||
		    (el->l_next_free_rec == 1 &&
		     ocfs2_is_empty_extent(&el->l_recs[0]))) {
			ret = OCFS2_ET_CORRUPT_EXTENT_BLOCK;
			goto bail;
		}
	}

	er = &el->l_recs[el->l_next_free_rec - 1];

	*v_cluster = er->e_cpos + er->e_leaf_clusters - 1;

bail:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
Esempio n. 22
0
errcode_t ocfs2_read_extent_block_nocheck(ocfs2_filesys *fs,
					  uint64_t blkno,
					  char *eb_buf)
{
	errcode_t ret;
	char *blk;
	struct ocfs2_extent_block *eb;

	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
	    (blkno > fs->fs_blocks))
		return OCFS2_ET_BAD_BLKNO;

	ret = ocfs2_malloc_block(fs->fs_io, &blk);
	if (ret)
		return ret;

	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
	if (ret)
		goto out;

	eb = (struct ocfs2_extent_block *)blk;

	ret = ocfs2_validate_meta_ecc(fs, blk, &eb->h_check);
	if (ret)
		goto out;

	if (memcmp(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE,
		   strlen(OCFS2_EXTENT_BLOCK_SIGNATURE))) {
		ret = OCFS2_ET_BAD_EXTENT_BLOCK_MAGIC;
		goto out;
	}

	memcpy(eb_buf, blk, fs->fs_blocksize);

	eb = (struct ocfs2_extent_block *) eb_buf;
	ocfs2_swap_extent_block_to_cpu(fs, eb);

out:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
errcode_t ocfs2_read_group_desc(ocfs2_filesys *fs, uint64_t blkno,
				char *gd_buf)
{
	errcode_t ret;
	char *blk;
	struct ocfs2_group_desc *gd;

	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
	    (blkno > fs->fs_blocks))
		return OCFS2_ET_BAD_BLKNO;

	ret = ocfs2_malloc_block(fs->fs_io, &blk);
	if (ret)
		return ret;

	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
	if (ret)
		goto out;

	gd = (struct ocfs2_group_desc *)blk;

	ret = ocfs2_validate_meta_ecc(fs, blk, &gd->bg_check);
	if (ret)
		goto out;

	ret = OCFS2_ET_BAD_GROUP_DESC_MAGIC;
	if (memcmp(gd->bg_signature, OCFS2_GROUP_DESC_SIGNATURE,
		   strlen(OCFS2_GROUP_DESC_SIGNATURE)))
		goto out;

	memcpy(gd_buf, blk, fs->fs_blocksize);

	gd = (struct ocfs2_group_desc *)gd_buf;
	ocfs2_swap_group_desc_to_cpu(fs, gd);

	ret = 0;
out:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 25
0
static errcode_t io_validate_o_direct(io_channel *channel)
{
	errcode_t ret = OCFS2_ET_UNEXPECTED_BLOCK_SIZE;
	int block_size;
	char *blk;

	for (block_size = io_get_blksize(channel);
	     block_size <= OCFS2_MAX_BLOCKSIZE;
	     block_size <<= 1) {
		io_set_blksize(channel, block_size);
		ret = ocfs2_malloc_block(channel, &blk);
		if (ret)
			break;

		ret = unix_io_read_block(channel, 0, 1, blk);
		ocfs2_free(&blk);
		if (!ret)
			break;
	}

	return ret;
}
Esempio n. 26
0
/*
 * dump_xattr_block()
 *
 */
errcode_t dump_xattr_block(FILE *out, ocfs2_filesys *fs,
                           struct ocfs2_dinode *in,
                           uint32_t *xattrs_block,
                           uint64_t *xattrs_bucket,
                           int verbose)
{
    errcode_t ret;
    char *blk = NULL;
    struct ocfs2_xattr_block *xb = NULL;

    ret = ocfs2_malloc_block(fs->fs_io, &blk);
    if (ret)
        goto out;

    ret = ocfs2_read_xattr_block(fs, in->i_xattr_loc, blk);
    if (ret)
        goto out;

    xb = (struct ocfs2_xattr_block *)blk;

    if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
        struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header;
        *xattrs_block = xh->xh_count;
        fprintf(out, "\tExtended Attributes in block #%"PRIu64": %u\n",
                (uint64_t)in->i_xattr_loc, *xattrs_block);
        if (verbose)
            dump_xattr(out, xh);
    } else {
        ret = dump_xattr_index_block(out, fs, in, xb,
                                     xattrs_bucket, verbose);
    }

out:
    if (blk)
        ocfs2_free(&blk);
    return ret;
}
Esempio n. 27
0
errcode_t ocfs2_write_extent_block(ocfs2_filesys *fs, uint64_t blkno,
				   char *eb_buf)
{
	errcode_t ret;
	char *blk;
	struct ocfs2_extent_block *eb;

	if (!(fs->fs_flags & OCFS2_FLAG_RW))
		return OCFS2_ET_RO_FILESYS;

	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
	    (blkno > fs->fs_blocks))
		return OCFS2_ET_BAD_BLKNO;

	ret = ocfs2_malloc_block(fs->fs_io, &blk);
	if (ret)
		return ret;

	memcpy(blk, eb_buf, fs->fs_blocksize);

	eb = (struct ocfs2_extent_block *) blk;
	ocfs2_swap_extent_block_from_cpu(fs, eb);

	ocfs2_compute_meta_ecc(fs, blk, &eb->h_check);
	ret = io_write_block(fs->fs_io, blkno, 1, blk);
	if (ret)
		goto out;

	fs->fs_flags |= OCFS2_FLAG_CHANGED;
	ret = 0;

out:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 28
0
errcode_t ocfs2_write_group_desc(ocfs2_filesys *fs, uint64_t blkno,
				 char *gd_buf)
{
	errcode_t ret;
	char *blk;
	struct ocfs2_group_desc *gd;

	if (!(fs->fs_flags & OCFS2_FLAG_RW))
		return OCFS2_ET_RO_FILESYS;

	if ((blkno < OCFS2_SUPER_BLOCK_BLKNO) ||
	    (blkno > fs->fs_blocks))
		return OCFS2_ET_BAD_BLKNO;

	ret = ocfs2_malloc_block(fs->fs_io, &blk);
	if (ret)
		return ret;

	memcpy(blk, gd_buf, fs->fs_blocksize);

	gd = (struct ocfs2_group_desc *)blk;
	ocfs2_swap_group_desc_from_cpu(fs, gd);

	ocfs2_compute_meta_ecc(fs, blk, &gd->bg_check);
	ret = io_write_block(fs->fs_io, blkno, 1, blk);
	if (ret)
		goto out;

	fs->fs_flags |= OCFS2_FLAG_CHANGED;
	ret = 0;

out:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 29
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;
}
Esempio n. 30
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;
}