[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