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.