Package: parted
Version: 1.8.8.git.2008.03.24-11.1
Severity: wishlist
Tags: patch
User: ubuntu-de...@lists.ubuntu.com
Usertags: origin-ubuntu ubuntu-patch jaunty

The attached dpatch adds skeletal support for ext4 (also forwarded
upstream at
http://parted.alioth.debian.org/cgi-bin/trac.cgi/ticket/188). Would you
consider adding it? I believe that this is enough to allow d-i to
install on ext4 given kernel support, klibc support, and a few partman
patches which I'll send separately.

Thanks,

-- 
Colin Watson                                       [cjwat...@ubuntu.com]
#! /bin/sh /usr/share/dpatch/dpatch-run
## ext4.dpatch by Colin Watson <cjwat...@ubuntu.com>
## Upstream: http://parted.alioth.debian.org/cgi-bin/trac.cgi/ticket/188
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Skeletal ext4 support.

@DPATCH@
diff -urNad parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2.c 
parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2.c
--- parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2.c       2009-01-08 
13:31:49.000000000 +0000
+++ parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2.c        2009-01-08 
13:31:58.000000000 +0000
@@ -184,8 +184,8 @@
 
                fs->gd[group].bg_free_blocks_count = PED_CPU_TO_LE16
                        (EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[group]) + diff);
-               fs->sb.s_free_blocks_count = PED_CPU_TO_LE32
-                       (EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) + diff);
+               ext2_super_free_blocks_count_set(&fs->sb,
+                               EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) + diff);
                fs->metadirty |= EXT2_META_SB | EXT2_META_GD;
        }
        return 1;
@@ -605,7 +605,7 @@
        if (wmeta == EXT2_META_CLEAN)
                return 1;
 
-       fs->sb.s_r_blocks_count = PED_CPU_TO_LE32 (
+       ext2_super_r_blocks_count_set(&fs->sb,
                fs->r_frac * (loff_t)EXT2_SUPER_BLOCKS_COUNT(fs->sb)
                                  / 100);
 
@@ -721,7 +721,8 @@
                            EXT2_FEATURE_COMPAT_HAS_DIR_INDEX)) ||
            (EXT2_SUPER_FEATURE_INCOMPAT(fs->sb)
                        & ~(EXT2_FEATURE_INCOMPAT_FILETYPE |
-                           EXT3_FEATURE_INCOMPAT_RECOVER)) ||
+                           EXT3_FEATURE_INCOMPAT_RECOVER |
+                           EXT4_FEATURE_INCOMPAT_64BIT)) ||
            (EXT2_SUPER_FEATURE_RO_COMPAT(fs->sb)
                        & ~(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
                            EXT2_FEATURE_RO_COMPAT_LARGE_FILE)))
diff -urNad parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_fs.h 
parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_fs.h
--- parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_fs.h    2009-01-08 
13:31:49.000000000 +0000
+++ parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_fs.h     2009-01-08 
13:32:12.000000000 +0000
@@ -59,6 +59,8 @@
 
 #define EXT2_FEATURE_INCOMPAT_FILETYPE         0x0002
 #define EXT3_FEATURE_INCOMPAT_RECOVER          0x0004
+#define EXT3_FEATURE_INCOMPAT_EXTENTS          0x0040 /* actually ext4 */
+#define EXT4_FEATURE_INCOMPAT_64BIT            0x0080
 
 /*
  * Special inodes numbers
@@ -170,9 +172,9 @@
 struct ext2_super_block
 {
        uint32_t        s_inodes_count;         /* Inodes count */
-       uint32_t        s_blocks_count;         /* Blocks count */
-       uint32_t        s_r_blocks_count;       /* Reserved blocks count */
-       uint32_t        s_free_blocks_count;    /* Free blocks count */
+       uint32_t        s_blocks_count_lo;      /* Blocks count */
+       uint32_t        s_r_blocks_count_lo;    /* Reserved blocks count */
+       uint32_t        s_free_blocks_count_lo; /* Free blocks count */
        uint32_t        s_free_inodes_count;    /* Free inodes count */
        uint32_t        s_first_data_block;     /* First Data Block */
        uint32_t        s_log_block_size;       /* Block size */
