[Ocfs2-tools-devel] [PATCH 3/3] Ocfs2-tools: Implement new prompt codes of journal for fswreck.

Tao Ma tao.ma at oracle.com
Wed Jul 1 00:56:36 PDT 2009



Tristan Ye wrote:
> We want fswreck to support journal's corruptions as fsck.ocfs2
> has had such kind of prompt codes already.
> 
> Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
> ---
>  fswreck/Makefile            |    3 +-
>  fswreck/corrupt.c           |   12 +++
>  fswreck/include/fsck_type.h |   14 +++-
>  fswreck/include/journal.h   |   30 +++++++
>  fswreck/include/main.h      |    1 +
>  fswreck/journal.c           |  178 +++++++++++++++++++++++++++++++++++++++++++
>  fswreck/main.c              |    8 ++
>  7 files changed, 240 insertions(+), 6 deletions(-)
>  create mode 100644 fswreck/include/journal.h
>  create mode 100644 fswreck/journal.c
> 

<snip>
> diff --git a/fswreck/include/fsck_type.h b/fswreck/include/fsck_type.h
> index c7b9170..df3cbc0 100644
> --- a/fswreck/include/fsck_type.h
> +++ b/fswreck/include/fsck_type.h
> @@ -122,6 +122,10 @@ enum fsck_type
>  	INODE_INLINE_SIZE,
>  	INODE_INLINE_CLUSTERS,
>  	DUPLICATE_CLUSTERS,
> +	JOURNAL_FILE_INVALID,
> +	JOURNAL_UNKNOWN_FEATURE,
> +	JOURNAL_MISS_FEATURE,
> +	JOURNAL_TOO_SMALL,
>  	NUM_FSCK_TYPE
>  };
>  
> @@ -154,7 +158,8 @@ enum fsck_type
>   * Group list error: GROUP_UNEXPECTED_DESC, GROUP_EXPECTED_DESC
>   *
>   * Inode field error: 	INODE_SUBALLOC, INODE_GEN, INODE_GEN_FIX,INODE_BLKNO,
> -			INODE_NZ_DTIME, INODE_SIZE, INODE_CLUSTERS, INODE_COUNT
> + *			INODE_NZ_DTIME, INODE_SIZE, INODE_SPARSE_SIZE,
> + *			INODE_CLUSTERS, INODE_SPARSE_CLUSTERS, INODE_COUNT
this should be in your 2/3 patch I guess?
>   *
>   * Inode link not connected error: INODE_LINK_NOT_CONNECTED 
>   *
> @@ -178,6 +183,8 @@ enum fsck_type
>   *
>   * Special files error: ROOT_NOTDIR, ROOT_DIR_MISSING, LOSTFOUND_MISSING,
>   *			DIR_DOTDOT
> + * Journal file error:	JOURNAL_FILE_INVALID, JOURNAL_UNKNOWN_FEATURE,
> +			JOURNAL_MISS_FEATURE, JOURNAL_TOO_SMALL.
>   * 	
>   * Link file error: LINK_FAST_DATA, LINK_NULLTERM, LINK_SIZE, LINK_BLOCKS
>   *
> @@ -194,9 +201,8 @@ enum fsck_type
>   *
>   * Directory not connected error: DIR_NOT_CONNECTED
>   *
> - * Inline file flag error:	INLINE_DATA_FLAG_INVALID
> - *
> - * Inline file id_count error:  INLINE_DATA_COUNT_INVALID
> + * Inline file:	INLINE_DATA_FLAG_INVALID, INLINE_DATA_COUNT_INVALID,
> + *		INODE_INLINE_SIZE, INODE_INLINE_CLUSTERS
ditto. Should be in 1/3.
>   *
>   */
>  #endif
> diff --git a/fswreck/include/journal.h b/fswreck/include/journal.h
> new file mode 100644
> index 0000000..f948ba1
> --- /dev/null
> +++ b/fswreck/include/journal.h
> @@ -0,0 +1,30 @@
> +/*
> + * journal.h
> + *
> + * Function prototypes, macros, etc. for related 'C' files
> + *
> + * Copyright (C) 2009 Oracle.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public
> + * License along with this program; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 021110-1307, USA.
this comments have been changed. Please use the new one(you can find a 
new version in fs/ocfs2/xattr.c).
> + *
> + */
> +
> +#ifndef __JOURNAL_H
> +#define __JOURNAL_H
> +
> +void mess_up_journal(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum);
> +
> +#endif		/* __JOURNAL_H */
> diff --git a/fswreck/include/main.h b/fswreck/include/main.h
> index 9c3dfe4..daedc0a 100644
> --- a/fswreck/include/main.h
> +++ b/fswreck/include/main.h
> @@ -88,5 +88,6 @@
>  #include "symlink.h"
>  #include "special.h"
>  #include "dir.h"
> +#include "journal.h"
>  
>  #endif		/* __MAIN_H__ */
> diff --git a/fswreck/journal.c b/fswreck/journal.c
> new file mode 100644
> index 0000000..3f2c6d9
> --- /dev/null
> +++ b/fswreck/journal.c
> @@ -0,0 +1,178 @@
> +/*
> + * journal.c
> + *
> + * corruptions for journal file.
> + *
> + * Copyright (C) 2009 Oracle.  All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public
> + * License along with this program; if not, write to the
> + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> + * Boston, MA 021110-1307, USA.
> + *
> + */
> +
> +#include "main.h"
> +
> +extern char *progname;
> +
> +/* This file will corrupt jorunal system file.
> + *
> + * Journal Error: JOURNAL_FILE_INVALID, JOURNAL_UNKNOWN_FEATURE,
> + * JOURNAL_MISS_FEATURE, JOURNAL_TOO_SMALL.
> + *
> + */
> +void mess_up_journal(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum)
> +{
> +	errcode_t ret;
> +	uint64_t j_blkno, jsb_blkno;
> +	uint64_t contig;
> +	uint32_t old_no;
> +	uint16_t max_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
> +	ocfs2_cached_inode *ci = NULL;
> +	char *buf = NULL;
> +	journal_superblock_t *jsb;
> +
> +	uint64_t tmp_j_blkno, tmp_jsb_blkno;
> +	uint64_t tmp_contig;
> +	uint16_t adj_slotnum;
> +	ocfs2_cached_inode *tmp_ci = NULL;
> +	journal_superblock_t *tmp_jsb;
> +	char *tmp_buf = NULL;
> +
> +	ret = ocfs2_malloc_block(fs->fs_io, &buf);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE,
> +					slotnum, &j_blkno);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	ret = ocfs2_read_cached_inode(fs, j_blkno, &ci);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &jsb_blkno, &contig, NULL);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	ret = ocfs2_read_journal_superblock(fs, jsb_blkno, buf);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	jsb = (journal_superblock_t *)buf;
> +
> +	switch (type) {
> +	case JOURNAL_FILE_INVALID:
> +		old_no = htonl(JBD2_MAGIC_NUMBER);
> +		jsb->s_header.h_magic = ~htonl(JBD2_MAGIC_NUMBER);
> +		fprintf(stdout, "JOURNAL_FILE_INVALID: "
> +			"Corrupt journal system inode#%"PRIu64"'s "
> +			"superblock's magic number from %x to %x.\n",
> +			j_blkno, old_no, !htonl(JBD2_MAGIC_NUMBER));
why need to call htonl here? ocfs2_swap_journal_superblock should handle 
this already for your.
> +		break;
> +	case JOURNAL_UNKNOWN_FEATURE:
> +		jsb->s_feature_incompat |= ~JBD2_KNOWN_INCOMPAT_FEATURES;
> +		jsb->s_feature_ro_compat |= ~JBD2_KNOWN_ROCOMPAT_FEATURES;
> +		fprintf(stdout, "JOURNAL_FILE_INVALID: "
> +			"Corrupt journal system inode#%"PRIu64" by "
> +			"adding unsupported features.\n", j_blkno);
the endian problem.
> +		break;
> +	case JOURNAL_MISS_FEATURE:
> +		/* First of all, set all supported features for
> +		 * another journal file if existed, therefore, we
> +		 * easily let the journal file with current slotnum
> +		 * become features-missing when compared to the rest
> +		 * of journal files.
> +		 */
> +		if (max_slots == 1)
> +			adj_slotnum = slotnum;
> +		else
> +			adj_slotnum = (slotnum + 1 > max_slots - 1) ?
> +				       max_slots - 1 : slotnum + 1;
I would guess adj_slotnum should not be equal to slotnum if max_slot > 
1, right?
If yes, here is a bug.
if slotnum == max_slot -1, adj_slotnum  = slotnum.
Can slotnum = max_slot - 1?

> +
> +		ret = ocfs2_malloc_block(fs->fs_io, &tmp_buf);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		ret = ocfs2_lookup_system_inode(fs, JOURNAL_SYSTEM_INODE,
> +						adj_slotnum, &tmp_j_blkno);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		ret = ocfs2_read_cached_inode(fs, tmp_j_blkno, &tmp_ci);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		ret = ocfs2_extent_map_get_blocks(ci, 0, 1, &tmp_jsb_blkno,
> +						  &tmp_contig, NULL);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		ret = ocfs2_read_journal_superblock(fs, tmp_jsb_blkno, tmp_buf);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		tmp_jsb = (journal_superblock_t *)tmp_buf;
> +
> +		tmp_jsb->s_feature_compat |= JBD2_KNOWN_COMPAT_FEATURES;
> +		tmp_jsb->s_feature_incompat |= JBD2_KNOWN_INCOMPAT_FEATURES;
> +		tmp_jsb->s_feature_ro_compat |= JBD2_KNOWN_ROCOMPAT_FEATURES;
> +
> +		ret = ocfs2_write_journal_superblock(fs, tmp_jsb_blkno,
> +						     tmp_buf);
> +		if (ret)
> +			FSWRK_COM_FATAL(progname, ret);
> +
> +		if (tmp_buf)
> +			ocfs2_free(&tmp_buf);
> +		if (tmp_ci)
> +			ocfs2_free_cached_inode(fs, tmp_ci);
> +		/*
> +		 * Clear features bits for journal file with
> +		 * current slot number.
> +		 */
> +		jsb->s_feature_compat &= ~JBD2_KNOWN_COMPAT_FEATURES;
> +		jsb->s_feature_incompat &= ~JBD2_KNOWN_INCOMPAT_FEATURES;
> +		jsb->s_feature_ro_compat &= ~JBD2_KNOWN_ROCOMPAT_FEATURES;
> +		fprintf(stdout, "JOURNAL_FILE_INVALID: "
> +			"Corrupt journal system inode#%"PRIu64" by "
> +			"removing supported features.\n", j_blkno);
For local mode, if max_slots == 1, does your corruption work?
> +		break;
> +	case JOURNAL_TOO_SMALL:
> +		old_no = ci->ci_inode->i_clusters;
> +		ci->ci_inode->i_clusters = 0;
> +		fprintf(stdout, "JOURNAL_FILE_INVALID: "
> +			"Corrupt journal system inode#%"PRIu64"'s "
> +			"i_clusters from %u to zero.\n", j_blkno, old_no);
> +		break;
> +	default:
> +		FSWRK_FATAL("Invalid type[%d]\n", type);
> +	}
> +
> +	ret = ocfs2_write_cached_inode(fs, ci);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
> +
> +	ret = ocfs2_write_journal_superblock(fs, jsb_blkno, buf);
> +	if (ret)
> +		FSWRK_COM_FATAL(progname, ret);
Hey, you really need to write the journal super block befor you write 
the journal file.

Regards,
Tao



More information about the Ocfs2-tools-devel mailing list