public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
* e2fsck (git) on ext4: unsupported feature(s): huge_file
@ 2008-04-08 17:58 supersud501
  2008-04-08 18:36 ` Eric Sandeen
  2008-04-08 18:37 ` Eric Sandeen
  0 siblings, 2 replies; 23+ messages in thread
From: supersud501 @ 2008-04-08 17:58 UTC (permalink / raw)
  To: linux-ext4

i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
2.6.25-rc8), extents enabled:

e2fsck 1.40.8 (13-Mar-2008)
/dev/loop2 has unsupported feature(s): huge_file
e2fsck: Get a newer version of e2fsck!

just updated to the git-version of e2fsprogs, same error. i know e2fsck 
worked once with the drive (~2 months ago).

what can i do?

regards,
supersud501


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 17:58 e2fsck (git) on ext4: unsupported feature(s): huge_file supersud501
@ 2008-04-08 18:36 ` Eric Sandeen
  2008-04-08 19:45   ` supersud501
  2008-04-09 14:45   ` Calvin Walton
  2008-04-08 18:37 ` Eric Sandeen
  1 sibling, 2 replies; 23+ messages in thread
From: Eric Sandeen @ 2008-04-08 18:36 UTC (permalink / raw)
  To: supersud501; +Cc: linux-ext4

supersud501 wrote:
> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
> 2.6.25-rc8), extents enabled:
> 
> e2fsck 1.40.8 (13-Mar-2008)
> /dev/loop2 has unsupported feature(s): huge_file
> e2fsck: Get a newer version of e2fsck!
> 
> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
> worked once with the drive (~2 months ago).
> 
> what can i do?

Do you in fact have any very large files on the disk?

-Eric

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 17:58 e2fsck (git) on ext4: unsupported feature(s): huge_file supersud501
  2008-04-08 18:36 ` Eric Sandeen
@ 2008-04-08 18:37 ` Eric Sandeen
  2008-04-08 22:40   ` Christian Kujau
  1 sibling, 1 reply; 23+ messages in thread
From: Eric Sandeen @ 2008-04-08 18:37 UTC (permalink / raw)
  To: supersud501; +Cc: linux-ext4

supersud501 wrote:
> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
> 2.6.25-rc8), extents enabled:
> 
> e2fsck 1.40.8 (13-Mar-2008)
> /dev/loop2 has unsupported feature(s): huge_file
> e2fsck: Get a newer version of e2fsck!
> 
> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
> worked once with the drive (~2 months ago).
> 
> what can i do?

Oh, and for what it's worth, fsck support for ext4 is incomplete, even
in git.  That accounts for lots of the "dev" part in "ext4dev."

-Eric

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 18:36 ` Eric Sandeen
@ 2008-04-08 19:45   ` supersud501
  2008-04-08 21:00     ` Theodore Tso
  2008-04-09 12:54     ` e2fsck (git) on ext4: unsupported feature(s): huge_file Eric Sandeen
  2008-04-09 14:45   ` Calvin Walton
  1 sibling, 2 replies; 23+ messages in thread
From: supersud501 @ 2008-04-08 19:45 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-ext4

Eric Sandeen wrote:
> supersud501 wrote:
>> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
>> 2.6.25-rc8), extents enabled:
>>
>> e2fsck 1.40.8 (13-Mar-2008)
>> /dev/loop2 has unsupported feature(s): huge_file
>> e2fsck: Get a newer version of e2fsck!
>>
>> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
>> worked once with the drive (~2 months ago).
>>
>> what can i do?
> 
> Do you in fact have any very large files on the disk?
> 

yeah, i have (> 5.5gb).

i know it worked a few months (1-2) ago, even with extents enabled. at 
this time there where those large files too.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 19:45   ` supersud501
@ 2008-04-08 21:00     ` Theodore Tso
  2008-04-09  9:15       ` supersud501
  2008-04-09 15:50       ` [E2FSPROGS, PATCH] Add support for the HUGE_FILE feature Theodore Ts'o
  2008-04-09 12:54     ` e2fsck (git) on ext4: unsupported feature(s): huge_file Eric Sandeen
  1 sibling, 2 replies; 23+ messages in thread
From: Theodore Tso @ 2008-04-08 21:00 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

On Tue, Apr 08, 2008 at 09:45:08PM +0200, supersud501 wrote:
> Eric Sandeen wrote:
>> supersud501 wrote:
>>> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
>>> 2.6.25-rc8), extents enabled:
>>>
>>> e2fsck 1.40.8 (13-Mar-2008)
>>> /dev/loop2 has unsupported feature(s): huge_file
>>> e2fsck: Get a newer version of e2fsck!
>>>
>>> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
>>> worked once with the drive (~2 months ago).
>>>
>>> what can i do?
>> Do you in fact have any very large files on the disk?
>
> yeah, i have (> 5.5gb).
>
> i know it worked a few months (1-2) ago, even with extents enabled. at this 
> time there where those large files too.

The old 1.39-interim-tyt3 e2fsprogs patch claimed it supported huge
files, but it didn't, actually.  It lied.  :-(

(So if you needed to repair a filesystem, e2fsck would screw up the
i_blocks field.)

I'm working on fixing that.

					- Ted

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 18:37 ` Eric Sandeen
@ 2008-04-08 22:40   ` Christian Kujau
  0 siblings, 0 replies; 23+ messages in thread
From: Christian Kujau @ 2008-04-08 22:40 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: supersud501, linux-ext4

On Tue, 8 Apr 2008, Eric Sandeen wrote:
> Oh, and for what it's worth, fsck support for ext4 is incomplete, even
> in git.

"Incomplete", but usable I may add. I've had a few (I/O related) crashes 
and ext4 told me that running e2fsck was recommended. I did several times 
and it went ok.

> That accounts for lots of the "dev" part in "ext4dev."

Yeah, I won't argue with that statement :)

my 2 cents...
C.
-- 
BOFH excuse #24:

network packets travelling uphill (use a carrier pigeon)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 21:00     ` Theodore Tso
@ 2008-04-09  9:15       ` supersud501
  2008-04-09 16:11         ` Theodore Tso
  2008-04-09 15:50       ` [E2FSPROGS, PATCH] Add support for the HUGE_FILE feature Theodore Ts'o
  1 sibling, 1 reply; 23+ messages in thread
From: supersud501 @ 2008-04-09  9:15 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:
> On Tue, Apr 08, 2008 at 09:45:08PM +0200, supersud501 wrote:
>> Eric Sandeen wrote:
>>> supersud501 wrote:
>>>> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
>>>> 2.6.25-rc8), extents enabled:
>>>>
>>>> e2fsck 1.40.8 (13-Mar-2008)
>>>> /dev/loop2 has unsupported feature(s): huge_file
>>>> e2fsck: Get a newer version of e2fsck!
>>>>
>>>> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
>>>> worked once with the drive (~2 months ago).
>>>>
>>>> what can i do?
>>> Do you in fact have any very large files on the disk?
>> yeah, i have (> 5.5gb).
>>
>> i know it worked a few months (1-2) ago, even with extents enabled. at this 
>> time there where those large files too.
> 
> The old 1.39-interim-tyt3 e2fsprogs patch claimed it supported huge
> files, but it didn't, actually.  It lied.  :-(
> 
> (So if you needed to repair a filesystem, e2fsck would screw up the
> i_blocks field.)
> 
> I'm working on fixing that.
> 

ah ok, so i know what's up - seems i've to wait until fixing it. just 
wanted to do it, because syslog said "maximum mount time reached, 
running is recommended". so no need to hurry ;)

regards.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 19:45   ` supersud501
  2008-04-08 21:00     ` Theodore Tso
@ 2008-04-09 12:54     ` Eric Sandeen
  1 sibling, 0 replies; 23+ messages in thread
From: Eric Sandeen @ 2008-04-09 12:54 UTC (permalink / raw)
  To: supersud501; +Cc: linux-ext4

