Whamcloud - gitweb
On-disk format definition for huge files
authorTheodore Ts'o <tytso@mit.edu>
Sat, 11 Nov 2006 11:32:03 +0000 (06:32 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 11 Nov 2006 11:32:03 +0000 (06:32 -0500)
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE (0x0008) - change i_blocks to be
  in units of s_blocksize units instead of 512-byte sectors, use
  l_i_frag and l_i_fsize as i_blocks_hi (could also be part of 64BIT).

E2fsck and debugfs changed to support i_blocks_hi instead of l_i_frag and
l_i_fsize.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
13 files changed:
debugfs/debugfs.c
debugfs/set_fields.c
e2fsck/ChangeLog
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/problem.c
e2fsck/problem.h
lib/ext2fs/ChangeLog
lib/ext2fs/ext2_fs.h
lib/ext2fs/swapfs.c
tests/ChangeLog
tests/f_bad_disconnected_inode/expect.1
tests/f_badinode/expect.1

index 8d93795..6eba9ae 100644 (file)
@@ -541,7 +541,7 @@ void internal_dump_inode(FILE *out, const char *prefix,
                fprintf(out, "%lld\n", i_size);
        } else
                fprintf(out, "%d\n", inode->i_size);
-       if (current_fs->super->s_creator_os == EXT2_OS_HURD)
+       if (os == EXT2_OS_HURD)
                fprintf(out,
                        "%sFile ACL: %d    Directory ACL: %d Translator: %d\n",
                        prefix,
@@ -551,13 +551,16 @@ void internal_dump_inode(FILE *out, const char *prefix,
                fprintf(out, "%sFile ACL: %d    Directory ACL: %d\n",
                        prefix,
                        inode->i_file_acl, LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0);
-       fprintf(out, "%sLinks: %d   Blockcount: %u\n",
-               prefix, inode->i_links_count, inode->i_blocks);
+       if (os == EXT2_OS_LINUX) 
+               fprintf(out, "%sLinks: %d   Blockcount: %llu\n",
+                       prefix, inode->i_links_count, 
+                       (((unsigned long long) 
+                         inode->osd2.linux2.l_i_blocks_hi << 32)) + 
+                       inode->i_blocks);
+       else
+               fprintf(out, "%sLinks: %d   Blockcount: %u\n",
+                       prefix, inode->i_links_count, inode->i_blocks);
        switch (os) {
-           case EXT2_OS_LINUX:
-               frag = inode->osd2.linux2.l_i_frag;
-               fsize = inode->osd2.linux2.l_i_fsize;
-               break;
            case EXT2_OS_HURD:
                frag = inode->osd2.hurd2.h_i_frag;
                fsize = inode->osd2.hurd2.h_i_fsize;
@@ -867,6 +870,9 @@ void do_modify_inode(int argc, char *argv[])
        modify_u32(argv[0], "Access time", decimal_format, &inode.i_atime);
        modify_u32(argv[0], "Deletion time", decimal_format, &inode.i_dtime);
        modify_u16(argv[0], "Link count", decimal_format, &inode.i_links_count);
+       if (os == EXT2_OS_LINUX)
+               modify_u16(argv[0], "Block count high", unsignedlong_format, 
+                          &inode.osd2.linux2.l_i_blocks_hi);
        modify_u32(argv[0], "Block count", unsignedlong_format, &inode.i_blocks);
        modify_u32(argv[0], "File flags", hex_format, &inode.i_flags);
        modify_u32(argv[0], "Generation", hex_format, &inode.i_generation);
@@ -879,16 +885,12 @@ void do_modify_inode(int argc, char *argv[])
        else
                modify_u32(argv[0], "High 32bits of size", decimal_format, &inode.i_size_high);
 
-       if (current_fs->super->s_creator_os == EXT2_OS_HURD)
+       if (os == EXT2_OS_HURD)
                modify_u32(argv[0], "Translator Block",
                            decimal_format, &inode.osd1.hurd1.h_i_translator);
        
        modify_u32(argv[0], "Fragment address", decimal_format, &inode.i_faddr);
        switch (os) {
-           case EXT2_OS_LINUX:
-               frag = &inode.osd2.linux2.l_i_frag;
-               fsize = &inode.osd2.linux2.l_i_fsize;
-               break;
            case EXT2_OS_HURD:
                frag = &inode.osd2.hurd2.h_i_frag;
                fsize = &inode.osd2.hurd2.h_i_fsize;
index 014420a..5bbddfb 100644 (file)
@@ -136,8 +136,9 @@ static struct field_set_info inode_fields[] = {
        { "file_acl", &set_inode.i_file_acl, 4, parse_uint },
        { "dir_acl", &set_inode.i_dir_acl, 4, parse_uint },
        { "faddr", &set_inode.i_faddr, 4, parse_uint },
-       { "frag", &set_inode.osd2.linux2.l_i_frag, 1, parse_uint },
-       { "fsize", &set_inode.osd2.linux2.l_i_fsize, 1, parse_uint },
+       { "blocks_hi", &set_inode.osd2.linux2.l_i_blocks_hi, 2, parse_uint },
+       { "frag", &set_inode.osd2.hurd2.h_i_frag, 1, parse_uint },
+       { "fsize", &set_inode.osd2.hurd2.h_i_fsize, 1, parse_uint },
        { "uid_high", &set_inode.osd2.linux2.l_i_uid_high, 2, parse_uint },
        { "gid_high", &set_inode.osd2.linux2.l_i_gid_high, 2, parse_uint },
        { "author", &set_inode.osd2.hurd2.h_i_author, 4, parse_uint },
index ce80f5c..2f11bd7 100644 (file)
@@ -1,3 +1,11 @@
+2006-11-11  Theodore Tso  <tytso@mit.edu>
+
+       * problem.c, problem.h (PR_2_BLOCKS_HI_ZERO): Add new problem code.
+
+       * pass1.c (e2fsck_pass1), pass2.c (e2fsck_process_bad_inode):
+               Replace check for l_i_frag and l_i_fsize with one for
+               i_blocks_hi.
+
 2006-11-08  Theodore Tso  <tytso@mit.edu>
 
        * badblocks.c (read_bad_blocks_file): Change the last_block
index 9a84b78..9650fe1 100644 (file)
@@ -731,10 +731,6 @@ void e2fsck_pass1(e2fsck_t ctx)
                
                ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
                switch (fs->super->s_creator_os) {
-                   case EXT2_OS_LINUX:
-                       frag = inode->osd2.linux2.l_i_frag;
-                       fsize = inode->osd2.linux2.l_i_fsize;
-                       break;
                    case EXT2_OS_HURD:
                        frag = inode->osd2.hurd2.h_i_frag;
                        fsize = inode->osd2.hurd2.h_i_fsize;
@@ -750,6 +746,11 @@ void e2fsck_pass1(e2fsck_t ctx)
                if (inode->i_faddr || frag || fsize ||
                    (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
                        mark_inode_bad(ctx, ino);
+               if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
+                   !(fs->super->s_feature_ro_compat & 
+                     EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+                   (inode->osd2.linux2.l_i_blocks_hi != 0))
+                       mark_inode_bad(ctx, ino);
                if (inode->i_flags & EXT2_IMAGIC_FL) {
                        if (imagic_fs) {
                                if (!ctx->inode_imagic_map)
index e47e950..8bcb3d1 100644 (file)
@@ -1251,10 +1251,6 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
        }
 
        switch (fs->super->s_creator_os) {
-           case EXT2_OS_LINUX:
-               frag = &inode.osd2.linux2.l_i_frag;
-               fsize = &inode.osd2.linux2.l_i_fsize;
-               break;
            case EXT2_OS_HURD:
                frag = &inode.osd2.hurd2.h_i_frag;
                fsize = &inode.osd2.hurd2.h_i_fsize;
@@ -1285,6 +1281,17 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                pctx.num = 0;
        }
 
+       if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
+           !(fs->super->s_feature_ro_compat & 
+             EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
+           (inode.osd2.linux2.l_i_blocks_hi != 0)) {
+               pctx.num = inode.osd2.linux2.l_i_blocks_hi;
+               if (fix_problem(ctx, PR_2_BLOCKS_HI_ZERO, &pctx)) {
+                       inode.osd2.linux2.l_i_blocks_hi = 0;
+                       inode_modified++;
+               }
+       }
+
        if (inode.i_file_acl &&
            ((inode.i_file_acl < fs->super->s_first_data_block) ||
             (inode.i_file_acl >= fs->super->s_blocks_count))) {
index 2dc3073..7f6add4 100644 (file)
@@ -1173,6 +1173,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
          PROMPT_NONE, 0 },
        
+       /* i_blocks_hi should be zero */
+       { PR_2_BLOCKS_HI_ZERO,
+         N_("i_blocks_hi @F %N, @s zero.\n"),
+         PROMPT_CLEAR, 0 },
+
        /* Pass 3 errors */
 
        /* Pass 3: Checking directory connectivity */
index 12f29ec..4561c61 100644 (file)
@@ -699,6 +699,9 @@ struct problem_context {
 /* Duplicate directory entry found */
 #define PR_2_REPORT_DUP_DIRENT 0x020043
 
+/* i_blocks_hi should be zero */
+#define PR_2_BLOCKS_HI_ZERO    0x020044
+
 /*
  * Pass 3 errors
  */
index a76d96b..024363d 100644 (file)
@@ -1,3 +1,12 @@
+2006-11-11  Theodore Tso  <tytso@mit.edu>
+
+       * swapfs.c (ext2fs_swap_inode_full): Byte swap inode->l_i_blocks_hi
+
+       * ext2_fs.h: Add definition of EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
+               which changes i_blocks to be in units of s_blocksize units
+               instead of 512-byte sectors, use l_i_frag and l_i_fsize as
+               i_blocks_hi.
+
 2006-10-02  Eric Sandeen <esandeen@sandeen.net>
 
        * getsize.c (ext2fs_get_device_size): Check to make sure that the
index d3e39f2..c6c9aca 100644 (file)
@@ -299,8 +299,7 @@ struct ext2_inode {
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
-                       __u8    l_i_frag;       /* Fragment number */
-                       __u8    l_i_fsize;      /* Fragment size */
+                       __u16   l_i_blocks_hi;
                        __u16   i_pad1;
                        __u16   l_i_uid_high;   /* these 2 fields    */
                        __u16   l_i_gid_high;   /* were reserved2[0] */
@@ -356,8 +355,7 @@ struct ext2_inode_large {
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
-                       __u8    l_i_frag;       /* Fragment number */
-                       __u8    l_i_fsize;      /* Fragment size */
+                       __u16   l_i_blocks_hi;
                        __u16   i_pad1;
                        __u16   l_i_uid_high;   /* these 2 fields    */
                        __u16   l_i_gid_high;   /* were reserved2[0] */
@@ -576,6 +574,7 @@ struct ext2_super_block {
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
 /* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR    0x0004 not used */
+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE       0x0008
 
 #define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
 #define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
index a4c6698..39e23b2 100644 (file)
@@ -159,8 +159,8 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
        case EXT2_OS_LINUX:
                t->osd1.linux1.l_i_reserved1 =
                        ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
-               t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
-               t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
+               t->osd2.linux2.l_i_blocks_hi = 
+                       ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
                t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
                t->osd2.linux2.l_i_uid_high =
                  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
index 6c9152a..7de19f8 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-11  Theodore Tso  <tytso@mit.edu>
+
+       * f_badinode, f_bad_disconnected_inode: Update expect scripts to
+               show check for i_blocks_hi instead of i_frag and i_fsize.
+
 2006-08-30  Eric Sandeen <esandeen@redhat.com>
 
        * m_raid_opt/expect.1:
index deba68b..b4851f0 100644 (file)
@@ -30,10 +30,7 @@ Clear? yes
 i_faddr for inode 16 (...) is 1003914917, should be zero.
 Clear? yes
 
-i_frag for inode 16 (...) is 42, should be zero.
-Clear? yes
-
-i_fsize for inode 16 (...) is 245, should be zero.
+i_blocks_hi for inode 16 (...) is 62762, should be zero.
 Clear? yes
 
 Unattached inode 16
index ccda818..8caa2cc 100644 (file)
@@ -10,7 +10,7 @@ Clear? yes
 i_file_acl for inode 13 (/timings) is 39, should be zero.
 Clear? yes
 
-i_fsize for inode 13 (/timings) is 4, should be zero.
+i_blocks_hi for inode 13 (/timings) is 1024, should be zero.
 Clear? yes
 
 Inode 14 (/block_dev) is an illegal block device.