[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