supersud501 wrote:
> Eric Sandeen wrote:
>> supersud501 wrote:
>>> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
>>> 2.6.25-rc8), extents enabled:
>>>
>>> e2fsck 1.40.8 (13-Mar-2008)
>>> /dev/loop2 has unsupported feature(s): huge_file
>>> e2fsck: Get a newer version of e2fsck!
>>>
>>> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
>>> worked once with the drive (~2 months ago).
>>>
>>> what can i do?
>> Do you in fact have any very large files on the disk?
>>
> 
> yeah, i have (> 5.5gb).
> 
> i know it worked a few months (1-2) ago, even with extents enabled. at 
> this time there where those large files too.

For what it's worth, I don't think 5.5gb should have tripped the
huge_file flag.  So I wonder how this got set on your fs.

-Eric

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-08 18:36 ` Eric Sandeen
  2008-04-08 19:45   ` supersud501
@ 2008-04-09 14:45   ` Calvin Walton
  2008-04-09 14:52     ` supersud501
  1 sibling, 1 reply; 23+ messages in thread
From: Calvin Walton @ 2008-04-09 14:45 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: supersud501, linux-ext4

On Tue, 2008-04-08 at 13:36 -0500, Eric Sandeen wrote:
> supersud501 wrote:
> > i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
> > 2.6.25-rc8), extents enabled:
> > 
> > e2fsck 1.40.8 (13-Mar-2008)
> > /dev/loop2 has unsupported feature(s): huge_file
> > e2fsck: Get a newer version of e2fsck!
> > 
> > just updated to the git-version of e2fsprogs, same error. i know e2fsck 
> > worked once with the drive (~2 months ago).
> > 
> > what can i do?
> 
> Do you in fact have any very large files on the disk?

I'm just curious - if I know for sure that I don't have any huge files
on my disk, would I be able to do something like use debugfs to simply
clear the flag?

-- 
Calvin Walton <calvin.walton@gmail.com>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 14:45   ` Calvin Walton
@ 2008-04-09 14:52     ` supersud501
  2008-04-09 16:09       ` Eric Sandeen
  0 siblings, 1 reply; 23+ messages in thread
From: supersud501 @ 2008-04-09 14:52 UTC (permalink / raw)
  To: Calvin Walton; +Cc: Eric Sandeen, linux-ext4

Calvin Walton wrote:
> On Tue, 2008-04-08 at 13:36 -0500, Eric Sandeen wrote:
>> supersud501 wrote:
>>> i get this when trying to run e2fsck on my ext4dev filesystem (kernel 
>>> 2.6.25-rc8), extents enabled:
>>>
>>> e2fsck 1.40.8 (13-Mar-2008)
>>> /dev/loop2 has unsupported feature(s): huge_file
>>> e2fsck: Get a newer version of e2fsck!
>>>
>>> just updated to the git-version of e2fsprogs, same error. i know e2fsck 
>>> worked once with the drive (~2 months ago).
>>>
>>> what can i do?
>> Do you in fact have any very large files on the disk?
> 
> I'm just curious - if I know for sure that I don't have any huge files
> on my disk, would I be able to do something like use debugfs to simply
> clear the flag?
> 

interests mee, too. and how are "huge files" defined? thought they are 
 >4gb files?


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [E2FSPROGS, PATCH] Add support for the HUGE_FILE feature
  2008-04-08 21:00     ` Theodore Tso
  2008-04-09  9:15       ` supersud501
@ 2008-04-09 15:50       ` Theodore Ts'o
  1 sibling, 0 replies; 23+ messages in thread
From: Theodore Ts'o @ 2008-04-09 15:50 UTC (permalink / raw)
  To: linux-ext4; +Cc: Theodore Ts'o

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 e2fsck/emptydir.c      |    3 +-
 e2fsck/message.c       |    7 ++++-
 e2fsck/pass1.c         |   12 ++++++-
 e2fsck/pass2.c         |    2 +-
 e2fsck/pass3.c         |    6 ++--
 e2fsck/rehash.c        |    2 +-
 e2fsck/super.c         |    3 +-
 lib/e2p/pf.c           |    1 +
 lib/ext2fs/Makefile.in |    2 +
 lib/ext2fs/bb_inode.c  |    2 +-
 lib/ext2fs/bmap.c      |    2 +-
 lib/ext2fs/expanddir.c |    2 +-
 lib/ext2fs/ext2_fs.h   |    1 +
 lib/ext2fs/ext2fs.h    |   14 ++++++--
 lib/ext2fs/i_block.c   |   76 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ext2fs/mkdir.c     |    2 +-
 lib/ext2fs/mkjournal.c |    2 +-
 lib/ext2fs/read_bb.c   |   11 ++++--
 lib/ext2fs/res_gdt.c   |    8 ++---
 misc/dumpe2fs.c        |    7 ++++-
 resize/resize2fs.c     |    2 +-
 21 files changed, 135 insertions(+), 32 deletions(-)
 create mode 100644 lib/ext2fs/i_block.c

diff --git a/e2fsck/emptydir.c b/e2fsck/emptydir.c
index 5dbf021..6baab76 100644
--- a/e2fsck/emptydir.c
+++ b/e2fsck/emptydir.c
@@ -168,8 +168,7 @@ static int fix_directory(ext2_filsys fs,
 
 	if (edi->freed_blocks) {
 		edi->inode.i_size -= edi->freed_blocks * fs->blocksize;
-		edi->inode.i_blocks -= edi->freed_blocks *
-			(fs->blocksize / 512);
+		ext2fs_iblk_add_blocks(fs, &edi->inode, edi->freed_blocks);
 		retval = ext2fs_write_inode(fs, db->ino, &edi->inode);
 		if (retval)
 			return 0;
diff --git a/e2fsck/message.c b/e2fsck/message.c
index 8a3705e..184e824 100644
--- a/e2fsck/message.c
+++ b/e2fsck/message.c
@@ -275,7 +275,12 @@ static _INLINE_ void expand_inode_expression(char ch,
 		printf("%u", large_inode->i_extra_isize);
 		break;
 	case 'b':
-		printf("%u", inode->i_blocks);
+		if (inode->i_flags & EXT4_HUGE_FILE_FL)
+			printf("%llu", inode->i_blocks +
+			       (((long long) inode->osd2.linux2.l_i_blocks_hi) 
+				<< 32));
+		else
+			printf("%u", inode->i_blocks);
 		break;
 	case 'l':
 		printf("%d", inode->i_links_count);
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index b85f04f..18cb916 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1847,7 +1847,10 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		}
 	}
 
-	pb.num_blocks *= (fs->blocksize / 512);
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+	    (inode->i_flags & EXT4_HUGE_FILE_FL))
+		pb.num_blocks *= (fs->blocksize / 512);
 #if 0
 	printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
 	       ino, inode->i_size, pb.last_block, inode->i_blocks,
@@ -1891,10 +1894,15 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	if (LINUX_S_ISREG(inode->i_mode) &&
 	    (inode->i_size_high || inode->i_size & 0x80000000UL))
 		ctx->large_files++;
