コード例 #1
0
ファイル: backup_super.c プロジェクト: djs55/ocfs2-tools
errcode_t ocfs2_clear_backup_super_list(ocfs2_filesys *fs,
					uint64_t *blocks, size_t len)
{
	size_t i;
	errcode_t ret = 0;

	if (!len || !blocks || !*blocks)
		goto bail;
	len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS);

	/*
	 * Don't clear anything if backup superblocks aren't enabled -
	 * there might be real data there!  If backup superblocks are
	 * enabled, we know these blocks are backups, and we're
	 * safe to clear them.
	 */
	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
		goto bail;


	for (i = 0; i < len; i++) {
		ret = ocfs2_free_clusters(fs, 1, blocks[i]);
		if (ret)
			break;
	}

bail:
	return ret;
}
コード例 #2
0
ファイル: backup_super.c プロジェクト: djs55/ocfs2-tools
errcode_t ocfs2_set_backup_super_list(ocfs2_filesys *fs,
				      uint64_t *blocks, size_t len)
{
	size_t i;
	errcode_t ret = 0;
	char *buf = NULL;
	uint64_t *blkno = blocks;
	uint32_t cluster, bpc = fs->fs_clustersize / fs->fs_blocksize;

	if (!len || !blocks || !*blocks)
		goto bail;
	len = ocfs2_min(len,(size_t)OCFS2_MAX_BACKUP_SUPERBLOCKS);

	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
				      OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
		/* check all the blkno to see whether it is used. */
		for (i = 0; i < len; i++, blkno++) {
			ret = check_cluster(fs,
					    ocfs2_blocks_to_clusters(fs, *blkno));
			if (ret)
				goto bail;
		}
	}

	ret = ocfs2_malloc_blocks(fs->fs_io, bpc, &buf);
	if (ret)
		goto bail;
	memset(buf, 0, fs->fs_clustersize);

	/* zero all the clusters at first */
	blkno = blocks;
	for (i = 0; i < len; i++, blkno++) {
		cluster = ocfs2_blocks_to_clusters(fs, *blkno);
		ret = io_write_block(fs->fs_io, cluster*bpc, bpc, buf);
		if (ret)
			goto bail;
	}

	ret = ocfs2_refresh_backup_super_list(fs, blocks, len);
	if (ret)
		goto bail;

	/* We just tested the clusters, so the allocation can't fail */
	blkno = blocks;
	for (i = 0; i < len; i++, blkno++)
		ocfs2_new_specific_cluster(fs, ocfs2_blocks_to_clusters(fs, *blkno));

bail:
	if (buf)
		ocfs2_free(&buf);
	return ret;
}
コード例 #3
0
ファイル: backup_super.c プロジェクト: djs55/ocfs2-tools
errcode_t ocfs2_refresh_backup_supers(ocfs2_filesys *fs)
{
	int num;
	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];

	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
		return 0;  /* Do nothing */

	num = ocfs2_get_backup_super_offsets(fs, blocks,
					     ARRAY_SIZE(blocks));
	return num ? ocfs2_refresh_backup_super_list(fs, blocks, num) : 0;
}
コード例 #4
0
static int enable_backup_super(ocfs2_filesys *fs, int flags)
{
	errcode_t err = 0;
	struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
	struct tools_progress *prog;

	if (OCFS2_HAS_COMPAT_FEATURE(super,
				     OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
		verbosef(VL_APP,
			 "Backup superblock feature is already enabled; "
			 "nothing to enable\n");
		goto out;
	}

	if (!tools_interact("Enable the backup superblock feature on "
			    "device \"%s\"? ",
			    fs->fs_devname))
		goto out;

	prog = tools_progress_start("Enable backup-super", "backup-super",
				    2);
	if (!prog) {
		err = TUNEFS_ET_NO_MEMORY;
		tcom_err(err, "while initializing the progress display");
		goto out;
	}

	tunefs_block_signals();
	err = check_backup_offsets(fs);
	tools_progress_step(prog, 1);
	if (!err)
		err = fill_backup_supers(fs);
	if (!err) {
		super->s_feature_compat |= OCFS2_FEATURE_COMPAT_BACKUP_SB;
		err = ocfs2_write_super(fs);
		if (err)
			tcom_err(err, "while writing out the superblock\n");
	}
	tunefs_unblock_signals();

	tools_progress_step(prog, 1);
	tools_progress_stop(prog);

	if (err)
		errorf("Unable to enable the backup superblock feature on "
		       "device \"%s\"\n",
		       fs->fs_devname);
out:
	return err;
}
コード例 #5
0
ファイル: backup_super.c プロジェクト: djs55/ocfs2-tools
errcode_t ocfs2_read_backup_super(ocfs2_filesys *fs, int backup, char *sbbuf)
{
	int numsb;
	uint64_t blocks[OCFS2_MAX_BACKUP_SUPERBLOCKS];

	if (!OCFS2_HAS_COMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
				      OCFS2_FEATURE_COMPAT_BACKUP_SB))
		return OCFS2_ET_NO_BACKUP_SUPER;

	numsb = ocfs2_get_backup_super_offsets(fs, blocks,
					       ARRAY_SIZE(blocks));
	if (backup < 0 || backup >= numsb)
		return OCFS2_ET_NO_BACKUP_SUPER;

	return ocfs2_read_super(fs, blocks[backup], sbbuf);
}
コード例 #6
0
static void ocfs2_update_super_and_backups(struct inode *inode,
					   int new_clusters)
{
	int ret;
	u32 clusters = 0;
	struct buffer_head *super_bh = NULL;
	struct ocfs2_dinode *super_di = NULL;
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);

	/*
	 * update the superblock last.
	 * It doesn't matter if the write failed.
	 */
	ret = ocfs2_read_blocks_sync(osb, OCFS2_SUPER_BLOCK_BLKNO, 1,
				     &super_bh);
	if (ret < 0) {
		mlog_errno(ret);
		goto out;
	}

	super_di = (struct ocfs2_dinode *)super_bh->b_data;
	le32_add_cpu(&super_di->i_clusters, new_clusters);
	clusters = le32_to_cpu(super_di->i_clusters);

	ret = ocfs2_write_super_or_backup(osb, super_bh);
	if (ret < 0) {
		mlog_errno(ret);
		goto out;
	}

	if (OCFS2_HAS_COMPAT_FEATURE(osb->sb, OCFS2_FEATURE_COMPAT_BACKUP_SB))
		ret = update_backups(inode, clusters, super_bh->b_data);

