Re: extents in e2fsprogs
Andreas Dilger <[email protected]>
| Newsgroups | gmane.comp.file-systems.ext2.devel |
|---|---|
| Message-ID | <[email protected]> |
On Jun 15, 2006 18:50 +0200, Alexandre Ratchov wrote:
> > > @@ -83,10 +84,26 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
> > > + 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...
> >
>
> the EXT2_FEATURE_RO_COMPAT_64BIT flag is wrong;
>
> however, if the file system is using extents then we can create the new
> directory using extents; is it ok?
While this is possible, it definitely isn't desirable. There is a
bug in e2fsck that breaks the walking of directories that are extent
mapped. This is because the htree code is assuming that i_blocks[0]
is directly mapping to the first logical block of the directory, but
of extent-mapped files this is a struct ext3_extent_hdr.
Patch below to do correct logical->physical mapping for the index root
block 0 (though CFS doesn't need this currently, since we don't use
extent-mapped directories anymore):
============================================================================
diff -rup e2fsprogs/e2fsck/pass1.c e2fsprogs-lustre-hg/e2fsck/pass1.c
--- e2fsprogs/e2fsck/pass1.c 2006-02-09 14:08:12.000000000 -0700
+++ e2fsprogs-lustre-hg/e2fsck/pass1.c 2006-06-08 11:52:01.000000000 -0600
@@ -1309,10 +1346,23 @@ clear_extattr:
return 0;
}
+static int htree_blk_iter_cb(ext2_filsys fs EXT2FS_ATTR((unused)),
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
+ blk_t ref_blk EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
+ void *priv_data)
+{
+ blk_t *blk = priv_data;
+
+ *blk = *blocknr;
+
+ return BLOCK_ABORT;
+}
+
/* Returns 1 if bad htree, 0 if OK */
static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
- ext2_ino_t ino EXT2FS_ATTR((unused)),
- struct ext2_inode *inode,
+ ext2_ino_t ino, struct ext2_inode *inode,
char *block_buf)
{
struct ext2_dx_root_info *root;
@@ -1326,7 +1376,8 @@ static int handle_htree(e2fsck_t ctx, st
fix_problem(ctx, PR_1_HTREE_SET, pctx)))
return 1;
- blk = inode->i_block[0];
+ ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE,
+ block_buf, htree_blk_iter_cb, &blk);
if (((blk == 0) ||
(blk < fs->super->s_first_data_block) ||
(blk >= fs->super->s_blocks_count)) &&
Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.