-	if (pb.num_blocks != inode->i_blocks) {
+	if ((pb.num_blocks != inode->i_blocks) ||
+	    ((fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+	     (inode->i_flags & EXT4_HUGE_FILE_FL) &&
+	     (inode->osd2.linux2.l_i_blocks_hi != 0))) {
 		pctx->num = pb.num_blocks;
 		if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
 			inode->i_blocks = pb.num_blocks;
+			inode->osd2.linux2.l_i_blocks_hi = 0;
 			dirty_inode++;
 		}
 		pctx->num = 0;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 906662d..7aa693b 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1429,7 +1429,7 @@ static int allocate_dir_block(e2fsck_t ctx,
 	 * Update the inode block count
 	 */
 	e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
-	inode.i_blocks += fs->blocksize / 512;
+	ext2fs_iblk_add_blocks(fs, &inode, 1);
 	if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
 		inode.i_size = (db->blockcnt+1) * fs->blocksize;
 	e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 867cbf8..4ef1446 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -227,7 +227,7 @@ static void check_root(e2fsck_t ctx)
 	inode.i_size = fs->blocksize;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 	inode.i_links_count = 2;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	inode.i_block[0] = blk;
 
 	/*
@@ -472,7 +472,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
 	inode.i_size = fs->blocksize;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 	inode.i_links_count = 2;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	inode.i_block[0] = blk;
 
 	/*
@@ -803,7 +803,7 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
 		return retval;
 	
 	inode.i_size = (es.last_block + 1) * fs->blocksize;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 
 	e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
 
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index a1f75ef..e75774a 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -668,7 +668,7 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
 	else
 		inode.i_flags |= EXT2_INDEX_FL;
 	inode.i_size = outdir->num * fs->blocksize;
-	inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
+	ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
 	e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
 
 	return 0;
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 87a0d78..b8a1df7 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -195,8 +195,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
 	e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
 
 	if (pb.truncated_blocks)
-		inode->i_blocks -= pb.truncated_blocks *
-			(fs->blocksize / 512);
+		ext2fs_iblk_sub_blocks(fs, inode, pb.truncated_blocks);
 
 	if (inode->i_file_acl) {
 		retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
diff --git a/lib/e2p/pf.c b/lib/e2p/pf.c
index 3e9a7cd..05a961a 100644
--- a/lib/e2p/pf.c
+++ b/lib/e2p/pf.c
@@ -45,6 +45,7 @@ static struct flags_name flags_array[] = {
 	{ EXT2_NOTAIL_FL, "t", "No_Tailmerging" },
 	{ EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
 	{ EXT4_EXTENTS_FL, "e", "Extents" },
+	{ EXT4_HUGE_FILE_FL, "h", "Huge_file" },
 	{ 0, NULL, NULL }
 };
 
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 2766493..677e2d6 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -47,6 +47,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
 	get_pathname.o \
 	getsize.o \
 	getsectsize.o \
+	i_block.o \
 	icount.o \
 	ind_block.o \
 	initialize.o \
@@ -106,6 +107,7 @@ SRCS= ext2_err.c \
 	$(srcdir)/get_pathname.c \
 	$(srcdir)/getsize.c \
 	$(srcdir)/getsectsize.c \
+	$(srcdir)/i_block.c \
 	$(srcdir)/icount.c \
 	$(srcdir)/ind_block.c \
 	$(srcdir)/initialize.c \
diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c
index 1f5b4e8..dbda79f 100644
--- a/lib/ext2fs/bb_inode.c
+++ b/lib/ext2fs/bb_inode.c
@@ -127,7 +127,7 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
 	inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0);
 	if (!inode.i_ctime)
 		inode.i_ctime = fs->now ? fs->now : time(0);
-	inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
+	ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
 	inode.i_size = rec.bad_block_count * fs->blocksize;
 
 	retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
diff --git a/lib/ext2fs/bmap.c b/lib/ext2fs/bmap.c
index 5fe0986..ceb352e 100644
--- a/lib/ext2fs/bmap.c
+++ b/lib/ext2fs/bmap.c
@@ -297,7 +297,7 @@ done:
 	if (handle)
 		ext2fs_extent_free(handle);
 	if ((retval == 0) && (blocks_alloc || inode_dirty)) {
-		inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
+		ext2fs_iblk_add_blocks(fs, inode, blocks_alloc);
 		retval = ext2fs_write_inode(fs, ino, inode);
 	}
 	return retval;
diff --git a/lib/ext2fs/expanddir.c b/lib/ext2fs/expanddir.c
index 10a5149..c124d3e 100644
--- a/lib/ext2fs/expanddir.c
+++ b/lib/ext2fs/expanddir.c
@@ -116,7 +116,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
 		return retval;
 	
 	inode.i_size += fs->blocksize;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 
 	retval = ext2fs_write_inode(fs, dir, &inode);
 	if (retval)
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 444211d..ad42cf8 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -271,6 +271,7 @@ struct ext2_dx_countlimit {
 #define EXT2_NOTAIL_FL			0x00008000 /* file tail should not be merged */
 #define EXT2_DIRSYNC_FL 		0x00010000 /* Synchronous directory modifications */
 #define EXT2_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
+#define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
 #define EXT4_EXTENTS_FL 		0x00080000 /* Inode uses extents */
 #define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
 
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 1a7cb86..e5988cd 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -516,6 +516,7 @@ typedef struct ext2_icount *ext2_icount_t;
 					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
 					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
 					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
@@ -524,10 +525,8 @@ typedef struct ext2_icount *ext2_icount_t;
  * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
  * to ext2fs_openfs()
  */
-#define EXT2_LIB_SOFTSUPP_INCOMPAT	(EXT3_FEATURE_INCOMPAT_EXTENTS)
-#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
-					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
-					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+#define EXT2_LIB_SOFTSUPP_INCOMPAT	(0)
+#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
 
 /*
  * function prototypes
@@ -899,6 +898,13 @@ extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
 /* getsectsize.c */
 errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
 
+/* i_block.c */
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b);
+
 /* imager.c */
 extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
 extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
diff --git a/lib/ext2fs/i_block.c b/lib/ext2fs/i_block.c
new file mode 100644
index 0000000..90e2a2b
--- /dev/null
+++ b/lib/ext2fs/i_block.c
@@ -0,0 +1,76 @@
+/*
+ * i_block.c --- Manage the i_block field for i_blocks
+ *
+ * Copyright (C) 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ * 
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <string.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b;
+
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		b = inode->i_blocks + 
+			(((long long) inode->osd2.linux2.l_i_blocks_hi) << 32);
+		b += num_blocks;
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks += (fs->blocksize / 512) * num_blocks;
+	return 0;
+}
+
+
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b;
+
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		b = inode->i_blocks + 
+			(((long long) inode->osd2.linux2.l_i_blocks_hi) << 32);
+		b -= num_blocks;
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks -= (fs->blocksize / 512) * num_blocks;
+	return 0;
+}
+
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)
+{
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks = (fs->blocksize / 512) * b;
+	return 0;
+}
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index 45e6820..34242df 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -82,7 +82,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	memset(&inode, 0, sizeof(struct ext2_inode));
 	inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
 	inode.i_uid = inode.i_gid = 0;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	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);
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
index 61d10a6..23cc60c 100644
--- a/lib/ext2fs/mkjournal.c
+++ b/lib/ext2fs/mkjournal.c
@@ -228,7 +228,7 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
 		goto errout;
 
  	inode.i_size += fs->blocksize * size;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 	inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
 	inode.i_links_count = 1;
 	inode.i_mode = LINUX_S_IFREG | 0600;
diff --git a/lib/ext2fs/read_bb.c b/lib/ext2fs/read_bb.c
index ff7e292..5a9aede 100644
--- a/lib/ext2fs/read_bb.c
+++ b/lib/ext2fs/read_bb.c
@@ -74,10 +74,13 @@ errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
 		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
 		if (retval)
 			return retval;
-		if (inode.i_blocks < 500)
-			numblocks = (inode.i_blocks /
-				     (fs->blocksize / 512)) + 20;
-		else
+		numblocks = inode.i_blocks;
+		if ((fs->super->s_feature_ro_compat &
+		     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+		    (inode.i_flags & EXT4_HUGE_FILE_FL))
+			numblocks = numblocks / (fs->blocksize / 512);
+		numblocks += 20;
+		if (numblocks < 500)
 			numblocks = 500;
 		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
 		if (retval)
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index ef87ab7..848a02a 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -64,7 +64,6 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 	struct ext2_super_block	*sb;
 	struct ext2_inode	inode;
 	__u32			*dindir_buf, *gdt_buf;
-	int			rsv_add;
 	unsigned long long	apb, inode_size;
 	blk_t			dindir_blk, rsv_off, gdt_off, gdt_blk;
 	int			dindir_dirty = 0, inode_dirty = 0;
@@ -84,7 +83,6 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 
 	/* Maximum possible file size (we donly use the dindirect blocks) */
 	apb = EXT2_ADDR_PER_BLOCK(sb);
-	rsv_add = fs->blocksize / 512;
 	if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
 #ifdef RES_GDT_DEBUG
 		printf("reading GDT dindir %u\n", dindir_blk);
@@ -103,7 +101,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 		inode.i_mode = LINUX_S_IFREG | 0600;
 		inode.i_links_count = 1;
 		inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
-		inode.i_blocks = rsv_add;
+		ext2fs_iblk_set(fs, &inode, 1);
 		memset(dindir_buf, 0, fs->blocksize);
 #ifdef RES_GDT_DEBUG
 		printf("allocated GDT dindir %u\n", dindir_blk);
@@ -144,7 +142,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 			gdt_dirty = dindir_dirty = inode_dirty = 1;
 			memset(gdt_buf, 0, fs->blocksize);
 			dindir_buf[gdt_off] = gdt_blk;
-			inode.i_blocks += rsv_add;
+			ext2fs_iblk_add_blocks(fs, &inode, 1);
 #ifdef RES_GDT_DEBUG
 			printf("added primary GDT block %u at %u[%u]\n",
 			       gdt_blk, dindir_blk, gdt_off);
@@ -175,7 +173,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 				       expect, grp, gdt_blk, last);
 #endif
 				gdt_buf[last] = expect;
-				inode.i_blocks += rsv_add;
+				ext2fs_iblk_add_blocks(fs, &inode, 1);
 				gdt_dirty = inode_dirty = 1;
 			} else if (gdt_buf[last] != expect) {
 #ifdef RES_GDT_DEBUG
diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c
index b0bdd7d..4e2ce0f 100644
--- a/misc/dumpe2fs.c
+++ b/misc/dumpe2fs.c
@@ -296,7 +296,12 @@ static void print_inline_journal_information(ext2_filsys fs)
 		exit(1);
 	}
 	fputs(_("Journal size:             "), stdout);
