コード例 #1
0
ファイル: openfs.c プロジェクト: pepe5/ocfs2-tools
errcode_t ocfs2_write_super(ocfs2_filesys *fs)
{
	errcode_t ret;

	ret = ocfs2_write_primary_super(fs);
	if (!ret)
		ret = ocfs2_refresh_backup_supers(fs);

	return ret;
}
コード例 #2
0
ファイル: fsck.c プロジェクト: abligh/ocfs2-tools
static errcode_t recover_backup_super(o2fsck_state *ost,
				      char* device, int sb_num)
{
	errcode_t ret;
	uint64_t offsets[OCFS2_MAX_BACKUP_SUPERBLOCKS], blksize, sb;
	ocfs2_filesys *fs = NULL;

	if (sb_num < 1 || sb_num > OCFS2_MAX_BACKUP_SUPERBLOCKS)
		return -1;

	ocfs2_get_backup_super_offsets(NULL, offsets, ARRAY_SIZE(offsets));

	/* iterate all the blocksize to get the right one. */
	for (blksize = OCFS2_MIN_BLOCKSIZE;
		blksize <= OCFS2_MAX_BLOCKSIZE;	blksize <<= 1) {
		sb = offsets[sb_num - 1] / blksize;
		/* Here we just give the possible value of block num and
		 * block size to ocfs2_open and this function will check
		 * them and return '0' if they meet the right one.
		 */
		ret = ocfs2_open(device, OCFS2_FLAG_RW, sb, blksize, &fs);
		if (!ret)
			break;
	}

	if (ret)
		goto bail;

	/* recover the backup information to superblock. */
	if (prompt(ost, PN, PR_RECOVER_BACKUP_SUPERBLOCK,
	    	   "Recover superblock information from backup block"
		   "#%"PRIu64"?", sb)) {
		fs->fs_super->i_blkno = OCFS2_SUPER_BLOCK_BLKNO;
		ret = ocfs2_write_primary_super(fs);
		if (ret)
			goto bail;
	}

	/* no matter whether the user recover the superblock or not above,
	 * we should return 0 in case the superblock can be opened
	 * without the recovery.
	 */
	ret = 0;

bail:
	if (fs)
		ocfs2_close(fs);
	return ret;
}
コード例 #3
0
ファイル: pass3.c プロジェクト: pepe5/ocfs2-tools
static void check_root(o2fsck_state *ost)
{
	struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super);
	errcode_t ret;
	uint64_t blkno, old_root;
	int was_set;

	if (o2fsck_test_inode_allocated(ost, ost->ost_fs->fs_root_blkno)) {
		ocfs2_bitmap_test(ost->ost_dir_inodes, 
				ost->ost_fs->fs_root_blkno, &was_set);
		if (!was_set)
			printf("The root inode exists but isn't a "
			       "directory.\n");
		return;
	}

	if (!prompt(ost, PY, PR_ROOT_DIR_MISSING,
		    "The super block claims that inode %"PRIu64" is the root "
		    "directory but it isn't allocated.  Create a new root "
		    "directory and update the super block?",
		    ost->ost_fs->fs_root_blkno))
		return;

	ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR);
	if (ret) {
		com_err(whoami, ret, "while trying to allocate a new inode "
			"for the root directory\n");
		return;
	}

	ret = ocfs2_init_dir(ost->ost_fs, blkno, blkno);
	if (ret) {
		com_err(whoami, ret, "while trying to expand a new root "
			"directory");
		goto out;
	}

	o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 1);
	o2fsck_icount_set(ost->ost_icount_refs, blkno, 1);
	ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, 
				    ost->ost_fs->fs_root_blkno,
				    ost->ost_fs->fs_root_blkno, 0);
	if (ret) {
		com_err(whoami, ret, "while recording a new root directory");
		goto out;
	}

	old_root = sb->s_root_blkno;
	ost->ost_fs->fs_root_blkno = blkno;
	sb->s_root_blkno = blkno;

	ret = ocfs2_write_primary_super(ost->ost_fs);
	if (ret) {
		com_err(whoami, ret, "while writing the super block with a "
			"new root directory inode");
		ost->ost_fs->fs_root_blkno = old_root;
		sb->s_root_blkno = old_root;
		goto out;
	}

	blkno = 0;

out:
	if (blkno) {
		ret = ocfs2_delete_inode(ost->ost_fs, blkno);
		if (ret) {
			com_err(whoami, ret, "while trying to clean up an "
			        "an allocated inode after linking /lost+found "
				"failed");
		}
	}
}
コード例 #4
0
static errcode_t remove_slots(ocfs2_filesys *fs, int num_slots)
{
	errcode_t ret;
	uint16_t old_num = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
	uint16_t removed_slot = old_num - 1;
	struct tools_progress *prog = NULL;

	ret = remove_slot_check(fs, num_slots);
	if (ret)
		goto bail;

	/* We have seven steps in removing each slot */
	prog = tools_progress_start("Removing slots", "rmslots",
				    (old_num - num_slots) * 7);
	if (!prog) {
		ret = TUNEFS_ET_NO_MEMORY;
		goto bail;
	}

	/* This is cleared up in update_slot_count() if everything works */
	ret = tunefs_set_in_progress(fs, OCFS2_TUNEFS_INPROG_REMOVE_SLOT);
	if (ret)
		goto bail;

	/* we will remove the slots once at a time so that fsck.ocfs2 can work
	 * well and we can continue our work easily in case of any panic.
	 */
	while (removed_slot >= num_slots) {
		/* Link the specified extent alloc file to others. */
		ret = relink_system_alloc(fs, removed_slot, num_slots,
					  EXTENT_ALLOC_SYSTEM_INODE);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* Link the specified inode alloc file to others. */
		ret = relink_system_alloc(fs, removed_slot, num_slots,
					  INODE_ALLOC_SYSTEM_INODE);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* Truncate the orphan dir to release its clusters
		 * to the global bitmap.
		 */
		ret = truncate_orphan_dir(fs, removed_slot);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* empty the content of journal and truncate its clusters. */
		ret = empty_and_truncate_journal(fs, removed_slot);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* Now, we decrease the max_slots first and then remove the
		 * slots for the reason that:
		 *
		 * 1. ocfs2_lock_down_clusters needs to lock all the journal
		 * files. so if we delete the journal entry first and fail
		 * to decrease the max_slots, the whole cluster can't be
		 * locked any more due to the loss of journals.
		 *
		 * 2. Now all the resources except the inodes are freed
		 * so it is safe to decrease the slots first, and if any
		 * panic happens after we decrease the slots, we can ignore
		 * them, and actually if we want to increase the slot in the
		 * future, we can reuse these inodes.
		 */

		/* The slot number is updated in the super block.*/
		OCFS2_RAW_SB(fs->fs_super)->s_max_slots--;
		ret = ocfs2_write_primary_super(fs);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* The extra system dir entries should be removed. */
		ret = remove_slot_entry(fs, removed_slot);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		/* Decrease the i_links_count in system file directory
		 * since the orphan_dir is removed.
		 */
		ret = decrease_link_count(fs, fs->fs_sysdir_blkno);
		if (ret)
			goto bail;
		tools_progress_step(prog, 1);

		removed_slot--;
	}

bail:
	if (prog)
		tools_progress_stop(prog);

	return ret;
}