diff --git a/src/adv.c b/src/adv.c index e26e36ef..44adf4a4 100644 --- a/src/adv.c +++ b/src/adv.c @@ -90,6 +90,7 @@ static int is_linux(const partition_t *partition) case UP_CRAMFS: case UP_EXT2: case UP_EXT3: + case UP_EXT4: case UP_JFS: case UP_RFS: case UP_RFS2: @@ -255,7 +256,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const options="tuscq"; else options="tscq"; - menuAdv[2].desc="Locate EXT2/EXT3 backup superblock"; + menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock"; menu=1; } else if(is_part_hfs(current_element->part) || is_part_hfsp(current_element->part)) @@ -280,7 +281,7 @@ void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const options="tuscq"; else options="tscq"; - menuAdv[2].desc="Locate EXT2/EXT3 backup superblock"; + menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock"; menu=1; } else if(is_hfs(current_element->part) || is_hfsp(current_element->part)) diff --git a/src/analyse.c b/src/analyse.c index 346c76f8..29228f4a 100644 --- a/src/analyse.c +++ b/src/analyse.c @@ -298,14 +298,14 @@ list_part_t *search_superblock(disk_t *disk_car, const partition_t *partition, c { wmove(stdscr,9,0); wclrtoeol(stdscr); - wprintw(stdscr,"Search EXT2/EXT3 superblock %10lu/%lu %lu%%", (long unsigned)(hd_offset/disk_car->sector_size), + wprintw(stdscr,"Search ext2/ext3/ext4 superblock %10lu/%lu %lu%%", (long unsigned)(hd_offset/disk_car->sector_size), (long unsigned)(partition->part_size/disk_car->sector_size),percent); wrefresh(stdscr); ind_stop|=check_enter_key_or_s(stdscr); old_percent=percent; } #endif - /* EXT2/EXT3 */ + /* ext2/ext3/ext4 */ if( hd_offset==(EXT2_MIN_BLOCK_SIZE<<0) || hd_offset==(EXT2_MIN_BLOCK_SIZE<<1) || hd_offset==(EXT2_MIN_BLOCK_SIZE<<2) || diff --git a/src/common.h b/src/common.h index f7295979..65d080af 100644 --- a/src/common.h +++ b/src/common.h @@ -212,7 +212,7 @@ struct efi_guid_s #define TESTDISK_O_READAHEAD_32K 010 #define TESTDISK_O_ALL 020 -enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXTENDED, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4}; +enum upart_type { UP_UNK, UP_BEOS, UP_CRAMFS, UP_EXT2, UP_EXT3, UP_EXT4, UP_EXTENDED, UP_FAT12, UP_FAT16, UP_FAT32, UP_FATX, UP_FREEBSD, UP_HFS, UP_HFSP, UP_HFSX, UP_HPFS, UP_JFS, UP_LINSWAP, UP_LINSWAP2, UP_LUKS, UP_LVM, UP_LVM2, UP_MD, UP_MD1, UP_NETWARE, UP_NTFS, UP_OPENBSD, UP_OS2MB, UP_RFS, UP_RFS2, UP_RFS3, UP_RFS4, UP_SUN, UP_SYSV4, UP_UFS, UP_UFS2, UP_XFS, UP_XFS2, UP_XFS3, UP_XFS4}; typedef enum upart_type upart_type_t; enum status_type { STATUS_DELETED, STATUS_PRIM, STATUS_PRIM_BOOT, STATUS_LOG, STATUS_EXT, STATUS_EXT_IN_EXT}; typedef enum status_type status_type_t; diff --git a/src/dirpart.c b/src/dirpart.c index 3bdc14b2..ed15b4c0 100644 --- a/src/dirpart.c +++ b/src/dirpart.c @@ -83,6 +83,7 @@ int dir_partition(disk_t *disk_car, const partition_t *partition, const int verb case UP_FAT32: res=dir_partition_fat_init(disk_car,partition,&dir_data,verbose); break; + case UP_EXT4: case UP_EXT3: case UP_EXT2: res=dir_partition_ext2_init(disk_car,partition,&dir_data,verbose); diff --git a/src/ext2.c b/src/ext2.c index 08e67685..96b84713 100644 --- a/src/ext2.c +++ b/src/ext2.c @@ -2,7 +2,7 @@ File: ext2.c - Copyright (C) 1998-2007 Christophe GRENIER + Copyright (C) 1998-2008 Christophe GRENIER This software is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -61,10 +61,18 @@ static int set_EXT2_info(disk_t *disk_car, const struct ext2_super_block *sb,par { set_part_name(partition,sb->s_volume_name,16); /* sb->s_last_mounted seems to be unemployed in kernel 2.2.16 */ - if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0) + if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_GDT_CSUM)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_DIR_NLINK)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)!=0 || + EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_64BIT)!=0 || + EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_MMP)!=0) + strncpy(partition->info,"EXT4",sizeof(partition->info)); + else if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0) strncpy(partition->info,"EXT3",sizeof(partition->info)); else strncpy(partition->info,"EXT2",sizeof(partition->info)); + if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_LARGE_FILE)!=0) strcat(partition->info," Large file"); if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)!=0) @@ -174,7 +182,14 @@ static int test_EXT2(disk_t *disk_car, const struct ext2_super_block *sb,partiti if(partition->part_size!=0 && partition->part_size<(uint64_t)le32(sb->s_blocks_count)*(EXT2_MIN_BLOCK_SIZE<s_log_block_size))) return 8; - if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0) + if(EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_GDT_CSUM)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_DIR_NLINK)!=0 || + EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)!=0 || + EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_64BIT)!=0 || + EXT2_HAS_INCOMPAT_FEATURE(sb,EXT4_FEATURE_INCOMPAT_MMP)!=0) + partition->upart_type=UP_EXT4; + else if(EXT2_HAS_COMPAT_FEATURE(sb,EXT3_FEATURE_COMPAT_HAS_JOURNAL)!=0) partition->upart_type=UP_EXT3; else partition->upart_type=UP_EXT2; diff --git a/src/ext2.h b/src/ext2.h index 5b67a0a7..d5db2e81 100644 --- a/src/ext2.h +++ b/src/ext2.h @@ -63,18 +63,27 @@ #define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 #define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +#define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040 #define EXT2_FEATURE_COMPAT_ANY 0xffffffff #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +//#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 #define EXT2_FEATURE_RO_COMPAT_ANY 0xffffffff #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 +#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 #define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff /* diff --git a/src/ext2grp.c b/src/ext2grp.c index c3daa785..5af5a220 100644 --- a/src/ext2grp.c +++ b/src/ext2grp.c @@ -47,10 +47,11 @@ unsigned int ext2_fix_group(alloc_data_t *list_search_space, disk_t *disk, parti unsigned char *buffer; unsigned int blocksize; if(partition->upart_type!=UP_EXT2 && - partition->upart_type!=UP_EXT3) + partition->upart_type!=UP_EXT3 && + partition->upart_type!=UP_EXT4) { - log_error("Not a valid ext2/ext3 filesystem"); - display_message("Not a valid ext2/ext3 filesystem"); + log_error("Not a valid ext2/ext3/ext4 filesystem"); + display_message("Not a valid ext2/ext3/ext4 filesystem"); free_search_space(list_search_space); return 0; } @@ -84,10 +85,11 @@ unsigned int ext2_fix_inode(alloc_data_t *list_search_space, disk_t *disk, parti unsigned char *buffer; unsigned int blocksize; if(partition->upart_type!=UP_EXT2 && - partition->upart_type!=UP_EXT3) + partition->upart_type!=UP_EXT3 && + partition->upart_type!=UP_EXT4) { - log_error("Not a valid ext2/ext3 filesystem"); - display_message("Not a valid ext2/ext3 filesystem"); + log_error("Not a valid ext2/ext3/ext4 filesystem"); + display_message("Not a valid ext2/ext3/ext4 filesystem"); free_search_space(list_search_space); return 0; } diff --git a/src/file_ext.c b/src/file_ext.c index ac01c3b0..77dca3f8 100644 --- a/src/file_ext.c +++ b/src/file_ext.c @@ -37,7 +37,7 @@ static int header_check_ext2_sb(const unsigned char *buffer, const unsigned int const file_hint_t file_hint_ext2_sb= { .extension="", - .description="EXT2/EXT3 Superblock", + .description="ext2/ext3/ext4 Superblock", .min_header_distance=0, .max_filesize=1, .recover=0, diff --git a/src/intrface.c b/src/intrface.c index 1979b7ff..1c9405db 100644 --- a/src/intrface.c +++ b/src/intrface.c @@ -1121,6 +1121,7 @@ static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_par { case UP_EXT2: case UP_EXT3: + case UP_EXT4: case UP_RFS: case UP_RFS2: case UP_RFS3: diff --git a/src/partnone.c b/src/partnone.c index 8d971be1..a5bb2751 100644 --- a/src/partnone.c +++ b/src/partnone.c @@ -79,6 +79,7 @@ static const struct systypes none_sys_types[] = { {UP_CRAMFS, "CramFS"}, {UP_EXT2, "ext2"}, {UP_EXT3, "ext3"}, + {UP_EXT4, "ext4"}, /* {UP_EXTENDED, "Extended"}, */ {UP_FAT12, "FAT12"}, {UP_FAT16, "FAT16"}, @@ -253,6 +254,7 @@ static int check_part_none(disk_t *disk_car,const int verbose,partition_t *parti break; case UP_EXT2: case UP_EXT3: + case UP_EXT4: ret=check_EXT2(disk_car,partition,verbose); break; case UP_EXTENDED: diff --git a/src/photorec.c b/src/photorec.c index a7624f01..25a67a9c 100644 --- a/src/photorec.c +++ b/src/photorec.c @@ -611,7 +611,7 @@ unsigned int remove_used_space(disk_t *disk_car, const partition_t *partition, a return ntfs_remove_used_space(disk_car, partition, list_search_space); #endif #ifdef HAVE_LIBEXT2FS - else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3) + else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3 || partition->upart_type==UP_EXT4) return ext2_remove_used_space(disk_car, partition, list_search_space); #endif return 0; diff --git a/src/phrecn.c b/src/phrecn.c index 01b4ab0f..a4e6efd8 100644 --- a/src/phrecn.c +++ b/src/phrecn.c @@ -260,7 +260,7 @@ static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, u { static const struct MenuItem menuMode[]= { - {'E',"EXT2/EXT3","EXT2/EXT3 filesystem"}, + {'E',"ext2/ext3","ext2/ext3/ext4 filesystem"}, {'O',"Other","FAT/NTFS/HFS+/ReiserFS/..."}, {0,NULL,NULL} }; @@ -297,7 +297,8 @@ static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, u unsigned int menu; int command; if(partition->upart_type==UP_EXT2 || - partition->upart_type==UP_EXT3) + partition->upart_type==UP_EXT3 || + partition->upart_type==UP_EXT4) menu=0; else menu=1; @@ -314,7 +315,7 @@ static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, u *mode_ext2=(command=='E' || command=='e'); if(*mode_ext2>0) { - log_info("EXT2/EXT3 mode activated.\n"); + log_info("ext2/ext3/ext4 mode activated.\n"); } /* if((*mode_ext2)!=0) @@ -340,7 +341,7 @@ static int ask_mode_ext2(const disk_t *disk_car, const partition_t *partition, u options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL); #endif #ifdef HAVE_LIBEXT2FS - else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3) + else if(partition->upart_type==UP_EXT2 || partition->upart_type==UP_EXT3 || partition->upart_type==UP_EXT4) command = wmenuSelect_ext(window, 24, 8, 0, menuEXT2, 11, options, MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu,NULL); #endif