-	size = inode.i_blocks >> 1;
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+	    (inode.i_flags & EXT4_HUGE_FILE_FL))
+		size = inode.i_blocks / (fs->blocksize / 1024);
+	else
+		size = inode.i_blocks >> 1;
 	if (size < 8192)
 		printf("%uk\n", size);
 	else
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 1062ffa..5fb3501 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -1536,7 +1536,7 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
 	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
 	if (retval) goto errout;
 
-	inode.i_blocks = fs->blocksize/512;
+	ext2fs_iblk_set(fs, &inode, 1);
 
 	retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
 	if (retval) goto errout;
-- 
1.5.4.1.144.gdfee-dirty


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 14:52     ` supersud501
@ 2008-04-09 16:09       ` Eric Sandeen
  0 siblings, 0 replies; 23+ messages in thread
From: Eric Sandeen @ 2008-04-09 16:09 UTC (permalink / raw)
  To: supersud501; +Cc: Calvin Walton, linux-ext4

supersud501 wrote:
> Calvin Walton wrote:
>> On Tue, 2008-04-08 at 13:36 -0500, Eric Sandeen wrote:

...

>>> Do you in fact have any very large files on the disk?
>> I'm just curious - if I know for sure that I don't have any huge files
>> on my disk, would I be able to do something like use debugfs to simply
>> clear the flag?
>>
> 
> interests mee, too. and how are "huge files" defined? thought they are 
>  >4gb files?

"large" files are for ei->i_disksize > 0x7fffffffULL, or 2147483647
bytes / 2G.  This is just max offset, not block counts; i.e. completely
sparse 2g file will set this flag.

the "huge" sb flag is set if any file has i_blocks > ~0UL, or 2^32
512-byte blocks, or around 2T, but in this case I think sparseness
doesn't count; you have to actually have the blocks allocated.

-Eric


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09  9:15       ` supersud501
@ 2008-04-09 16:11         ` Theodore Tso
  2008-04-09 17:53           ` supersud501
                             ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Theodore Tso @ 2008-04-09 16:11 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

On Wed, Apr 09, 2008 at 11:15:24AM +0200, supersud501 wrote:
>
> ah ok, so i know what's up - seems i've to wait until fixing it. just 
> wanted to do it, because syslog said "maximum mount time reached, running 
> is recommended". so no need to hurry ;)

That patch which I just sent out passes the regression test suite, but
it hasn't been extensively tested for actual *huge* files.
(Specifically, files with the EXT4_HUGE_FILE_FL because they are
larger than 2TB and so i_blocks had to be specified in units of
filesystem blocksize, instead of units of 512 bytes.)

If you could apply the patch I just sent out and then run "e2fsck -nf
/dev/sdXXX" and let me know you get, that would be much appreciated.

In answer to question of how to determine if you actually *have* any
large files, the simplest thing to do is to use debugfs to temporarily
remove huge_file feature:

debugfs -w /dev/sdXXX               <------- disable the huge_file feature
debugfs: features ^huge_file
debugfs: quit

e2fsck -nf /dev/sdXXX

debugfs -w /dev/sdXXX               <------- re-enable the huge_file feature
debugfs: features huge_file
debugfs: quit

If you see error messages about i_blocks values being wrong (with the
huge_file feature disabled), then the inodes that are referenced are
the ones that have the huge_file flag set.

						- Ted

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 16:11         ` Theodore Tso
@ 2008-04-09 17:53           ` supersud501
  2008-04-09 18:59             ` Theodore Tso
  2008-04-09 17:56           ` supersud501
  2008-04-09 18:12           ` supersud501
  2 siblings, 1 reply; 23+ messages in thread
From: supersud501 @ 2008-04-09 17:53 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:
> 
> That patch which I just sent out passes the regression test suite, but
> it hasn't been extensively tested for actual *huge* files.
> (Specifically, files with the EXT4_HUGE_FILE_FL because they are
> larger than 2TB and so i_blocks had to be specified in units of
> filesystem blocksize, instead of units of 512 bytes.)
> 
> If you could apply the patch I just sent out and then run "e2fsck -nf
> /dev/sdXXX" and let me know you get, that would be much appreciated.
> 

I'll do when the patch arrives in git (or where do i get it from?)

> In answer to question of how to determine if you actually *have* any
> large files, the simplest thing to do is to use debugfs to temporarily
> remove huge_file feature:
> 
> debugfs -w /dev/sdXXX               <------- disable the huge_file feature
> debugfs: features ^huge_file
> debugfs: quit
> 
> e2fsck -nf /dev/sdXXX
> 
> debugfs -w /dev/sdXXX               <------- re-enable the huge_file feature
> debugfs: features huge_file
> debugfs: quit
> 
> If you see error messages about i_blocks values being wrong (with the
> huge_file feature disabled), then the inodes that are referenced are
> the ones that have the huge_file flag set.
> 

Yeah, i'm getting some (~80) errors about i blocks being wrong (besides 
errors that a fast symlink has extents_fl set), and the error is always 
from the type: "i_blocks is x, should be x+8", so it always wants to add 
8 to the existing number. is this the mentioned miscalculation?

however, as i read in the mail from eric, i didn't know that there is a 
difference between "large" and "huge" files and apparently meant "large" 
(>2gb) files. i've got no "huge" (~2TB) files on my drive (and never had).

so i wonder why the flag is set on my drive and if the i_blocks errors i 
get are because of some miscalculation (which shouldn't happen, because 
i have no huge files, right?) or really are some errors (but it's weird 
e2fsck wants to set them always to x+8). doesn't make much sense to me yet.

oh and: thanks for getting into my problem and trying to help me!


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 16:11         ` Theodore Tso
  2008-04-09 17:53           ` supersud501
@ 2008-04-09 17:56           ` supersud501
  2008-04-09 18:12           ` supersud501
  2 siblings, 0 replies; 23+ messages in thread
From: supersud501 @ 2008-04-09 17:56 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:

