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

tristan.ye tristan.ye at oracle.com
Wed Jul 1 19:25:59 PDT 2009


Tao, 

Thank you for pointing all these out!

On Wed, 2009-07-01 at 15:56 +0800, Tao Ma wrote:
> 
> 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.

Yes, you're right.

> >   *
> >   */
> >  #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).

Ok, i'll change this accordingly.

> > + *
> > + */
> > +
> > +#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.
Good catch, I realized ocfs2_read_journal_superblock() and
ocfs2_write_journal_superblok() have already handled this for us.

> > +		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?

Good catch, it's a typing mistake, it should be

if (max_slots == 1)
	adj_slotnum = slotnum;
else
	adj_slotnum = (slotnum + 1 > max_slots - 1) ?
				slotnum - 1 : slotnum + 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?

Yes, for the case 'max_slots == 1', we may let program quit.

> > +		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.

Good suggestion.


> 
> Regards,
> Tao




More information about the Ocfs2-tools-devel mailing list