@@ -231,10 +233,38 @@
        uint32_t        s_journal_inum;         /* inode number of journal file 
*/
        uint32_t        s_journal_dev;          /* device number of journal 
file */
        uint32_t        s_last_orphan;          /* start of list of inodes to 
delete */
+       uint32_t        s_hash_seed[4];         /* HTREE hash seed */
+       uint8_t         s_def_hash_version;     /* Default hash version to use 
*/
+       uint8_t         s_reserved_char_pad;
+       uint16_t        s_desc_size;            /* size of group descriptor */
+       uint32_t        s_default_mount_opts;
+       uint32_t        s_first_meta_bg;        /* First metablock block group 
*/
+       uint32_t        s_mkfs_time;            /* When the filesystem was 
created */
+       uint32_t        s_jnl_blocks[17];       /* Backup of the journal inode 
*/
+       /* 64bit support valid if EXT4_FEATURE_INCOMPAT_64BIT */
+       uint32_t        s_blocks_count_hi;      /* Blocks count */
+       uint32_t        s_r_blocks_count_hi;    /* Reserved blocks count */
+       uint32_t        s_free_blocks_count_hi; /* Free blocks count */
+       uint16_t        s_min_extra_isize;      /* All inodes have at least # 
bytes */
+       uint16_t        s_want_extra_isize;     /* New inodes should reserve # 
bytes */
+       uint32_t        s_flags;                /* Miscellaneous flags */
+       uint16_t        s_raid_stride;          /* RAID stride */
+       uint16_t        s_mmp_interval;         /* # seconds to wait in MMP 
checking */
+       uint64_t        s_mmp_block;            /* Block for multi-mount 
protection */
+       uint32_t        s_raid_stripe_width;    /* blocks on all data disks 
(N*stride) */
+       uint8_t         s_log_groups_per_flex;  /* FLEX_BG group size */
+       uint8_t         s_reserved_char_pad2;
+       uint16_t        s_reserved_pad;
 
-       uint32_t        s_reserved[197];        /* Padding to the end of the 
block */
+       uint32_t        s_reserved[162];        /* Padding to the end of the 
block */
 };
 
+#define EXT2_SUPER_FEATURE_COMPAT(sb)  (PED_LE32_TO_CPU((sb).s_feature_compat))
+#define EXT2_SUPER_FEATURE_INCOMPAT(sb) \
+               (PED_LE32_TO_CPU((sb).s_feature_incompat))
+#define EXT2_SUPER_FEATURE_RO_COMPAT(sb) \
+               (PED_LE32_TO_CPU((sb).s_feature_ro_compat))
+
 #define EXT2_DIRENT_INODE(dir_ent)     (PED_LE32_TO_CPU((dir_ent).inode))
 #define EXT2_DIRENT_REC_LEN(dir_ent)   (PED_LE16_TO_CPU((dir_ent).rec_len))
 #define EXT2_DIRENT_NAME_LEN(dir_ent)  ((dir_ent).name_len)
@@ -267,10 +297,44 @@
 #define EXT2_INODE_BLOCK(inode, blk)   (PED_LE32_TO_CPU((inode).i_block[blk]))
 
 #define EXT2_SUPER_INODES_COUNT(sb)    (PED_LE32_TO_CPU((sb).s_inodes_count))
-#define EXT2_SUPER_BLOCKS_COUNT(sb)    (PED_LE32_TO_CPU((sb).s_blocks_count))
-#define EXT2_SUPER_R_BLOCKS_COUNT(sb)  (PED_LE32_TO_CPU((sb).s_r_blocks_count))
+
+#define EXT2_SUPER_BLOCKS_COUNT(sb) \
+               ((EXT2_SUPER_FEATURE_INCOMPAT((sb)) & 
EXT4_FEATURE_INCOMPAT_64BIT) \
+                ? (((uint64_t) PED_LE32_TO_CPU((sb).s_blocks_count_hi) << 32) \
+                   | PED_LE32_TO_CPU((sb).s_blocks_count_lo)) \
+                : PED_LE32_TO_CPU((sb).s_blocks_count_lo))
+#define EXT2_SUPER_R_BLOCKS_COUNT(sb) \
+               ((EXT2_SUPER_FEATURE_INCOMPAT((sb)) & 
EXT4_FEATURE_INCOMPAT_64BIT) \
+                ? (((uint64_t) PED_LE32_TO_CPU((sb).s_r_blocks_count_hi) << 
32) \
+                   | PED_LE32_TO_CPU((sb).s_r_blocks_count_lo)) \
+                : PED_LE32_TO_CPU((sb).s_r_blocks_count_lo))
 #define EXT2_SUPER_FREE_BLOCKS_COUNT(sb) \