> That patch which I just sent out passes the regression test suite, but
> it hasn't been extensively tested for actual *huge* files.
> (Specifically, files with the EXT4_HUGE_FILE_FL because they are
> larger than 2TB and so i_blocks had to be specified in units of
> filesystem blocksize, instead of units of 512 bytes.)
> 

ah ok, found it (i should read all mails before answering them :) )


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 16:11         ` Theodore Tso
  2008-04-09 17:53           ` supersud501
  2008-04-09 17:56           ` supersud501
@ 2008-04-09 18:12           ` supersud501
  2008-04-09 19:06             ` Theodore Tso
  2 siblings, 1 reply; 23+ messages in thread
From: supersud501 @ 2008-04-09 18:12 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:
> That patch which I just sent out passes the regression test suite, but
> it hasn't been extensively tested for actual *huge* files.
> (Specifically, files with the EXT4_HUGE_FILE_FL because they are
> larger than 2TB and so i_blocks had to be specified in units of
> filesystem blocksize, instead of units of 512 bytes.)
> 
> If you could apply the patch I just sent out and then run "e2fsck -nf
> /dev/sdXXX" and let me know you get, that would be much appreciated.
> 


with this patch (and huge_files enabled) i get much more errors 
(>1000++) of the following type:

inode x, i_blocks is y, should be y/8
inoda x+1, iblocks is z, should be z/8
.....

for example:

Inode 32538663, i_blocks is 8, should be 1.  Fix? no
Inode 32538664, i_blocks is 8, should be 1.  Fix? no
Inode 32538665, i_blocks is 8, should be 1.  Fix? no
Inode 32538666, i_blocks is 40, should be 5.  Fix? no
Inode 32538667, i_blocks is 32, should be 4.  Fix? no
Inode 32538668, i_blocks is 8, should be 1.  Fix? no
Inode 32538669, i_blocks is 8, should be 1.  Fix? no
Inode 32538670, i_blocks is 8, should be 1.  Fix? no
....
Inode 32587785, i_blocks is 17320, should be 2165.  Fix? no
Inode 32587786, i_blocks is 16936, should be 2117.  Fix? no
Inode 32587787, i_blocks is 120, should be 15.  Fix? no 
<------------ there are also gaps, not always x+1
Inode 32604181, i_blocks is 8, should be 1.  Fix? no
Inode 32604161, i_blocks is 18624, should be 2328.  Fix? no
Inode 32604162, i_blocks is 19400, should be 2425.  Fix? no
Inode 32604163, i_blocks is 18800, should be 2350.  Fix? no
Inode 32604164, i_blocks is 16488, should be 2061.  Fix? no
Inode 32604165, i_blocks is 17832, should be 2229.  Fix? no
Inode 32604166, i_blocks is 17880, should be 2235.  Fix? no
Inode 32604167, i_blocks is 20560, should be 2570.  Fix? no
Inode 32604168, i_blocks is 20480, should be 2560.  Fix? no
Inode 32604169, i_blocks is 18224, should be 2278.  Fix? no

not good?


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 17:53           ` supersud501
@ 2008-04-09 18:59             ` Theodore Tso
  2008-04-09 19:23               ` supersud501
  0 siblings, 1 reply; 23+ messages in thread
From: Theodore Tso @ 2008-04-09 18:59 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

On Wed, Apr 09, 2008 at 07:53:42PM +0200, supersud501 wrote:
> Theodore Tso wrote:
>> That patch which I just sent out passes the regression test suite, but
>> it hasn't been extensively tested for actual *huge* files.
>> (Specifically, files with the EXT4_HUGE_FILE_FL because they are
>> larger than 2TB and so i_blocks had to be specified in units of
>> filesystem blocksize, instead of units of 512 bytes.)
>> If you could apply the patch I just sent out and then run "e2fsck -nf
>> /dev/sdXXX" and let me know you get, that would be much appreciated.
>
> I'll do when the patch arrives in git (or where do i get it from?)

I mailed it to the linux-ext4 list for reiview, I'll send it to you
directly.

> Yeah, i'm getting some (~80) errors about i blocks being wrong (besides 
> errors that a fast symlink has extents_fl set), and the error is always 
> from the type: "i_blocks is x, should be x+8", so it always wants to add 8 
> to the existing number. is this the mentioned miscalculation?

x+8, or x*8?  I would have expected the latter.

> so i wonder why the flag is set on my drive and if the i_blocks errors i 
> get are because of some miscalculation (which shouldn't happen, because i 
> have no huge files, right?) or really are some errors (but it's weird 
> e2fsck wants to set them always to x+8). doesn't make much sense to me yet.


Using debugfs, can you use the stat command to dump out the inode, and
send the results?

i.e., if you get the message:

Inode 45994, i_blocks is 24, should be 192.  Fix? no

Then when you use debugfs, you might see:

debugfs 1.40.8 (13-Mar-2008)
debugfs:  features
Filesystem features: has_journal resize_inode dir_index filetype sparse_super large_file huge_file
debugfs:  stat <45994>
Inode: 45994   Type: regular    Mode:  0644   Flags: 0x0   Generation: 124890615
User:     0   Group:     0   Size: 90118
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 24
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x47ddb871 -- Sun Mar 16 20:16:49 2008
atime: 0x47fbd5d3 -- Tue Apr  8 16:30:11 2008
mtime: 0x47dca16f -- Sun Mar 16 00:26:23 2008
BLOCKS:
(0-11):140798-140809, (IND):140810, (12-22):140811-140821
TOTAL: 24

So with the huge file, note the Blockcount (i_blocks) of 24, and that
debugfs reports the total number of blocks is 24.  

Without the huge_file feature, you'll see this:

debugfs 1.40.8 (13-Mar-2008)
debugfs:  features
Filesystem features: has_journal resize_inode dir_index filetype sparse_super large_file
debugfs:   stat <45994>
Inode: 45994   Type: regular    Mode:  0644   Flags: 0x0   Generation: 124890615
User:     0   Group:     0   Size: 90118
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 192
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x47ddb871 -- Sun Mar 16 20:16:49 2008
atime: 0x47fbd5d3 -- Tue Apr  8 16:30:11 2008
mtime: 0x47dca16f -- Sun Mar 16 00:26:23 2008
BLOCKS:
(0-11):140798-140809, (IND):140810, (12-22):140811-140821
TOTAL: 24

Note that the blockcount (i.e., i_blocks) is 192 blocks (in Single
Unix Specification legacy 512-byte units).  Since this filesystem is
using a 4k filesystem blocksize, and there are 8 legacy SuS blocks per
filesystem block, when you take the 192 blockcount, and divide by 8,
you get 24 blocks --- which matches with the "TOTAL: 24" display.

       	   	 	      	  	  - Ted

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 18:12           ` supersud501
@ 2008-04-09 19:06             ` Theodore Tso
  2008-04-09 19:19               ` supersud501
  0 siblings, 1 reply; 23+ messages in thread
From: Theodore Tso @ 2008-04-09 19:06 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

On Wed, Apr 09, 2008 at 08:12:52PM +0200, supersud501 wrote:
>
> with this patch (and huge_files enabled) i get much more errors (>1000++) 
> of the following type:
>
> inode x, i_blocks is y, should be y/8
> inoda x+1, iblocks is z, should be z/8
> .....
>
> for example:
>
> Inode 32538663, i_blocks is 8, should be 1.  Fix? no
> Inode 32538664, i_blocks is 8, should be 1.  Fix? no

Can you send me the output of debugfs's "stat <32538663>", "stat
<32538664>", etc?   And also the output of dumpe2fs -h for the filesystem?

	     	    	     	 	   - Ted

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 19:06             ` Theodore Tso
@ 2008-04-09 19:19               ` supersud501
  2008-04-09 21:08                 ` Theodore Tso
  0 siblings, 1 reply; 23+ messages in thread
