Re: extents in e2fsprogs

Andreas Dilger <[email protected]>
Newsgroups gmane.comp.file-systems.ext2.devel
Message-ID <[email protected]>
On Jun 14, 2006  18:19 +0200, Alexandre Ratchov wrote:
> +static int block_iterate_extents(struct ext3_extent_header *eh, ext2_filsys fs,
> +				 struct block_context *ctx)
> +{
> +        if(eh->eh_depth == 0) {
> +                show_extent(eh);
> +                ex = EXT_FIRST_EXTENT(eh);
> +                for (i = 0; i < eh->eh_entries; i++, ex++) {
> +                        for(j=0; j< ex->ee_len; j++) {
> +                                block_address = ex->ee_start + j;
> +				ret = (*ctx->func)(ctx->fs, &block_address,
> +						   (ex->ee_block + j), 0,
> +						   i, ctx->priv_data);

One of the CFS fixes is to handle partial iteration correctly:

                                if (ret & BLOCK_ABORT)
					return ret;

> +                        }
> +                }
> +        } else {
> +		show_index(eh);
> +                ret = ext2fs_get_mem(fs->blocksize, &block_buf);
> +                if (ret)
> +                        return ret;
> +                ix = EXT_FIRST_INDEX(eh);
> +                for (i = 0; i < eh->eh_entries; i++, ix++) {
> +			block_address = ix->ei_leaf;

Don't iterate over index blocks:

                        if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
                            !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {

> +				ret = (*ctx->func)(ctx->fs, &block_address,
> +					   BLOCK_COUNT_IND, 0, i, ctx->priv_data);
> +				if (ret & BLOCK_ABORT) {
> +					ext2fs_free_mem(&block_buf);
> +					return ret;
> +				}
			}

> @@ -83,10 +84,26 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
>  	inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
>  	inode.i_uid = inode.i_gid = 0;
>  	inode.i_blocks = fs->blocksize / 512;
> -	inode.i_block[0] = blk;
>  	inode.i_links_count = 2;
>  	inode.i_ctime = inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(NULL);
>  	inode.i_size = fs->blocksize;
> +	if (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT) {
> +		struct ext3_extent_header *eh = (struct ext3_extent_header *)inode.i_block;
> +		struct ext3_extent *ex = EXT_FIRST_EXTENT(eh);
> +
> +		 eh->eh_magic = EXT3_EXT_MAGIC;
> +		 eh->eh_depth = 0;
> +		 eh->eh_entries = 1;
> +		 eh->eh_max = (sizeof(inode.i_block) - sizeof(struct ext3_extent_header))
> +			 / sizeof(struct ext3_extent);
> +		 ex->ee_block = 0;
> +		 ex->ee_start = blk;
> +		 ex->ee_len = 1;
> +
> +		 inode.i_flags = EXT3_EXTENTS_FL;
> +	} else {
> +		inode.i_block[0] = blk;
> +	}

This relates to 64-bit support...

> Index: e2fsprogs-1.39/e2fsck/pass1.c
> ===================================================================
> --- e2fsprogs-1.39.orig/e2fsck/pass1.c	2006-05-31 15:44:49.000000000 +0200
> +++ e2fsprogs-1.39/e2fsck/pass1.c	2006-06-14 13:25:47.000000000 +0200
> @@ -806,21 +806,30 @@ void e2fsck_pass1(e2fsck_t ctx)
>  			ctx->fs_sockets_count++;
>  		} else
>  			mark_inode_bad(ctx, ino);
> -		if (inode->i_block[EXT2_IND_BLOCK])
> -			ctx->fs_ind_count++;
> -		if (inode->i_block[EXT2_DIND_BLOCK])
> -			ctx->fs_dind_count++;
> -		if (inode->i_block[EXT2_TIND_BLOCK])
> -			ctx->fs_tind_count++;
> -		if (inode->i_block[EXT2_IND_BLOCK] ||
> -		    inode->i_block[EXT2_DIND_BLOCK] ||
> -		    inode->i_block[EXT2_TIND_BLOCK] ||
> -		    inode->i_file_acl) {
> +		if (fs->super->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_64BIT) {
> +		    if (inode->i_flags & EXT3_EXTENTS_FL) {
>  			inodes_to_process[process_inode_count].ino = ino;
>  			inodes_to_process[process_inode_count].inode = *inode;
>  			process_inode_count++;
> +		    } else
> +			    mark_inode_bad(ctx, ino);

Also related to 64-bit support...

> +		} else {
> +			if (inode->i_block[EXT2_IND_BLOCK])
> +				ctx->fs_ind_count++;
> +			if (inode->i_block[EXT2_DIND_BLOCK])
> +				ctx->fs_dind_count++;
> +			if (inode->i_block[EXT2_TIND_BLOCK])
> +				ctx->fs_tind_count++;

These stats could use the ext3_extent_hdr depth to account similar
stats for extents.

> +			if (inode->i_block[EXT2_IND_BLOCK] ||
> +			    inode->i_block[EXT2_DIND_BLOCK] ||
> +			    inode->i_block[EXT2_TIND_BLOCK] ||
> +			    inode->i_file_acl) {
> +				inodes_to_process[process_inode_count].ino = ino;
> +				inodes_to_process[process_inode_count].inode = *inode;
> +				process_inode_count++;

This probably needs to also check the extent_hdr depth for processing...



Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.