[Ocfs2-tools-devel] [PATCH 6/6] fsck.ocfs2: Do slot recovery.

Sunil Mushran sunil.mushran at oracle.com
Tue Sep 16 18:43:29 PDT 2008


comment inlined.

Tao Ma wrote:
> In fsck.ocfs2, add the ability of slot recovery in fsck.ocfs2.
> The whole process will work like this:
> 1. Replay journal for all slots.
> 2. Apply the truncate log and local alloc bits. Look for inconsistency.
>    If any inconsistency, force a full fsck.
> 3. If non-force fsck, replay orphan dirs. If error, force a full fsck.
>    If not, go to step 6.
> 4. If force fsck, fsck the entire fs.
> 5. Remove the entries in orphan dirs.
> 6. Reset the slot map and the journal dirty flags.
>
> Signed-off-by: Tao Ma <tao.ma at oracle.com>
> ---
>  fsck.ocfs2/fsck.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 72 insertions(+), 1 deletions(-)
>
> diff --git a/fsck.ocfs2/fsck.c b/fsck.ocfs2/fsck.c
> index ed275a3..b27c195 100644
> --- a/fsck.ocfs2/fsck.c
> +++ b/fsck.ocfs2/fsck.c
> @@ -66,6 +66,7 @@
>  #include "pass4.h"
>  #include "problem.h"
>  #include "util.h"
> +#include "slot_recovery.h"
>  
>  int verbose = 0;
>  
> @@ -495,6 +496,43 @@ out:
>  	return ret;
>  }
>  
> +/*
> + * Do the slot recovery, replay truncate log, local aloc and orphan dir.
> + * If there is any error, a force check is enabled.
> + */
> +static errcode_t o2fsck_slot_recovery(o2fsck_state *ost)
> +{
> +	errcode_t ret = 0;
> +
> +	if (!(ost->ost_fs->fs_flags & OCFS2_FLAG_RW)) {
> +		printf("** Skipping slot recovery because -n was "
> +		       "given. **\n");
> +		goto out;
> +	}
> +
> +	ret = o2fsck_replay_truncate_logs(ost->ost_fs);
> +	if (ret)
> +		goto out;
> +
> +	ret = o2fsck_replay_local_allocs(ost->ost_fs);
> +	if (ret)
> +		goto out;
> +

In the kernel, we replay local alloc before truncate log. Can
we keep the same sequence here too. Not suggesting this is
wrong... just trying to keep the two consistent as far as possible.

> +	/*
> +	 * If the user want a force-check, orphan_dir will be
> +	 * replayed after the full check.
> +	 */
> +	if (!ost->ost_force) {
> +		ret = replay_orphan_dir(ost, 1);
> +		if (ret)
> +			com_err(whoami, ret, "while trying to replay the orphan"
> +				" directory");
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static errcode_t recover_backup_super(o2fsck_state *ost,
>  				      char* device, int sb_num)
>  {
> @@ -612,6 +650,7 @@ int main(int argc, char **argv)
>  	int c, open_flags = OCFS2_FLAG_RW | OCFS2_FLAG_STRICT_COMPAT_CHECK;
>  	int sb_num = 0;
>  	int fsck_mask = FSCK_OK;
> +	int slot_recover_err = 0;
>  	errcode_t ret;
>  
>  	memset(ost, 0, sizeof(o2fsck_state));
> @@ -823,9 +862,17 @@ int main(int argc, char **argv)
>  		goto unlock;
>  	}
>  
> +	ret = o2fsck_slot_recovery(ost);
> +	if (ret) {
> +		printf("fsck encountered errors while replaying the slot "
> +		       "recovery, force-check enabled.\n");
> +		slot_recover_err = 1;
> +		ost->ost_force = 1;
> +	}
> +
>  	if (fs_is_clean(ost, filename)) {
>  		fsck_mask = FSCK_OK;
> -		goto unlock;
> +		goto clear_dirty_flag;
>  	}
>  
>  #if 0
> @@ -874,15 +921,39 @@ done:
>  	if (ret)
>  		fsck_mask |= FSCK_ERROR;
>  	else {
> +		fsck_mask = FSCK_OK;
>  		ost->ost_saw_error = 0;
>  		printf("All passes succeeded.\n");
>  	}
>  
> +clear_dirty_flag:
>  	if (ost->ost_fs->fs_flags & OCFS2_FLAG_RW) {
>  		ret = write_out_superblock(ost);
>  		if (ret)
>  			com_err(whoami, ret, "while writing back the "
>  				"superblock(s)");
> +		if (fsck_mask == FSCK_OK) {
> +			if (slot_recover_err) {
> +			    ret = o2fsck_slot_recovery(ost);
> +				if (ret) {
> +					com_err(whoami, ret, "while doing slot "
> +						"recovery.");
> +					goto unlock;
> +				}
> +			}
> +
> +			ret = o2fsck_clear_journal_flags(ost);
> +			if (ret) {
> +				com_err(whoami, ret, "while clear dirty "
> +					"journal flag.");
> +				goto unlock;
> +			}
> +
> +			ret = ocfs2_format_slot_map(ost->ost_fs);
> +			if (ret)
> +				com_err(whoami, ret, "while format slot "
> +					"map.");
> +		}
>  	}
>  
>  unlock:




More information about the Ocfs2-tools-devel mailing list