out:
	brelse(super_bh);
	if (ret)
		printk(KERN_WARNING "ocfs2: Failed to update super blocks on %s"
			" during fs resize. This condition is not fatal,"
			" but fsck.ocfs2 should be run to fix it\n",
			osb->dev_str);
	return;
}
コード例 #7
0
static int ocfs2_update_last_group_and_inode(handle_t *handle,
					     struct inode *bm_inode,
					     struct buffer_head *bm_bh,
					     struct buffer_head *group_bh,
					     u32 first_new_cluster,
					     int new_clusters)
{
	int ret = 0;
	struct ocfs2_super *osb = OCFS2_SB(bm_inode->i_sb);
	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bm_bh->b_data;
	struct ocfs2_chain_list *cl = &fe->id2.i_chain;
	struct ocfs2_chain_rec *cr;
	struct ocfs2_group_desc *group;
	u16 chain, num_bits, backups = 0;
	u16 cl_bpc = le16_to_cpu(cl->cl_bpc);
	u16 cl_cpg = le16_to_cpu(cl->cl_cpg);

	trace_ocfs2_update_last_group_and_inode(new_clusters,
						first_new_cluster);

	ret = ocfs2_journal_access_gd(handle, INODE_CACHE(bm_inode),
				      group_bh, OCFS2_JOURNAL_ACCESS_WRITE);
	if (ret < 0) {
		mlog_errno(ret);
		goto out;
	}

	group = (struct ocfs2_group_desc *)group_bh->b_data;

	/* update the group first. */
	num_bits = new_clusters * cl_bpc;
	le16_add_cpu(&group->bg_bits, num_bits);
	le16_add_cpu(&group->bg_free_bits_count, num_bits);

	/*
	 * check whether there are some new backup superblocks exist in
	 * this group and update the group bitmap accordingly.
	 */
	if (OCFS2_HAS_COMPAT_FEATURE(osb->sb,
				     OCFS2_FEATURE_COMPAT_BACKUP_SB)) {
		backups = ocfs2_calc_new_backup_super(bm_inode,
						     group,
						     new_clusters,
						     first_new_cluster,
						     cl_cpg, 1);
		le16_add_cpu(&group->bg_free_bits_count, -1 * backups);
	}

	ocfs2_journal_dirty(handle, group_bh);

	/* update the inode accordingly. */
	ret = ocfs2_journal_access_di(handle, INODE_CACHE(bm_inode), bm_bh,
				      OCFS2_JOURNAL_ACCESS_WRITE);
	if (ret < 0) {
		mlog_errno(ret);
		goto out_rollback;
	}

	chain = le16_to_cpu(group->bg_chain);
	cr = (&cl->cl_recs[chain]);
	le32_add_cpu(&cr->c_total, num_bits);
	le32_add_cpu(&cr->c_free, num_bits);
	le32_add_cpu(&fe->id1.bitmap1.i_total, num_bits);
	le32_add_cpu(&fe->i_clusters, new_clusters);

	if (backups) {
		le32_add_cpu(&cr->c_free, -1 * backups);
		le32_add_cpu(&fe->id1.bitmap1.i_used, backups);
	}

	spin_lock(&OCFS2_I(bm_inode)->ip_lock);
	OCFS2_I(bm_inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
	le64_add_cpu(&fe->i_size, new_clusters << osb->s_clustersize_bits);
	spin_unlock(&OCFS2_I(bm_inode)->ip_lock);
	i_size_write(bm_inode, le64_to_cpu(fe->i_size));

	ocfs2_journal_dirty(handle, bm_bh);

out_rollback:
	if (ret < 0) {
		ocfs2_calc_new_backup_super(bm_inode,
					    group,
					    new_clusters,
					    first_new_cluster,
					    cl_cpg, 0);
		le16_add_cpu(&group->bg_free_bits_count, backups);
		le16_add_cpu(&group->bg_bits, -1 * num_bits);
		le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits);
	}
out:
	if (ret)
		mlog_errno(ret);
	return ret;
}