-               (PED_LE32_TO_CPU((sb).s_free_blocks_count))
+               ((EXT2_SUPER_FEATURE_INCOMPAT((sb)) & 
EXT4_FEATURE_INCOMPAT_64BIT) \
+                ? (((uint64_t) PED_LE32_TO_CPU((sb).s_free_blocks_count_hi) << 
32) \
+                   | PED_LE32_TO_CPU((sb).s_free_blocks_count_lo)) \
+                : PED_LE32_TO_CPU((sb).s_free_blocks_count_lo))
+
+static inline void ext2_super_blocks_count_set(struct ext2_super_block *sb, 
uint64_t blk)
+{
+       sb->s_blocks_count_lo = PED_CPU_TO_LE32((uint32_t) blk);
+       if (EXT2_SUPER_FEATURE_INCOMPAT(*sb) & EXT4_FEATURE_INCOMPAT_64BIT)
+               sb->s_blocks_count_hi = PED_CPU_TO_LE32(blk >> 32);
+}
+
+static inline void ext2_super_free_blocks_count_set(struct ext2_super_block 
*sb, uint64_t blk)
+{
+       sb->s_free_blocks_count_lo = PED_CPU_TO_LE32((uint32_t) blk);
+       if (EXT2_SUPER_FEATURE_INCOMPAT(*sb) & EXT4_FEATURE_INCOMPAT_64BIT)
+               sb->s_free_blocks_count_hi = PED_CPU_TO_LE32(blk >> 32);
+}
+
+static inline void ext2_super_r_blocks_count_set(struct ext2_super_block *sb, 
uint64_t blk)
+{
+       sb->s_r_blocks_count_lo = PED_CPU_TO_LE32((uint32_t) blk);
+       if (EXT2_SUPER_FEATURE_INCOMPAT(*sb) & EXT4_FEATURE_INCOMPAT_64BIT)
+               sb->s_r_blocks_count_hi = PED_CPU_TO_LE32(blk >> 32);
+}
+
 #define EXT2_SUPER_FREE_INODES_COUNT(sb) \
                (PED_LE32_TO_CPU((sb).s_free_inodes_count))
 #define EXT2_SUPER_FIRST_DATA_BLOCK(sb) \
@@ -304,11 +368,6 @@
 #define EXT2_SUPER_FIRST_INO(sb)       (PED_LE32_TO_CPU((sb).s_first_ino))
 #define EXT2_SUPER_INODE_SIZE(sb)      (PED_LE16_TO_CPU((sb).s_inode_size))
 #define EXT2_SUPER_BLOCK_GROUP_NR(sb)  (PED_LE16_TO_CPU((sb).s_block_group_nr))
-#define EXT2_SUPER_FEATURE_COMPAT(sb)  (PED_LE32_TO_CPU((sb).s_feature_compat))
-#define EXT2_SUPER_FEATURE_INCOMPAT(sb) \
-               (PED_LE32_TO_CPU((sb).s_feature_incompat))
-#define EXT2_SUPER_FEATURE_RO_COMPAT(sb) \
-               (PED_LE32_TO_CPU((sb).s_feature_ro_compat))
 #define EXT2_SUPER_UUID(sb)            ((sb).s_uuid)
 #define EXT2_SUPER_VOLUME_NAME(sb)     ((sb).s_volume_name)
 #define EXT2_SUPER_LAST_MOUNTED(sb)    ((sb).s_last_mounted)
diff -urNad parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_mkfs.c 
parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_mkfs.c
--- parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_mkfs.c  2009-01-08 
13:31:49.000000000 +0000
+++ parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_mkfs.c   2009-01-08 
13:31:58.000000000 +0000
@@ -240,7 +240,7 @@
                gd[i].bg_reserved[1] = 0;
                gd[i].bg_reserved[2] = 0;
 
-               sb->s_free_blocks_count = PED_CPU_TO_LE32 (
+               ext2_super_free_blocks_count_set(sb,
                        EXT2_SUPER_FREE_BLOCKS_COUNT(*sb)
                        + EXT2_GROUP_FREE_BLOCKS_COUNT(gd[i]));
        }