From: supersud501 @ 2008-04-09 19:19 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:
> On Wed, Apr 09, 2008 at 08:12:52PM +0200, supersud501 wrote:
>> with this patch (and huge_files enabled) i get much more errors (>1000++) 
>> of the following type:
>>
>> inode x, i_blocks is y, should be y/8
>> inoda x+1, iblocks is z, should be z/8
>> .....
>>
>> for example:
>>
>> Inode 32538663, i_blocks is 8, should be 1.  Fix? no
>> Inode 32538664, i_blocks is 8, should be 1.  Fix? no
> 
> Can you send me the output of debugfs's "stat <32538663>", "stat
> <32538664>", etc?   And also the output of dumpe2fs -h for the filesystem?
> 
> 	     	    	     	 	   - Ted
> 


Inode: 32538663   Type: regular    Mode:  0640   Flags: 0x80000 
Generation: 1807877460
User:  1000   Group:  1000   Size: 3902
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x47dead07 -- Mon Mar 17 18:40:23 2008
atime: 0x47dead07 -- Mon Mar 17 18:40:23 2008
mtime: 0x45a5e96b -- Thu Jan 11 08:38:19 2007
BLOCKS:
(0):75131957
TOTAL: 1

Inode: 32538664   Type: regular    Mode:  0640   Flags: 0x80000 
Generation: 1807877461
User:  1000   Group:  1000   Size: 2984
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x47dead07 -- Mon Mar 17 18:40:23 2008
atime: 0x47dead07 -- Mon Mar 17 18:40:23 2008
mtime: 0x45a5e96b -- Thu Jan 11 08:38:19 2007
BLOCKS:
(0):75131958
TOTAL: 1


dumpe2fs:

dumpe2fs 1.40.8 (13-Mar-2008)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          4021e5ea-b06d-45c9-8c53-28b0565bb834
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal resize_inode dir_index filetype 
extents sparse_super large_file huge_file
Filesystem flags:         signed_directory_hash test_filesystem
Default mount options:    (none)
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              58114048
Block count:              116207103
Reserved block count:     5810355
Free blocks:              11485206
Free inodes:              57967276
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      996
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         16384
Inode blocks per group:   512
Filesystem created:       Wed Oct  3 01:15:34 2007
Last mount time:          Wed Apr  9 19:30:26 2008
Last write time:          Wed Apr  9 20:02:38 2008
Mount count:              14
Maximum mount count:      27
Last checked:             Thu Feb 28 23:21:45 2008
Check interval:           15552000 (6 months)
Next check after:         Wed Aug 27 00:21:45 2008
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:		  128
Journal inode:            8
Default directory hash:   tea
Directory Hash Seed:      89709093-0816-4385-a3fa-164c8564e7d2
Journal backup:           inode blocks
Journal size:             128M


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 18:59             ` Theodore Tso
@ 2008-04-09 19:23               ` supersud501
  0 siblings, 0 replies; 23+ messages in thread
From: supersud501 @ 2008-04-09 19:23 UTC (permalink / raw)
  To: Theodore Tso, linux-ext4, Eric Sandeen

Theodore Tso wrote:
>> Yeah, i'm getting some (~80) errors about i blocks being wrong (besides 
>> errors that a fast symlink has extents_fl set), and the error is always 
>> from the type: "i_blocks is x, should be x+8", so it always wants to add 8 
>> to the existing number. is this the mentioned miscalculation?
> 
> x+8, or x*8?  I would have expected the latter.
> 

