[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