@@ -424,14 +424,14 @@
        memset(sb, 0, 1024);
 
        sb->s_inodes_count = PED_CPU_TO_LE32(numgroups * inodes_per_group);
-       sb->s_blocks_count = PED_CPU_TO_LE32(numblocks);
-       sb->s_r_blocks_count = PED_CPU_TO_LE32(((uint64_t)numblocks
+       ext2_super_blocks_count_set(sb, numblocks);
+       ext2_super_r_blocks_count_set(sb, ((uint64_t)numblocks
                                * reserved_block_percentage) / 100);
 
        /* hack: this get's inc'd as we go through each group in
         * ext2_mkfs_write_meta()
         */
-       sb->s_free_blocks_count = 0;
+       ext2_super_free_blocks_count_set(sb, 0);
        sb->s_free_inodes_count = PED_CPU_TO_LE32 (numgroups
                                                        * inodes_per_group);
        sb->s_first_data_block = PED_CPU_TO_LE32(first_block);
diff -urNad parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_resize.c 
parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_resize.c
--- parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/ext2_resize.c        
2009-01-08 13:31:49.000000000 +0000
+++ parted-1.8.8.git.2008.03.24/libparted/fs/ext2/ext2_resize.c 2009-01-08 
13:31:58.000000000 +0000
@@ -104,9 +104,9 @@
        fs->sb.s_inodes_count = PED_CPU_TO_LE32(
                EXT2_SUPER_INODES_COUNT(fs->sb)
                + EXT2_SUPER_INODES_PER_GROUP(fs->sb));
-       fs->sb.s_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_blocks_count_set(&fs->sb,
                EXT2_SUPER_BLOCKS_COUNT(fs->sb) + groupsize);
-       fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_free_blocks_count_set(&fs->sb,
                EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) + groupsize - admin);
        fs->sb.s_free_inodes_count = PED_CPU_TO_LE32(
                EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
@@ -303,9 +303,9 @@
        fs->sb.s_inodes_count = PED_CPU_TO_LE32(
                EXT2_SUPER_INODES_COUNT(fs->sb)
                - EXT2_SUPER_INODES_PER_GROUP(fs->sb));
-       fs->sb.s_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_blocks_count_set(&fs->sb,
                EXT2_SUPER_BLOCKS_COUNT(fs->sb) - groupsize);
-       fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_free_blocks_count_set(&fs->sb,
                EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) - (groupsize - admin));
        fs->sb.s_free_inodes_count = PED_CPU_TO_LE32(
                EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
@@ -357,7 +357,7 @@
        for (i=gblocks;i<newsize;i++)
                ext2_set_block_state(fs, groupoff + i, 0, 1);
 
-       fs->sb.s_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_blocks_count_set(&fs->sb,
                EXT2_SUPER_BLOCKS_COUNT(fs->sb) + newsize - gblocks);
        fs->metadirty |= EXT2_META_SB;
 
@@ -432,9 +432,9 @@
        }
 
        i = gblocks - newsize;
-       fs->sb.s_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_blocks_count_set(&fs->sb,
                EXT2_SUPER_BLOCKS_COUNT(fs->sb) - i);
-       fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
+       ext2_super_free_blocks_count_set(&fs->sb,
                EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) - i);
        fs->gd[group].bg_free_blocks_count = PED_CPU_TO_LE16(
                EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[group]) - i);
@@ -684,6 +684,14 @@
                fs->metadirty |= EXT2_META_SB;
        }
 
