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); }