[Ocfs2-tools-devel] [PATCH 2/3] Ocfs2-tools: Implement new prompt codes of sparse file for fswreck.
Joel Becker
Joel.Becker at oracle.com
Thu Jul 2 15:12:46 PDT 2009
On Thu, Jul 02, 2009 at 02:52:38PM +0800, Tristan Ye wrote:
> Adding new corruptions of sparse file for fswreck after fsck.ocfs2
> supported new separated prompt codes.
<snip>
> diff --git a/fswreck/inode.c b/fswreck/inode.c
> index a66ff3f..425222c 100644
> --- a/fswreck/inode.c
> +++ b/fswreck/inode.c
> @@ -47,6 +47,18 @@ static void damage_inode(ocfs2_filesys *fs, uint64_t blkno,
> errcode_t ret;
> char *buf = NULL;
> struct ocfs2_dinode *di;
> + struct ocfs2_dinode *sb_di;
> + char *sb_blk;
> +
> + if ((type == INODE_SPARSE_SIZE) || (type == INODE_SPARSE_CLUSTERS)) {
> +
> + sb_blk = (char *)fs->fs_super;
> + sb_di = (struct ocfs2_dinode *)sb_blk;
> + if (!(sb_di->id2.i_super.s_feature_incompat &
> + OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC))
Just use:
if (!ocfs2_sparse_alloc(OCFS2_RAW_SB(fs->fs_super))
> @@ -103,12 +115,25 @@ static void damage_inode(ocfs2_filesys *fs, uint64_t blkno,
> blkno, di->i_size, (di->i_size + 100));
> di->i_size += 100;
> break;
> + case INODE_SPARSE_SIZE:
> + fprintf(stdout, "INODE_SPARSE_SIZE: "
> + "Corrupt inode#%"PRIu64", change i_size"
> + " from %"PRIu64" to %"PRIu64"\n",
> + blkno, di->i_size, (di->i_size + 100));
> + di->i_size += fs->fs_clustersize;
> + break;
This isn't a corruption. A sparse file can have i_size way past
the last actual allocation. The INODE_SPARSE_SIZE check sees if there
is an actual cluster *past* i_size. So this corruption should extend
the file with a real cluster, then shrink i_size down below that
cluster.
I'd say create the sparse file in mess_up_inode_field like this:
> @@ -130,14 +155,13 @@ static void damage_inode(ocfs2_filesys *fs, uint64_t blkno,
>
> void mess_up_inode_field(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno)
> {
> - int i;
> errcode_t ret;
> uint64_t tmpblkno;
> uint32_t clusters = 10;
>
> create_file(fs, blkno, &tmpblkno);
>
Right here, if INODE_SPARSE_SIZE, call a function that verifies
ocfs2_sparse_alloc(), then reads the inode, changes i_size to equal two
clusters, then writes the inode out. Now you have a file with i_size of
2 * fs_clustersize and i_clusters of 0. That's a perfectly valid sparse
file.
> - if (type == INODE_CLUSTERS) {
> + if ((type == INODE_CLUSTERS) || (type == INODE_SPARSE_CLUSTERS)) {
> ret = ocfs2_extend_allocation(fs, tmpblkno, clusters);
> if (ret)
> FSWRK_COM_FATAL(progname, ret);
Here you add INODE_SPARSE_SIZE to the list of types that extend
the allocation. So when this is done, your sparse file has an i_size of
12 * fs_clustersize and i_clusters of 10.
Then, in damage_inode, the INODE_SPARSE_SIZE code sets i_size to
fs_clustersize. Right in the middle of the hole. When fsck runs, it
should notice that the extent tree reaches out to 12 * fs_clustersize
and ask to set i_size to 12 * fs_clustersize.
Joel
--
Life's Little Instruction Book #510
"Count your blessings."
Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127
More information about the Ocfs2-tools-devel
mailing list