+       if (EXT2_SUPER_FEATURE_INCOMPAT(fs->sb)
+                       & EXT3_FEATURE_INCOMPAT_EXTENTS) {
+               ped_exception_throw (
+                       PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+                       _("Parted cannot resize ext4 file systems yet."));
+               return 0;
+       }
+
        if (!ext2_determine_itoffset(fs) && ped_exception_throw (
                         PED_EXCEPTION_WARNING,
                         PED_EXCEPTION_OK_CANCEL,
diff -urNad parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/interface.c 
parted-1.8.8.git.2008.03.24/libparted/fs/ext2/interface.c
--- parted-1.8.8.git.2008.03.24~/libparted/fs/ext2/interface.c  2009-01-08 
13:31:49.000000000 +0000
+++ parted-1.8.8.git.2008.03.24/libparted/fs/ext2/interface.c   2009-01-08 
13:31:58.000000000 +0000
@@ -28,11 +28,12 @@
 
 static PedFileSystemType _ext2_type;
 static PedFileSystemType _ext3_type;
+static PedFileSystemType _ext4_type;
 
 struct ext2_dev_handle* ext2_make_dev_handle_from_parted_geometry(PedGeometry* 
geom);
 
 static PedGeometry*
-_ext2_generic_probe (PedGeometry* geom, int expect_ext3)
+_ext2_generic_probe (PedGeometry* geom, int expect_ext3, int expect_ext4)
 {
        struct ext2_super_block sb;
 
@@ -48,9 +49,13 @@
                int version = EXT2_SUPER_REV_LEVEL(sb);
                int is_ext3 = (EXT2_SUPER_FEATURE_COMPAT(sb) 
                                & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0;
+               int is_ext4 = (EXT2_SUPER_FEATURE_INCOMPAT(sb)
+                               & EXT3_FEATURE_INCOMPAT_EXTENTS) != 0;
 
                if (expect_ext3 != is_ext3)
                        return NULL;
+               if (expect_ext4 != is_ext4)
+                       return NULL;
 
                if (version > 0 && group_nr > 0) {
                        PedSector start;
@@ -64,7 +69,8 @@
                                return NULL;
                        ped_geometry_init (&probe_geom, geom->dev,
                                           start, block_count * block_size);
-                       return _ext2_generic_probe (&probe_geom, expect_ext3);
+                       return _ext2_generic_probe (&probe_geom, expect_ext3,
+                                                   expect_ext4);
                } else {
                        return ped_geometry_new (geom->dev, geom->start,
                                                 block_count * block_size);
@@ -76,13 +82,19 @@
 static PedGeometry*
 _ext2_probe (PedGeometry* geom)
 {
-       return _ext2_generic_probe (geom, 0);
+       return _ext2_generic_probe (geom, 0, 0);
 }
 
 static PedGeometry*
 _ext3_probe (PedGeometry* geom)
 {
-       return _ext2_generic_probe (geom, 1);
+       return _ext2_generic_probe (geom, 1, 0);
+}
+
+static PedGeometry*
+_ext4_probe (PedGeometry* geom)
+{
+       return _ext2_generic_probe (geom, 1, 1);
 }
 
 #ifndef DISCOVER_ONLY
@@ -323,6 +335,33 @@
 #endif /* !DISCOVER_ONLY */
 };
 
+static PedFileSystemOps _ext4_ops = {
+       probe:          _ext4_probe,
+#ifndef DISCOVER_ONLY
+       clobber:        _ext2_clobber,
+       open:           _ext2_open,
+       create:         NULL,
+       close:          _ext2_close,
+       check:          _ext2_check,
+       resize:         _ext2_resize,
+       copy:           NULL,
+       get_create_constraint:  _ext2_get_create_constraint,
+       get_copy_constraint:    NULL,
+       get_resize_constraint:  _ext2_get_resize_constraint
+#else /* !DISCOVER_ONLY */
+       clobber:        NULL,
+       open:           NULL,
+       create:         NULL,
+       close:          NULL,
+       check:          NULL,
+       resize:         NULL,
+       copy:           NULL,
+       get_create_constraint:  NULL,
+       get_copy_constraint:    NULL,
+       get_resize_constraint:  NULL
+#endif /* !DISCOVER_ONLY */
+};
+
 #define EXT23_BLOCK_SIZES ((int[6]){512, 1024, 2048, 4096, 8192, 0})
 
 static PedFileSystemType _ext2_type = {
@@ -339,14 +378,23 @@
        block_sizes:      EXT23_BLOCK_SIZES
 };
 
+static PedFileSystemType _ext4_type = {
+       next:            NULL,
+       ops:             &_ext4_ops,
+       name:            "ext4",
+       block_sizes:      EXT23_BLOCK_SIZES
+};
+
 void ped_file_system_ext2_init ()
 {
        ped_file_system_type_register (&_ext2_type);
        ped_file_system_type_register (&_ext3_type);
+       ped_file_system_type_register (&_ext4_type);
 }
 
 void ped_file_system_ext2_done ()
 {
        ped_file_system_type_unregister (&_ext2_type);
        ped_file_system_type_unregister (&_ext3_type);
+       ped_file_system_type_unregister (&_ext4_type);
 }

Reply via email to