really "x+8" - but since those are only "few" errors (~80 in opposite to 
the 1000++ i've with the patched version), they might not be related to 
my "huge_file" problem.


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 19:19               ` supersud501
@ 2008-04-09 21:08                 ` Theodore Tso
  2008-04-11 13:04                   ` Theodore Tso
  0 siblings, 1 reply; 23+ messages in thread
From: Theodore Tso @ 2008-04-09 21:08 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

Whoops, I had a one-character typo in e2fsck.  Try this patch
instead.... (made against git the next branch).

					- Ted

>From 9f86e62e242ce7e977def15925c70a39dec6be6c Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Wed, 9 Apr 2008 11:39:11 -0400
Subject: [E2FSPROGS, PATCH] Add support for the HUGE_FILE feature

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 e2fsck/emptydir.c      |    3 +-
 e2fsck/message.c       |    7 ++++-
 e2fsck/pass1.c         |   12 ++++++-
 e2fsck/pass2.c         |    2 +-
 e2fsck/pass3.c         |    6 ++--
 e2fsck/rehash.c        |    2 +-
 e2fsck/super.c         |    3 +-
 lib/e2p/pf.c           |    1 +
 lib/ext2fs/Makefile.in |    2 +
 lib/ext2fs/bb_inode.c  |    2 +-
 lib/ext2fs/bmap.c      |    2 +-
 lib/ext2fs/expanddir.c |    2 +-
 lib/ext2fs/ext2_fs.h   |    1 +
 lib/ext2fs/ext2fs.h    |   14 ++++++--
 lib/ext2fs/i_block.c   |   76 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/ext2fs/mkdir.c     |    2 +-
 lib/ext2fs/mkjournal.c |    2 +-
 lib/ext2fs/read_bb.c   |   13 ++++++--
 lib/ext2fs/res_gdt.c   |    8 ++---
 misc/dumpe2fs.c        |    7 ++++-
 resize/resize2fs.c     |    2 +-
 21 files changed, 137 insertions(+), 32 deletions(-)
 create mode 100644 lib/ext2fs/i_block.c

diff --git a/e2fsck/emptydir.c b/e2fsck/emptydir.c
index 5dbf021..6baab76 100644
--- a/e2fsck/emptydir.c
+++ b/e2fsck/emptydir.c
@@ -168,8 +168,7 @@ static int fix_directory(ext2_filsys fs,
 
 	if (edi->freed_blocks) {
 		edi->inode.i_size -= edi->freed_blocks * fs->blocksize;
-		edi->inode.i_blocks -= edi->freed_blocks *
-			(fs->blocksize / 512);
+		ext2fs_iblk_add_blocks(fs, &edi->inode, edi->freed_blocks);
 		retval = ext2fs_write_inode(fs, db->ino, &edi->inode);
 		if (retval)
 			return 0;
diff --git a/e2fsck/message.c b/e2fsck/message.c
index 8a3705e..184e824 100644
--- a/e2fsck/message.c
+++ b/e2fsck/message.c
@@ -275,7 +275,12 @@ static _INLINE_ void expand_inode_expression(char ch,
 		printf("%u", large_inode->i_extra_isize);
 		break;
 	case 'b':
-		printf("%u", inode->i_blocks);
+		if (inode->i_flags & EXT4_HUGE_FILE_FL)
+			printf("%llu", inode->i_blocks +
+			       (((long long) inode->osd2.linux2.l_i_blocks_hi) 
+				<< 32));
+		else
+			printf("%u", inode->i_blocks);
 		break;
 	case 'l':
 		printf("%d", inode->i_links_count);
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index b85f04f..ee9186f 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1847,7 +1847,10 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		}
 	}
 
-	pb.num_blocks *= (fs->blocksize / 512);
+	if (!(fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
+	    !(inode->i_flags & EXT4_HUGE_FILE_FL))
+		pb.num_blocks *= (fs->blocksize / 512);
 #if 0
 	printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
 	       ino, inode->i_size, pb.last_block, inode->i_blocks,
@@ -1891,10 +1894,15 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	if (LINUX_S_ISREG(inode->i_mode) &&
 	    (inode->i_size_high || inode->i_size & 0x80000000UL))
 		ctx->large_files++;
-	if (pb.num_blocks != inode->i_blocks) {
+	if ((pb.num_blocks != inode->i_blocks) ||
+	    ((fs->super->s_feature_ro_compat &
+	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+	     (inode->i_flags & EXT4_HUGE_FILE_FL) &&
+	     (inode->osd2.linux2.l_i_blocks_hi != 0))) {
 		pctx->num = pb.num_blocks;
 		if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
 			inode->i_blocks = pb.num_blocks;
+			inode->osd2.linux2.l_i_blocks_hi = 0;
 			dirty_inode++;
 		}
 		pctx->num = 0;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 906662d..7aa693b 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -1429,7 +1429,7 @@ static int allocate_dir_block(e2fsck_t ctx,
 	 * Update the inode block count
 	 */
 	e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
-	inode.i_blocks += fs->blocksize / 512;
+	ext2fs_iblk_add_blocks(fs, &inode, 1);
 	if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
 		inode.i_size = (db->blockcnt+1) * fs->blocksize;
 	e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 867cbf8..4ef1446 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -227,7 +227,7 @@ static void check_root(e2fsck_t ctx)
 	inode.i_size = fs->blocksize;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 	inode.i_links_count = 2;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	inode.i_block[0] = blk;
 
 	/*
@@ -472,7 +472,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
 	inode.i_size = fs->blocksize;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
 	inode.i_links_count = 2;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	inode.i_block[0] = blk;
 
 	/*
@@ -803,7 +803,7 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
 		return retval;
 	
 	inode.i_size = (es.last_block + 1) * fs->blocksize;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 
 	e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
 
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index a1f75ef..e75774a 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -668,7 +668,7 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
 	else
 		inode.i_flags |= EXT2_INDEX_FL;
 	inode.i_size = outdir->num * fs->blocksize;
-	inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
+	ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared);
 	e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
 
 	return 0;
diff --git a/e2fsck/super.c b/e2fsck/super.c
index 87a0d78..b8a1df7 100644
--- a/e2fsck/super.c
+++ b/e2fsck/super.c
@@ -195,8 +195,7 @@ static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
 	e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
 
 	if (pb.truncated_blocks)
-		inode->i_blocks -= pb.truncated_blocks *
-			(fs->blocksize / 512);
+		ext2fs_iblk_sub_blocks(fs, inode, pb.truncated_blocks);
 
 	if (inode->i_file_acl) {
 		retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
diff --git a/lib/e2p/pf.c b/lib/e2p/pf.c
index 3e9a7cd..05a961a 100644
--- a/lib/e2p/pf.c
+++ b/lib/e2p/pf.c
@@ -45,6 +45,7 @@ static struct flags_name flags_array[] = {
 	{ EXT2_NOTAIL_FL, "t", "No_Tailmerging" },
 	{ EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
 	{ EXT4_EXTENTS_FL, "e", "Extents" },
+	{ EXT4_HUGE_FILE_FL, "h", "Huge_file" },
 	{ 0, NULL, NULL }
 };
 
diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in
index 2766493..677e2d6 100644
--- a/lib/ext2fs/Makefile.in
+++ b/lib/ext2fs/Makefile.in
@@ -47,6 +47,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
 	get_pathname.o \
 	getsize.o \
 	getsectsize.o \
+	i_block.o \
 	icount.o \
 	ind_block.o \
 	initialize.o \
@@ -106,6 +107,7 @@ SRCS= ext2_err.c \
 	$(srcdir)/get_pathname.c \
 	$(srcdir)/getsize.c \
 	$(srcdir)/getsectsize.c \
+	$(srcdir)/i_block.c \
 	$(srcdir)/icount.c \
 	$(srcdir)/ind_block.c \
 	$(srcdir)/initialize.c \
diff --git a/lib/ext2fs/bb_inode.c b/lib/ext2fs/bb_inode.c
index 1f5b4e8..dbda79f 100644
--- a/lib/ext2fs/bb_inode.c
+++ b/lib/ext2fs/bb_inode.c
@@ -127,7 +127,7 @@ errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
 	inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0);
 	if (!inode.i_ctime)
 		inode.i_ctime = fs->now ? fs->now : time(0);
-	inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
+	ext2fs_iblk_set(fs, &inode, rec.bad_block_count);
 	inode.i_size = rec.bad_block_count * fs->blocksize;
 
 	retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
diff --git a/lib/ext2fs/bmap.c b/lib/ext2fs/bmap.c
index 5fe0986..ceb352e 100644
--- a/lib/ext2fs/bmap.c
+++ b/lib/ext2fs/bmap.c
@@ -297,7 +297,7 @@ done:
 	if (handle)
 		ext2fs_extent_free(handle);
 	if ((retval == 0) && (blocks_alloc || inode_dirty)) {
-		inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
+		ext2fs_iblk_add_blocks(fs, inode, blocks_alloc);
 		retval = ext2fs_write_inode(fs, ino, inode);
 	}
 	return retval;
diff --git a/lib/ext2fs/expanddir.c b/lib/ext2fs/expanddir.c
index 10a5149..c124d3e 100644
--- a/lib/ext2fs/expanddir.c
+++ b/lib/ext2fs/expanddir.c
@@ -116,7 +116,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
 		return retval;
 	
 	inode.i_size += fs->blocksize;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 
 	retval = ext2fs_write_inode(fs, dir, &inode);
 	if (retval)
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 444211d..ad42cf8 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -271,6 +271,7 @@ struct ext2_dx_countlimit {
 #define EXT2_NOTAIL_FL			0x00008000 /* file tail should not be merged */
 #define EXT2_DIRSYNC_FL 		0x00010000 /* Synchronous directory modifications */
 #define EXT2_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
+#define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
 #define EXT4_EXTENTS_FL 		0x00080000 /* Inode uses extents */
 #define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
 
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 1a7cb86..e5988cd 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -516,6 +516,7 @@ typedef struct ext2_icount *ext2_icount_t;
 					 EXT4_FEATURE_INCOMPAT_FLEX_BG)
 #endif
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
 					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
 					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
 					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
@@ -524,10 +525,8 @@ typedef struct ext2_icount *ext2_icount_t;
  * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
  * to ext2fs_openfs()
  */
-#define EXT2_LIB_SOFTSUPP_INCOMPAT	(EXT3_FEATURE_INCOMPAT_EXTENTS)
-#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
-					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
-					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+#define EXT2_LIB_SOFTSUPP_INCOMPAT	(0)
+#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
 
 /*
  * function prototypes
@@ -899,6 +898,13 @@ extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
 /* getsectsize.c */
 errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
 
+/* i_block.c */
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks);
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b);
+
 /* imager.c */
 extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
 extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
diff --git a/lib/ext2fs/i_block.c b/lib/ext2fs/i_block.c
new file mode 100644
index 0000000..90e2a2b
--- /dev/null
+++ b/lib/ext2fs/i_block.c
@@ -0,0 +1,76 @@
+/*
+ * i_block.c --- Manage the i_block field for i_blocks
+ *
+ * Copyright (C) 2008 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ * 
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <string.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b;
+
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		b = inode->i_blocks + 
+			(((long long) inode->osd2.linux2.l_i_blocks_hi) << 32);
+		b += num_blocks;
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks += (fs->blocksize / 512) * num_blocks;
+	return 0;
+}
+
+
+errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
+				 blk64_t num_blocks)
+{
+	unsigned long long b;
+
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		b = inode->i_blocks + 
+			(((long long) inode->osd2.linux2.l_i_blocks_hi) << 32);
+		b -= num_blocks;
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks -= (fs->blocksize / 512) * num_blocks;
+	return 0;
+}
+
+errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b)
+{
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+	    (inode->i_flags & EXT4_HUGE_FILE_FL)) {
+		inode->i_blocks = b & 0xFFFFFFFF;
+		inode->osd2.linux2.l_i_blocks_hi = b >> 32;
+	} else
+		inode->i_blocks = (fs->blocksize / 512) * b;
+	return 0;
+}
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index 45e6820..34242df 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -82,7 +82,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	memset(&inode, 0, sizeof(struct ext2_inode));
 	inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
 	inode.i_uid = inode.i_gid = 0;
-	inode.i_blocks = fs->blocksize / 512;
+	ext2fs_iblk_set(fs, &inode, 1);
 	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);
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
index 61d10a6..23cc60c 100644
--- a/lib/ext2fs/mkjournal.c
+++ b/lib/ext2fs/mkjournal.c
@@ -228,7 +228,7 @@ static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
 		goto errout;
 
  	inode.i_size += fs->blocksize * size;
-	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+	ext2fs_iblk_add_blocks(fs, &inode, es.newblocks);
 	inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
 	inode.i_links_count = 1;
 	inode.i_mode = LINUX_S_IFREG | 0600;
diff --git a/lib/ext2fs/read_bb.c b/lib/ext2fs/read_bb.c
index ff7e292..732d2ab 100644
--- a/lib/ext2fs/read_bb.c
+++ b/lib/ext2fs/read_bb.c
@@ -74,10 +74,15 @@ errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
 		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
 		if (retval)
 			return retval;
-		if (inode.i_blocks < 500)
-			numblocks = (inode.i_blocks /
-				     (fs->blocksize / 512)) + 20;
-		else
+		numblocks = inode.i_blocks;
+		if (!((fs->super->s_feature_ro_compat &
+		       EXT4_FEATURE_RO_COMPAT_HUGE_FILE) && 
+		      (inode.i_flags & EXT4_HUGE_FILE_FL)))
+			numblocks = numblocks / (fs->blocksize / 512);
+		numblocks += 20;
+		if (numblocks < 50)
+			numblocks = 50;
+		if (numblocks > 50000)
 			numblocks = 500;
 		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
 		if (retval)
diff --git a/lib/ext2fs/res_gdt.c b/lib/ext2fs/res_gdt.c
index ef87ab7..848a02a 100644
--- a/lib/ext2fs/res_gdt.c
+++ b/lib/ext2fs/res_gdt.c
@@ -64,7 +64,6 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 	struct ext2_super_block	*sb;
 	struct ext2_inode	inode;
 	__u32			*dindir_buf, *gdt_buf;
-	int			rsv_add;
 	unsigned long long	apb, inode_size;
 	blk_t			dindir_blk, rsv_off, gdt_off, gdt_blk;
 	int			dindir_dirty = 0, inode_dirty = 0;
@@ -84,7 +83,6 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 
 	/* Maximum possible file size (we donly use the dindirect blocks) */
 	apb = EXT2_ADDR_PER_BLOCK(sb);
-	rsv_add = fs->blocksize / 512;
 	if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
 #ifdef RES_GDT_DEBUG
 		printf("reading GDT dindir %u\n", dindir_blk);
@@ -103,7 +101,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 		inode.i_mode = LINUX_S_IFREG | 0600;
 		inode.i_links_count = 1;
 		inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
-		inode.i_blocks = rsv_add;
+		ext2fs_iblk_set(fs, &inode, 1);
 		memset(dindir_buf, 0, fs->blocksize);
 #ifdef RES_GDT_DEBUG
 		printf("allocated GDT dindir %u\n", dindir_blk);
@@ -144,7 +142,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 			gdt_dirty = dindir_dirty = inode_dirty = 1;
 			memset(gdt_buf, 0, fs->blocksize);
 			dindir_buf[gdt_off] = gdt_blk;
-			inode.i_blocks += rsv_add;
+			ext2fs_iblk_add_blocks(fs, &inode, 1);
 #ifdef RES_GDT_DEBUG
 			printf("added primary GDT block %u at %u[%u]\n",
 			       gdt_blk, dindir_blk, gdt_off);
@@ -175,7 +173,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
 				       expect, grp, gdt_blk, last);
 #endif
 				gdt_buf[last] = expect;
-				inode.i_blocks += rsv_add;
+				ext2fs_iblk_add_blocks(fs, &inode, 1);
 				gdt_dirty = inode_dirty = 1;
 			} else if (gdt_buf[last] != expect) {
 #ifdef RES_GDT_DEBUG
diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c
index b0bdd7d..4e2ce0f 100644
--- a/misc/dumpe2fs.c
+++ b/misc/dumpe2fs.c
@@ -296,7 +296,12 @@ static void print_inline_journal_information(ext2_filsys fs)
 		exit(1);
 	}
 	fputs(_("Journal size:             "), stdout);
-	size = inode.i_blocks >> 1;
+	if ((fs->super->s_feature_ro_compat &
+	     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+	    (inode.i_flags & EXT4_HUGE_FILE_FL))
+		size = inode.i_blocks / (fs->blocksize / 1024);
+	else
+		size = inode.i_blocks >> 1;
 	if (size < 8192)
 		printf("%uk\n", size);
 	else
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 1062ffa..5fb3501 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -1536,7 +1536,7 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
 	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
 	if (retval) goto errout;
 
-	inode.i_blocks = fs->blocksize/512;
+	ext2fs_iblk_set(fs, &inode, 1);
 
 	retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
 	if (retval) goto errout;
-- 
1.5.4.1.144.gdfee-dirty


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-09 21:08                 ` Theodore Tso
@ 2008-04-11 13:04                   ` Theodore Tso
  2008-04-11 13:38                     ` supersud501
  0 siblings, 1 reply; 23+ messages in thread
From: Theodore Tso @ 2008-04-11 13:04 UTC (permalink / raw)
  To: supersud501; +Cc: Eric Sandeen, linux-ext4

On Wed, Apr 09, 2008 at 05:08:56PM -0400, Theodore Tso wrote:
> Whoops, I had a one-character typo in e2fsck.  Try this patch
> instead.... (made against git the next branch).

Hi, have you had a chance to try this updated patch?

Thanks,

							- Ted

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: e2fsck (git) on ext4: unsupported feature(s): huge_file
  2008-04-11 13:04                   ` Theodore Tso
@ 2008-04-11 13:38                     ` supersud501
  0 siblings, 0 replies; 23+ messages in thread
From: supersud501 @ 2008-04-11 13:38 UTC (permalink / raw)
  To: Theodore Tso; +Cc: Eric Sandeen, linux-ext4

Theodore Tso wrote:
> On Wed, Apr 09, 2008 at 05:08:56PM -0400, Theodore Tso wrote:
>> Whoops, I had a one-character typo in e2fsck.  Try this patch
>> instead.... (made against git the next branch).
> 
> Hi, have you had a chance to try this updated patch?
> 
> Thanks,
> 
> 							- Ted
> 

yes, i had, the mass of errors were not there anymore.

and the errors of the type "i_blocks is x, should be y" were not always 
of the type x+8 like before but more random, so that it looked like as 
if it was correcting them right.

unfortunately i cannot make any further tests, because i just 
reformatted the drive with ext3, to avoid further complications (and to 
be able to use the drive on windows machines, too).

my second (and now only) ext4dev test-filesystem has no huge_file flag, 
so i think i'm out of further testing the patch.

regards,
supersud501


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2008-04-11 13:38 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-08 17:58 e2fsck (git) on ext4: unsupported feature(s): huge_file supersud501
2008-04-08 18:36 ` Eric Sandeen
2008-04-08 19:45   ` supersud501
2008-04-08 21:00     ` Theodore Tso
2008-04-09  9:15       ` supersud501
2008-04-09 16:11         ` Theodore Tso
2008-04-09 17:53           ` supersud501
2008-04-09 18:59             ` Theodore Tso
2008-04-09 19:23               ` supersud501
2008-04-09 17:56           ` supersud501
2008-04-09 18:12           ` supersud501
2008-04-09 19:06             ` Theodore Tso
2008-04-09 19:19               ` supersud501
2008-04-09 21:08                 ` Theodore Tso
2008-04-11 13:04                   ` Theodore Tso
2008-04-11 13:38                     ` supersud501
2008-04-09 15:50       ` [E2FSPROGS, PATCH] Add support for the HUGE_FILE feature Theodore Ts'o
2008-04-09 12:54     ` e2fsck (git) on ext4: unsupported feature(s): huge_file Eric Sandeen
2008-04-09 14:45   ` Calvin Walton
2008-04-09 14:52     ` supersud501
2008-04-09 16:09       ` Eric Sandeen
2008-04-08 18:37 ` Eric Sandeen
2008-04-08 22:40   ` Christian Kujau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox