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.
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.