wok rev 20223

grub: add ext4 patch
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Mar 01 10:11:27 2018 +0100 (2018-03-01)
parents ccdba9b27403
children 90f9ce95a98e
files grub/receipt grub/stuff/ext3_256byte_inode+ext4.diff grub/stuff/ext3_256byte_inode.diff
line diff
     1.1 --- a/grub/receipt	Mon Feb 26 19:03:16 2018 +0100
     1.2 +++ b/grub/receipt	Thu Mar 01 10:11:27 2018 +0100
     1.3 @@ -16,7 +16,6 @@
     1.4  # Rules to configure and make the package.
     1.5  compile_rules()
     1.6  {
     1.7 -	cd $src
     1.8  	for i in $stuff/*.diff ; do
     1.9  		[ -f $(basename $i) ] && continue
    1.10  		patch -p1 < $i
    1.11 @@ -46,4 +45,3 @@
    1.12  	# Example config file (menu.lst).
    1.13  	cp $stuff/example-menu.lst $fs/boot/grub
    1.14  }
    1.15 -
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/grub/stuff/ext3_256byte_inode+ext4.diff	Thu Mar 01 10:11:27 2018 +0100
     2.3 @@ -0,0 +1,935 @@
     2.4 +--- grub-0.97/stage2/fsys_ext2fs.c
     2.5 ++++ grub-0.97/stage2/fsys_ext2fs.c
     2.6 +@@ -17,6 +17,19 @@
     2.7 +  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     2.8 +  */
     2.9 + 
    2.10 ++/*
    2.11 ++ * The patch about "ext3 with 256-byte inode size" was made by
    2.12 ++ * Stefan Lippers-Hollmann <s.L-H@gmx.de> for Debian in 2008-01-30.
    2.13 ++ * Thank Barton for submittal of this patch.
    2.14 ++ * 						---- Tinybit, 2008-06-24
    2.15 ++ */
    2.16 ++
    2.17 ++/*
    2.18 ++ * The ext4 patch comes from Gentoo.
    2.19 ++ * Thank kraml for direction to this patch.
    2.20 ++ * 						---- Tinybit, 2009-02-11
    2.21 ++ */
    2.22 ++
    2.23 + #ifdef FSYS_EXT2FS
    2.24 + 
    2.25 + #include "shared.h"
    2.26 +@@ -41,6 +54,7 @@
    2.27 + typedef unsigned short __u16;
    2.28 + typedef __signed__ int __s32;
    2.29 + typedef unsigned int __u32;
    2.30 ++typedef unsigned long long __u64;
    2.31 + 
    2.32 + /*
    2.33 +  * Constants relative to the data blocks, from ext2_fs.h
    2.34 +@@ -61,9 +75,9 @@
    2.35 +     __u32 s_free_inodes_count;	/* Free inodes count */
    2.36 +     __u32 s_first_data_block;	/* First Data Block */
    2.37 +     __u32 s_log_block_size;	/* Block size */
    2.38 +-    __s32 s_log_frag_size;	/* Fragment size */
    2.39 ++    __s32 s_obso_log_frag_size;	/* Obsoleted Fragment size */
    2.40 +     __u32 s_blocks_per_group;	/* # Blocks per group */
    2.41 +-    __u32 s_frags_per_group;	/* # Fragments per group */
    2.42 ++    __u32 s_obso_frags_per_group;	/* Obsoleted Fragments per group */
    2.43 +     __u32 s_inodes_per_group;	/* # Inodes per group */
    2.44 +     __u32 s_mtime;		/* Mount time */
    2.45 +     __u32 s_wtime;		/* Write time */
    2.46 +@@ -72,13 +86,14 @@
    2.47 +     __u16 s_magic;		/* Magic signature */
    2.48 +     __u16 s_state;		/* File system state */
    2.49 +     __u16 s_errors;		/* Behaviour when detecting errors */
    2.50 +-    __u16 s_pad;
    2.51 ++    __u16 s_minor_rev_level;	/* minor revision level */
    2.52 +     __u32 s_lastcheck;		/* time of last check */
    2.53 +     __u32 s_checkinterval;	/* max. time between checks */
    2.54 +     __u32 s_creator_os;		/* OS */
    2.55 +     __u32 s_rev_level;		/* Revision level */
    2.56 +     __u16 s_def_resuid;		/* Default uid for reserved blocks */
    2.57 +     __u16 s_def_resgid;		/* Default gid for reserved blocks */
    2.58 ++    //__u32 s_reserved[235];	/* Padding to the end of the block */
    2.59 +     /*
    2.60 +      * These fields are for EXT2_DYNAMIC_REV superblocks only.
    2.61 +      *
    2.62 +@@ -98,16 +113,16 @@
    2.63 +     __u32 s_feature_compat;	/* compatible feature set */
    2.64 +     __u32 s_feature_incompat;	/* incompatible feature set */
    2.65 +     __u32 s_feature_ro_compat;	/* readonly-compatible feature set */
    2.66 +-    __u8  s_uuid[16];		/* 128-bit uuid for volume */
    2.67 +-    char  s_volume_name[16];	/* volume name */
    2.68 +-    char  s_last_mounted[64];	/* directory where last mounted */
    2.69 +-    __u32 s_algorithm_usage_bitmap; /* For compression */
    2.70 ++    __u8 s_uuid[16];		/* 128-bit uuid for volume */
    2.71 ++    char s_volume_name[16];	/* volume name */
    2.72 ++    char s_last_mounted[64];	/* directory where last mounted */
    2.73 ++    __u32 s_algorithm_usage_bitmap;	/* For compression */
    2.74 +     /*
    2.75 +-     * Performance hints.  Directory preallocation should only
    2.76 ++     * Performance hints. Directory preallocation should only
    2.77 +      * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
    2.78 +      */
    2.79 +-    __u8  s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
    2.80 +-    __u8  s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
    2.81 ++    __u8 s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
    2.82 ++    __u8 s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
    2.83 +     __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
    2.84 +     /*
    2.85 +      * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
    2.86 +@@ -117,17 +132,17 @@
    2.87 +     __u32 s_journal_dev;	/* device number of journal file */
    2.88 +     __u32 s_last_orphan;	/* start of list of inodes to delete */
    2.89 +     __u32 s_hash_seed[4];	/* HTREE hash seed */
    2.90 +-    __u8  s_def_hash_version;	/* Default hash version to use */
    2.91 +-    __u8  s_jnl_backup_type; 	/* Default type of journal backup */
    2.92 +-    __u16 s_reserved_word_pad;
    2.93 ++    __u8 s_def_hash_version;	/* Default hash version to use */
    2.94 ++    __u8 s_jnl_backup_type;	/* Default type of journal backup */
    2.95 ++    __u16 s_desc_size;		/* size of group descriptor */
    2.96 +     __u32 s_default_mount_opts;
    2.97 +     __u32 s_first_meta_bg;	/* First metablock group */
    2.98 +     __u32 s_mkfs_time;		/* When the filesystem was created */
    2.99 +-    __u32 s_jnl_blocks[17]; 	/* Backup of the journal inode */
   2.100 ++    __u32 s_jnl_blocks[17];	/* Backup of the journal inode */
   2.101 +     __u32 s_reserved[172];	/* Padding to the end of the block */
   2.102 +   };
   2.103 + 
   2.104 +-struct ext2_group_desc
   2.105 ++struct ext4_group_desc
   2.106 +   {
   2.107 +     __u32 bg_block_bitmap;	/* Blocks bitmap block */
   2.108 +     __u32 bg_inode_bitmap;	/* Inodes bitmap block */
   2.109 +@@ -135,8 +150,18 @@
   2.110 +     __u16 bg_free_blocks_count;	/* Free blocks count */
   2.111 +     __u16 bg_free_inodes_count;	/* Free inodes count */
   2.112 +     __u16 bg_used_dirs_count;	/* Directories count */
   2.113 +-    __u16 bg_pad;
   2.114 +-    __u32 bg_reserved[3];
   2.115 ++    __u16 bg_flags;		/* EXT4_BG_flags (INODE_UNINIT, etc) */
   2.116 ++    __u32 bg_reserved[2];		/* Likely block/inode bitmap checksum */
   2.117 ++    __u16 bg_itable_unused;	/* Unused inodes count */
   2.118 ++    __u16 bg_checksum;		/* crc16(sb_uuid+group+desc) */
   2.119 ++    __u32 bg_block_bitmap_hi;	/* Blocks bitmap block MSB */
   2.120 ++    __u32 bg_inode_bitmap_hi;	/* Inodes bitmap block MSB */
   2.121 ++    __u32 bg_inode_table_hi;	/* Inodes table block MSB */
   2.122 ++    __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */
   2.123 ++    __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
   2.124 ++    __u16 bg_used_dirs_count_hi;	/* Directories count MSB */
   2.125 ++    __u16 bg_itable_unused_hi;	/* Unused inodes count MSB */
   2.126 ++    __u32 bg_reserved2[3];
   2.127 +   };
   2.128 + 
   2.129 + struct ext2_inode
   2.130 +@@ -174,22 +199,22 @@
   2.131 +     __u32 i_block[EXT2_N_BLOCKS];	/* 40: Pointers to blocks */
   2.132 +     __u32 i_version;		/* File version (for NFS) */
   2.133 +     __u32 i_file_acl;		/* File ACL */
   2.134 +-    __u32 i_dir_acl;		/* Directory ACL */
   2.135 +-    __u32 i_faddr;		/* Fragment address */
   2.136 ++    __u32 i_size_high;
   2.137 ++    __u32 i_obso_faddr;		/* Obsoleted fragment address */
   2.138 +     union
   2.139 +       {
   2.140 + 	struct
   2.141 + 	  {
   2.142 +-	    __u8 l_i_frag;	/* Fragment number */
   2.143 +-	    __u8 l_i_fsize;	/* Fragment size */
   2.144 +-	    __u16 i_pad1;
   2.145 +-	    __u32 l_i_reserved2[2];
   2.146 ++		__u16	l_i_blocks_high; /* were l_i_reserved1 */
   2.147 ++		__u16	l_i_file_acl_high;
   2.148 ++		__u16	l_i_uid_high;	/* these 2 fields */
   2.149 ++		__u16	l_i_gid_high;	/* were reserved2[0] */
   2.150 ++		__u32	l_i_reserved2;
   2.151 + 	  }
   2.152 + 	linux2;
   2.153 + 	struct
   2.154 + 	  {
   2.155 +-	    __u8 h_i_frag;	/* Fragment number */
   2.156 +-	    __u8 h_i_fsize;	/* Fragment size */
   2.157 ++		__u16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
   2.158 + 	    __u16 h_i_mode_high;
   2.159 + 	    __u16 h_i_uid_high;
   2.160 + 	    __u16 h_i_gid_high;
   2.161 +@@ -198,16 +223,36 @@
   2.162 + 	hurd2;
   2.163 + 	struct
   2.164 + 	  {
   2.165 +-	    __u8 m_i_frag;	/* Fragment number */
   2.166 +-	    __u8 m_i_fsize;	/* Fragment size */
   2.167 +-	    __u16 m_pad1;
   2.168 ++		__u16	h_i_reserved1;	/* Obsoleted fragment number/size which are removed in ext4 */
   2.169 ++		__u16	m_i_file_acl_high;
   2.170 + 	    __u32 m_i_reserved2[2];
   2.171 + 	  }
   2.172 + 	masix2;
   2.173 +       }
   2.174 +     osd2;			/* OS dependent 2 */
   2.175 ++	__u16	i_extra_isize;
   2.176 ++	__u16	i_pad1;
   2.177 ++	__u32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
   2.178 ++	__u32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
   2.179 ++	__u32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
   2.180 ++	__u32  i_crtime;       /* File Creation time */
   2.181 ++	__u32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
   2.182 ++	__u32  i_version_hi;	/* high 32 bits for 64-bit version */
   2.183 +   };
   2.184 + 
   2.185 ++#define EXT4_FEATURE_INCOMPAT_EXTENTS		0x0040 /* extents support */
   2.186 ++#define EXT4_FEATURE_INCOMPAT_64BIT			0x0080 /* grub not supported*/
   2.187 ++#define EXT4_FEATURE_INCOMPAT_MMP           0x0100
   2.188 ++#define EXT4_FEATURE_INCOMPAT_FLEX_BG		0x0200
   2.189 ++
   2.190 ++#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask)			\
   2.191 ++	( sb->s_feature_incompat & mask )
   2.192 ++
   2.193 ++#define EXT4_EXTENTS_FL		0x00080000 /* Inode uses extents */
   2.194 ++#define EXT4_HUGE_FILE_FL	0x00040000 /* Set to each huge file */
   2.195 ++
   2.196 ++#define EXT4_MIN_DESC_SIZE			32
   2.197 ++
   2.198 + /* linux/limits.h */
   2.199 + #define NAME_MAX         255	/* # chars in a file name */
   2.200 + 
   2.201 +@@ -225,6 +270,57 @@
   2.202 +     char name[EXT2_NAME_LEN];	/* File name */
   2.203 +   };
   2.204 + 
   2.205 ++/* linux/ext4_fs_extents.h */ 
   2.206 ++/* This is the extent on-disk structure.
   2.207 ++ * It's used at the bottom of the tree.
   2.208 ++ */
   2.209 ++struct ext4_extent 
   2.210 ++  {
   2.211 ++	__u32  ee_block;   /* first logical block extent covers */
   2.212 ++	__u16  ee_len;     /* number of blocks covered by extent */
   2.213 ++	__u16  ee_start_hi;    /* high 16 bits of physical block */
   2.214 ++	__u32  ee_start_lo;    /* low 32 bits of physical block */
   2.215 ++  };
   2.216 ++
   2.217 ++/*
   2.218 ++ * This is index on-disk structure.
   2.219 ++ * It's used at all the levels except the bottom.
   2.220 ++ */
   2.221 ++struct ext4_extent_idx 
   2.222 ++  {
   2.223 ++    __u32  ei_block;   /* index covers logical blocks from 'block' */
   2.224 ++    __u32  ei_leaf_lo; /* pointer to the physical block of the next *
   2.225 ++	                     * level. leaf or next index could be there */
   2.226 ++    __u16  ei_leaf_hi; /* high 16 bits of physical block */
   2.227 ++    __u16  ei_unused;
   2.228 ++  };
   2.229 ++
   2.230 ++/*
   2.231 ++ * Each block (leaves and indexes), even inode-stored has header.
   2.232 ++ */
   2.233 ++struct ext4_extent_header 
   2.234 ++  {
   2.235 ++    __u16  eh_magic;   /* probably will support different formats */
   2.236 ++    __u16  eh_entries; /* number of valid entries */
   2.237 ++    __u16  eh_max;     /* capacity of store in entries */
   2.238 ++    __u16  eh_depth;   /* has tree real underlying blocks? */
   2.239 ++    __u32  eh_generation;  /* generation of the tree */
   2.240 ++  };
   2.241 ++
   2.242 ++#define EXT4_EXT_MAGIC      (0xf30a)
   2.243 ++#define EXT_FIRST_EXTENT(__hdr__) \
   2.244 ++    ((struct ext4_extent *) (((char *) (__hdr__)) +     \
   2.245 ++                 sizeof(struct ext4_extent_header)))
   2.246 ++#define EXT_FIRST_INDEX(__hdr__) \
   2.247 ++    ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
   2.248 ++                 sizeof(struct ext4_extent_header)))
   2.249 ++#define EXT_LAST_EXTENT(__hdr__) \
   2.250 ++    (EXT_FIRST_EXTENT((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
   2.251 ++#define EXT_LAST_INDEX(__hdr__) \
   2.252 ++    (EXT_FIRST_INDEX((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
   2.253 ++
   2.254 ++
   2.255 ++
   2.256 + /* linux/ext2fs.h */
   2.257 + /*
   2.258 +  * EXT2_DIR_PAD defines the directory entries boundaries
   2.259 +@@ -238,7 +334,7 @@
   2.260 + 
   2.261 + 
   2.262 + /* ext2/super.c */
   2.263 +-#define log2(n) ffz(~(n))
   2.264 ++//#define log2(n) ffz(~(n))
   2.265 + 
   2.266 + #define EXT2_SUPER_MAGIC      0xEF53	/* include/linux/ext2_fs.h */
   2.267 + #define EXT2_ROOT_INO              2	/* include/linux/ext2_fs.h */
   2.268 +@@ -247,11 +343,12 @@
   2.269 + 
   2.270 + /* made up, these are pointers into FSYS_BUF */
   2.271 + /* read once, always stays there: */
   2.272 ++#define NAME_BUF ((char *)(FSYS_BUF))	/* 512 bytes */
   2.273 + #define SUPERBLOCK \
   2.274 +-    ((struct ext2_super_block *)(FSYS_BUF))
   2.275 ++    ((struct ext2_super_block *)((FSYS_BUF)+512))	/* 1024 bytes */
   2.276 + #define GROUP_DESC \
   2.277 +     ((struct ext2_group_desc *) \
   2.278 +-     ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))
   2.279 ++     ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))	/* 32 bytes */
   2.280 + #define INODE \
   2.281 +     ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK)))
   2.282 + #define DATABLOCK1 \
   2.283 +@@ -261,14 +358,19 @@
   2.284 + 
   2.285 + /* linux/ext2_fs.h */
   2.286 + #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
   2.287 +-#define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))
   2.288 ++#define EXT2_ADDR_PER_BLOCK_BITS(s)	(log2_tmp(EXT2_ADDR_PER_BLOCK(s)))
   2.289 + 
   2.290 ++/* Revision levels */
   2.291 + #define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
   2.292 + #define EXT2_DYNAMIC_REV	1	/* V2 format w/ dynamic inode sizes */
   2.293 +-#define EXT2_GOOD_OLD_INODE_SIZE 128
   2.294 +-#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
   2.295 +-				EXT2_GOOD_OLD_INODE_SIZE : \
   2.296 +-				(s)->s_inode_size)
   2.297 ++
   2.298 ++#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
   2.299 ++#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
   2.300 ++
   2.301 ++#define EXT2_GOOD_OLD_INODE_SIZE	128
   2.302 ++
   2.303 ++#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
   2.304 ++//#define EXT2_INODE_SIZE(s)		(SUPERBLOCK->s_inode_size)
   2.305 + #define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
   2.306 + 
   2.307 + /* linux/ext2_fs.h */
   2.308 +@@ -276,8 +378,17 @@
   2.309 + /* kind of from ext2/super.c */
   2.310 + #define EXT2_BLOCK_SIZE(s)	(1 << EXT2_BLOCK_SIZE_BITS(s))
   2.311 + /* linux/ext2fs.h */
   2.312 ++/* sizeof(struct ext2_group_desc) is changed in ext4 
   2.313 ++ * in kernel code, ext2/3 uses sizeof(struct ext2_group_desc) to calculate 
   2.314 ++ * number of desc per block, while ext4 uses superblock->s_desc_size in stead
   2.315 ++ * superblock->s_desc_size is not available in ext2/3
   2.316 ++ * */
   2.317 ++#define EXT2_DESC_SIZE(s) \
   2.318 ++	(EXT4_HAS_INCOMPAT_FEATURE(s,EXT4_FEATURE_INCOMPAT_64BIT)? \
   2.319 ++	s->s_desc_size : EXT4_MIN_DESC_SIZE)
   2.320 + #define EXT2_DESC_PER_BLOCK(s) \
   2.321 +-     (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
   2.322 ++	(EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
   2.323 ++
   2.324 + /* linux/stat.h */
   2.325 + #define S_IFMT  00170000
   2.326 + #define S_IFLNK  0120000
   2.327 +@@ -287,38 +398,82 @@
   2.328 + #define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
   2.329 + #define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
   2.330 + 
   2.331 ++#ifndef GRUB_UTIL
   2.332 ++static char *linkbuf = (char *)(FSYS_BUF - PATH_MAX);	/* buffer for following symbolic links */
   2.333 ++#else
   2.334 ++static char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
   2.335 ++#endif
   2.336 ++
   2.337 + /* include/asm-i386/bitops.h */
   2.338 + /*
   2.339 +  * ffz = Find First Zero in word. Undefined if no zero exists,
   2.340 +  * so code should check against ~0UL first..
   2.341 +  */
   2.342 +-static __inline__ unsigned long
   2.343 +-ffz (unsigned long word)
   2.344 +-{
   2.345 +-  __asm__ ("bsfl %1,%0"
   2.346 +-:	   "=r" (word)
   2.347 +-:	   "r" (~word));
   2.348 +-  return word;
   2.349 +-}
   2.350 ++//static __inline__ unsigned long
   2.351 ++//ffz (unsigned long word)
   2.352 ++//{
   2.353 ++//  __asm__ ("bsfl %1,%0"
   2.354 ++//:	   "=r" (word)
   2.355 ++//:	   "r" (~word));
   2.356 ++//  return word;
   2.357 ++//}
   2.358 + 
   2.359 + /* check filesystem types and read superblock into memory buffer */
   2.360 + int
   2.361 + ext2fs_mount (void)
   2.362 + {
   2.363 +-  int retval = 1;
   2.364 ++//  if (((current_drive & 0x80) || (current_slice != 0))
   2.365 ++//       && (current_slice != PC_SLICE_TYPE_EXT2FS)
   2.366 ++//       && (current_slice != PC_SLICE_TYPE_LINUX_RAID)
   2.367 ++//       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
   2.368 ++//       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
   2.369 ++//      return 0;
   2.370 ++      
   2.371 ++  if ((unsigned long)part_length < (SBLOCK + (sizeof(struct ext2_super_block) / DEV_BSIZE)))
   2.372 ++      return 0;
   2.373 + 
   2.374 +-  if ((((current_drive & 0x80) || (current_slice != 0))
   2.375 +-       && (current_slice != PC_SLICE_TYPE_EXT2FS)
   2.376 +-       && (current_slice != PC_SLICE_TYPE_LINUX_RAID)
   2.377 +-       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
   2.378 +-       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
   2.379 +-      || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE))
   2.380 +-      || !devread (SBLOCK, 0, sizeof (struct ext2_super_block),
   2.381 +-		   (char *) SUPERBLOCK)
   2.382 +-      || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
   2.383 +-      retval = 0;
   2.384 ++  if (!devread(SBLOCK, 0, sizeof(struct ext2_super_block), (char *)SUPERBLOCK, 0xedde0d90))
   2.385 ++      return 0;
   2.386 + 
   2.387 +-  return retval;
   2.388 ++  if (SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
   2.389 ++      return 0;
   2.390 ++
   2.391 ++  if (SUPERBLOCK->s_inodes_count == 0)
   2.392 ++      return 0;
   2.393 ++
   2.394 ++  if (SUPERBLOCK->s_blocks_count == 0)
   2.395 ++      return 0;
   2.396 ++
   2.397 ++  if (SUPERBLOCK->s_blocks_per_group == 0)
   2.398 ++      return 0;
   2.399 ++
   2.400 ++  if (SUPERBLOCK->s_inodes_per_group == 0)
   2.401 ++      return 0;
   2.402 ++
   2.403 ++  if (SUPERBLOCK->s_first_data_block > 1) /* 1 for 1K block, 0 otherwise */
   2.404 ++      return 0;
   2.405 ++
   2.406 ++  if (SUPERBLOCK->s_log_block_size > 4)	/* max size of block is 16K. 0 for 1K */
   2.407 ++      return 0;
   2.408 ++
   2.409 ++  if (SUPERBLOCK->s_first_data_block)
   2.410 ++  {
   2.411 ++	if (SUPERBLOCK->s_log_block_size)
   2.412 ++		return 0;
   2.413 ++  } else {
   2.414 ++	if (SUPERBLOCK->s_log_block_size == 0)
   2.415 ++		return 0;
   2.416 ++  }
   2.417 ++
   2.418 ++  if (SUPERBLOCK->s_rev_level)
   2.419 ++  {
   2.420 ++	if (SUPERBLOCK->s_inode_size == 0)
   2.421 ++		return 0;
   2.422 ++	if (EXT2_BLOCK_SIZE(SUPERBLOCK) % (SUPERBLOCK->s_inode_size))
   2.423 ++		return 0;
   2.424 ++  }
   2.425 ++
   2.426 ++  return 1;
   2.427 + }
   2.428 + 
   2.429 + /* Takes a file system block number and reads it into BUFFER. */
   2.430 +@@ -329,7 +484,7 @@
   2.431 +   printf ("fsblock %d buffer %d\n", fsblock, buffer);
   2.432 + #endif /* E2DEBUG */
   2.433 +   return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0,
   2.434 +-		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
   2.435 ++		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer, 0xedde0d90);
   2.436 + }
   2.437 + 
   2.438 + /* from
   2.439 +@@ -338,7 +493,7 @@
   2.440 + /* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into
   2.441 +    a physical block (the location in the file system) via an inode. */
   2.442 + static int
   2.443 +-ext2fs_block_map (int logical_block)
   2.444 ++ext2fs_block_map (unsigned long logical_block)
   2.445 + {
   2.446 + 
   2.447 + #ifdef E2DEBUG
   2.448 +@@ -412,13 +567,16 @@
   2.449 +   /* else */
   2.450 +   mapblock2 = -1;
   2.451 +   logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
   2.452 ++  
   2.453 +   if (mapblock1 != 3
   2.454 +       && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
   2.455 +     {
   2.456 +       errnum = ERR_FSYS_CORRUPT;
   2.457 +       return -1;
   2.458 +     }
   2.459 ++  
   2.460 +   mapblock1 = 3;
   2.461 ++  
   2.462 +   if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
   2.463 + 		   [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
   2.464 + 				      * 2)],
   2.465 +@@ -427,7 +585,8 @@
   2.466 +       errnum = ERR_FSYS_CORRUPT;
   2.467 +       return -1;
   2.468 +     }
   2.469 +-  if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
   2.470 ++  
   2.471 ++  if (! ext2_rdfsb (((__u32 *) DATABLOCK2)
   2.472 + 		   [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
   2.473 + 		    & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
   2.474 + 		   DATABLOCK2))
   2.475 +@@ -435,30 +594,148 @@
   2.476 +       errnum = ERR_FSYS_CORRUPT;
   2.477 +       return -1;
   2.478 +     }
   2.479 +-  return ((__u32 *) DATABLOCK2)
   2.480 +-    [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
   2.481 ++  
   2.482 ++  return ((__u32 *) DATABLOCK2)[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
   2.483 + }
   2.484 + 
   2.485 ++/* extent binary search index
   2.486 ++ * find closest index in the current level extent tree
   2.487 ++ * kind of from ext4_ext_binsearch_idx in ext4/extents.c
   2.488 ++ */
   2.489 ++static struct ext4_extent_idx*
   2.490 ++ext4_ext_binsearch_idx(struct ext4_extent_header* eh, int logical_block)
   2.491 ++{
   2.492 ++  struct ext4_extent_idx *r, *l, *m;
   2.493 ++  l = EXT_FIRST_INDEX(eh) + 1;
   2.494 ++  r = EXT_LAST_INDEX(eh);
   2.495 ++  while (l <= r) 
   2.496 ++    {
   2.497 ++	  m = l + (r - l) / 2;
   2.498 ++	  if (logical_block < m->ei_block)
   2.499 ++		  r = m - 1;
   2.500 ++	  else
   2.501 ++		  l = m + 1;
   2.502 ++	}
   2.503 ++  return (struct ext4_extent_idx*)(l - 1);
   2.504 ++}
   2.505 ++
   2.506 ++/* extent binary search 
   2.507 ++ * find closest extent in the leaf level 
   2.508 ++ * kind of from ext4_ext_binsearch in ext4/extents.c
   2.509 ++ */
   2.510 ++static struct ext4_extent*
   2.511 ++ext4_ext_binsearch(struct ext4_extent_header* eh, int logical_block)
   2.512 ++{
   2.513 ++  struct ext4_extent *r, *l, *m;
   2.514 ++  l = EXT_FIRST_EXTENT(eh) + 1;
   2.515 ++  r = EXT_LAST_EXTENT(eh);
   2.516 ++  while (l <= r) 
   2.517 ++    {
   2.518 ++	  m = l + (r - l) / 2;
   2.519 ++	  if (logical_block < m->ee_block)
   2.520 ++		  r = m - 1;
   2.521 ++	  else
   2.522 ++		  l = m + 1;
   2.523 ++	}
   2.524 ++  return (struct ext4_extent*)(l - 1);
   2.525 ++}
   2.526 ++
   2.527 ++/* Maps extents enabled logical block into physical block via an inode. 
   2.528 ++ * EXT4_HUGE_FILE_FL should be checked before calling this.
   2.529 ++ */
   2.530 ++static int
   2.531 ++ext4fs_block_map (int logical_block)
   2.532 ++{
   2.533 ++  struct ext4_extent_header *eh;
   2.534 ++  struct ext4_extent *ex;//, *extent;
   2.535 ++  struct ext4_extent_idx *ei;//, *index;
   2.536 ++  int depth;
   2.537 ++  //int i;
   2.538 ++
   2.539 ++#ifdef E2DEBUG
   2.540 ++  unsigned char *i;
   2.541 ++  for (i = (unsigned char *) INODE;
   2.542 ++       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
   2.543 ++       i++)
   2.544 ++    {
   2.545 ++      printf ("%c", "0123456789abcdef"[*i >> 4]);
   2.546 ++      printf ("%c", "0123456789abcdef"[*i % 16]);
   2.547 ++      if (!((i + 1 - (unsigned char *) INODE) % 16))
   2.548 ++	{
   2.549 ++	  printf ("\n");
   2.550 ++	}
   2.551 ++      else
   2.552 ++	{
   2.553 ++	  printf (" ");
   2.554 ++	}
   2.555 ++    }
   2.556 ++  printf ("logical block %d\n", logical_block);
   2.557 ++#endif /* E2DEBUG */
   2.558 ++  eh = (struct ext4_extent_header*)INODE->i_block;
   2.559 ++  if (eh->eh_magic != EXT4_EXT_MAGIC)
   2.560 ++  {
   2.561 ++          errnum = ERR_FSYS_CORRUPT;
   2.562 ++          return -1;
   2.563 ++  }
   2.564 ++  while((depth = eh->eh_depth) != 0)
   2.565 ++  	{ /* extent index */
   2.566 ++	  if (eh->eh_magic != EXT4_EXT_MAGIC)
   2.567 ++	  {
   2.568 ++	          errnum = ERR_FSYS_CORRUPT;
   2.569 ++		  return -1;
   2.570 ++	  }
   2.571 ++	  ei = ext4_ext_binsearch_idx(eh, logical_block);
   2.572 ++	  if (ei->ei_leaf_hi)
   2.573 ++	{/* 64bit physical block number not supported */
   2.574 ++	  errnum = ERR_FILELENGTH;
   2.575 ++	  return -1;
   2.576 ++	}
   2.577 ++	  if (!ext2_rdfsb(ei->ei_leaf_lo, DATABLOCK1))
   2.578 ++	{
   2.579 ++	  errnum = ERR_FSYS_CORRUPT;
   2.580 ++	  return -1;
   2.581 ++	}
   2.582 ++	  eh = (struct ext4_extent_header*)DATABLOCK1;
   2.583 ++  	}
   2.584 ++
   2.585 ++  /* depth==0, we come to the leaf */
   2.586 ++  ex = ext4_ext_binsearch(eh, logical_block);
   2.587 ++  if (ex->ee_start_hi) 
   2.588 ++	{/* 64bit physical block number not supported */
   2.589 ++	  errnum = ERR_FILELENGTH;
   2.590 ++	  return -1;
   2.591 ++	}
   2.592 ++  if ((ex->ee_block + ex->ee_len) < logical_block)
   2.593 ++	{
   2.594 ++	  errnum = ERR_FSYS_CORRUPT;
   2.595 ++	  return -1;
   2.596 ++	}
   2.597 ++  return ex->ee_start_lo + logical_block - ex->ee_block;
   2.598 ++
   2.599 ++}
   2.600 ++
   2.601 + /* preconditions: all preconds of ext2fs_block_map */
   2.602 +-int
   2.603 +-ext2fs_read (char *buf, int len)
   2.604 ++unsigned long
   2.605 ++ext2fs_read (char *buf, unsigned long len, unsigned long write)
   2.606 + {
   2.607 +-  int logical_block;
   2.608 +-  int offset;
   2.609 ++  unsigned long logical_block;
   2.610 ++  unsigned long offset;
   2.611 ++  unsigned long ret = 0;
   2.612 ++  unsigned long size = 0;
   2.613 +   int map;
   2.614 +-  int ret = 0;
   2.615 +-  int size = 0;
   2.616 + 
   2.617 + #ifdef E2DEBUG
   2.618 +   static char hexdigit[] = "0123456789abcdef";
   2.619 +   unsigned char *i;
   2.620 ++  
   2.621 +   for (i = (unsigned char *) INODE;
   2.622 +        i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
   2.623 +        i++)
   2.624 +     {
   2.625 +       printf ("%c", hexdigit[*i >> 4]);
   2.626 +       printf ("%c", hexdigit[*i % 16]);
   2.627 +-      if (!((i + 1 - (unsigned char *) INODE) % 16))
   2.628 ++      
   2.629 ++      if (! ((i + 1 - (unsigned char *) INODE) % 16))
   2.630 + 	{
   2.631 + 	  printf ("\n");
   2.632 + 	}
   2.633 +@@ -469,41 +746,53 @@
   2.634 +     }
   2.635 + #endif /* E2DEBUG */
   2.636 +   while (len > 0)
   2.637 +-    {
   2.638 ++  {
   2.639 +       /* find the (logical) block component of our location */
   2.640 +       logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
   2.641 +       offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
   2.642 ++
   2.643 ++      /* map extents enabled logical block number to physical fs on-dick block number */
   2.644 ++      if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) 
   2.645 ++		&& INODE->i_flags & EXT4_EXTENTS_FL)
   2.646 ++	map = ext4fs_block_map (logical_block);
   2.647 ++      else
   2.648 +       map = ext2fs_block_map (logical_block);
   2.649 ++
   2.650 + #ifdef E2DEBUG
   2.651 +       printf ("map=%d\n", map);
   2.652 + #endif /* E2DEBUG */
   2.653 ++      
   2.654 +       if (map < 0)
   2.655 +-	break;
   2.656 ++	  break;
   2.657 + 
   2.658 +       size = EXT2_BLOCK_SIZE (SUPERBLOCK);
   2.659 +       size -= offset;
   2.660 ++      
   2.661 +       if (size > len)
   2.662 +-	size = len;
   2.663 ++	  size = len;
   2.664 + 
   2.665 +-      if (map == 0) {
   2.666 +-        memset ((char *) buf, 0, size);
   2.667 ++      if (map == 0)
   2.668 ++      {
   2.669 ++	  if (buf)
   2.670 ++		memset ((char *) buf, 0, size);
   2.671 +       } else {
   2.672 +-        disk_read_func = disk_read_hook;
   2.673 ++          disk_read_func = disk_read_hook;
   2.674 + 
   2.675 +-        devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
   2.676 +-	         offset, size, buf);
   2.677 ++          devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
   2.678 ++		 offset, size, buf, write);
   2.679 + 
   2.680 +-        disk_read_func = NULL;
   2.681 ++          disk_read_func = NULL;
   2.682 +       }
   2.683 + 
   2.684 +-      buf += size;
   2.685 +-      len -= size;
   2.686 ++      if (buf)
   2.687 ++	buf += size;
   2.688 ++      len -= size;	/* len always >= 0 */
   2.689 +       filepos += size;
   2.690 +       ret += size;
   2.691 +-    }
   2.692 ++  }
   2.693 + 
   2.694 +   if (errnum)
   2.695 +-    ret = 0;
   2.696 ++      ret = 0;
   2.697 + 
   2.698 +   return ret;
   2.699 + }
   2.700 +@@ -557,10 +846,10 @@
   2.701 +   int desc;			/* index within that group */
   2.702 +   int ino_blk;			/* fs pointer of the inode's information */
   2.703 +   int str_chk = 0;		/* used to hold the results of a string compare */
   2.704 +-  struct ext2_group_desc *gdp;
   2.705 ++  struct ext4_group_desc *ext4_gdp;
   2.706 +   struct ext2_inode *raw_inode;	/* inode info corresponding to current_ino */
   2.707 + 
   2.708 +-  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
   2.709 ++//char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
   2.710 +   int link_count = 0;
   2.711 + 
   2.712 +   char *rest;
   2.713 +@@ -590,7 +879,7 @@
   2.714 + 
   2.715 +       /* look up an inode */
   2.716 +       group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);
   2.717 +-      group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
   2.718 ++      group_desc = group_id >> log2_tmp (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
   2.719 +       desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1);
   2.720 + #ifdef E2DEBUG
   2.721 +       printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group,
   2.722 +@@ -603,10 +892,17 @@
   2.723 + 	{
   2.724 + 	  return 0;
   2.725 + 	}
   2.726 +-      gdp = GROUP_DESC;
   2.727 +-      ino_blk = gdp[desc].bg_inode_table +
   2.728 ++	  ext4_gdp = (struct ext4_group_desc *)( (__u8*)GROUP_DESC + 
   2.729 ++			  		desc * EXT2_DESC_SIZE(SUPERBLOCK));
   2.730 ++	  if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK, EXT4_FEATURE_INCOMPAT_64BIT)
   2.731 ++		&& (! ext4_gdp->bg_inode_table_hi))
   2.732 ++	{/* 64bit itable not supported */
   2.733 ++	  errnum = ERR_FILELENGTH;
   2.734 ++	  return -1;
   2.735 ++	}
   2.736 ++      ino_blk = ext4_gdp->bg_inode_table + 
   2.737 + 	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
   2.738 +-	 >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
   2.739 ++	 >> log2_tmp (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
   2.740 + #ifdef E2DEBUG
   2.741 +       printf ("inode table fsblock=%d\n", ino_blk);
   2.742 + #endif /* E2DEBUG */
   2.743 +@@ -620,10 +916,10 @@
   2.744 + 
   2.745 +       raw_inode = (struct ext2_inode *)((char *)INODE +
   2.746 + 	((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
   2.747 +-	EXT2_INODE_SIZE (SUPERBLOCK));
   2.748 ++	 EXT2_INODE_SIZE (SUPERBLOCK));
   2.749 + #ifdef E2DEBUG
   2.750 +       printf ("ipb=%d, sizeof(inode)=%d\n",
   2.751 +-	      EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
   2.752 ++	     EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
   2.753 +       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
   2.754 +       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
   2.755 +       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
   2.756 +@@ -661,13 +957,22 @@
   2.757 + 	    }
   2.758 + 
   2.759 + 	  /* Find out how long our remaining name is. */
   2.760 +-	  len = 0;
   2.761 +-	  while (dirname[len] && !isspace (dirname[len]))
   2.762 +-	    len++;
   2.763 ++	  //len = 0;
   2.764 ++	  //while (dirname[len] && !isspace (dirname[len]))
   2.765 ++	  //  len++;
   2.766 ++	  for (len = 0; (ch = dirname[len]) && !isspace (ch); len++)
   2.767 ++	  {
   2.768 ++		if (ch == '\\')
   2.769 ++		{
   2.770 ++			len++;
   2.771 ++			if (! (ch = dirname[len]))
   2.772 ++				break;
   2.773 ++		}
   2.774 ++	  }
   2.775 + 
   2.776 + 	  /* Get the symlink size. */
   2.777 + 	  filemax = (INODE->i_size);
   2.778 +-	  if (filemax + len > sizeof (linkbuf) - 2)
   2.779 ++	  if (filemax + len > PATH_MAX - 2)
   2.780 + 	    {
   2.781 + 	      errnum = ERR_FILELENGTH;
   2.782 + 	      return 0;
   2.783 +@@ -681,18 +986,23 @@
   2.784 + 	    }
   2.785 + 	  linkbuf[filemax + len] = '\0';
   2.786 + 
   2.787 +-	  /* Read the symlink data. */
   2.788 ++	  /* Read the symlink data. 
   2.789 ++	   * Slow symlink is extents enabled
   2.790 ++	   * But since grub_read invokes ext2fs_read, nothing to change here
   2.791 ++	   * */
   2.792 + 	  if (! ext2_is_fast_symlink ())
   2.793 + 	    {
   2.794 + 	      /* Read the necessary blocks, and reset the file pointer. */
   2.795 +-	      len = grub_read (linkbuf, filemax);
   2.796 ++	      len = grub_read (linkbuf, filemax, 0xedde0d90);
   2.797 + 	      filepos = 0;
   2.798 + 	      if (!len)
   2.799 + 		return 0;
   2.800 + 	    }
   2.801 + 	  else
   2.802 + 	    {
   2.803 +-	      /* Copy the data directly from the inode. */
   2.804 ++	      /* Copy the data directly from the inode. 
   2.805 ++		   * Fast symlink is not extents enabled
   2.806 ++		   * */
   2.807 + 	      len = filemax;
   2.808 + 	      memmove (linkbuf, (char *) INODE->i_block, len);
   2.809 + 	    }
   2.810 +@@ -726,6 +1036,13 @@
   2.811 + 	      errnum = ERR_BAD_FILETYPE;
   2.812 + 	      return 0;
   2.813 + 	    }
   2.814 ++	  /* if file is too large, just stop and report an error*/
   2.815 ++	  if ( (INODE->i_flags & EXT4_HUGE_FILE_FL) && !(INODE->i_size_high))
   2.816 ++	    {
   2.817 ++		  /* file too large, stop reading */
   2.818 ++		  errnum = ERR_FILELENGTH;
   2.819 ++		  return 0;
   2.820 ++	    }
   2.821 + 
   2.822 + 	  filemax = (INODE->i_size);
   2.823 + 	  return 1;
   2.824 +@@ -746,8 +1063,17 @@
   2.825 + 	}
   2.826 + 
   2.827 +       /* skip to next slash or end of filename (space) */
   2.828 +-      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
   2.829 +-	   rest++);
   2.830 ++//      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
   2.831 ++//	   rest++);
   2.832 ++      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++)
   2.833 ++      {
   2.834 ++	if (ch == '\\')
   2.835 ++	{
   2.836 ++		rest++;
   2.837 ++		if (! (ch = *rest))
   2.838 ++			break;
   2.839 ++	}
   2.840 ++      }
   2.841 + 
   2.842 +       /* look through this directory and find the next filename component */
   2.843 +       /* invariant: rest points to slash after the next filename component */
   2.844 +@@ -765,32 +1091,45 @@
   2.845 + 	     give up */
   2.846 + 	  if (loc >= INODE->i_size)
   2.847 + 	    {
   2.848 ++# ifndef STAGE1_5
   2.849 + 	      if (print_possibilities < 0)
   2.850 + 		{
   2.851 + # if 0
   2.852 + 		  putchar ('\n');
   2.853 + # endif
   2.854 ++		  return 1;
   2.855 + 		}
   2.856 +-	      else
   2.857 +-		{
   2.858 +-		  errnum = ERR_FILE_NOT_FOUND;
   2.859 +-		  *rest = ch;
   2.860 +-		}
   2.861 +-	      return (print_possibilities < 0);
   2.862 ++# endif /* STAGE1_5 */
   2.863 ++	      
   2.864 ++	      errnum = ERR_FILE_NOT_FOUND;
   2.865 ++	      *rest = ch;
   2.866 ++
   2.867 ++	      return 0;
   2.868 + 	    }
   2.869 + 
   2.870 + 	  /* else, find the (logical) block component of our location */
   2.871 ++	  /* ext4 logical block number the same as ext2/3 */
   2.872 + 	  blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
   2.873 + 
   2.874 + 	  /* we know which logical block of the directory entry we are looking
   2.875 + 	     for, now we have to translate that to the physical (fs) block on
   2.876 + 	     the disk */
   2.877 ++	  /* map extents enabled logical block number to physical fs on-dick block number */
   2.878 ++	  if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) 
   2.879 ++                        && INODE->i_flags & EXT4_EXTENTS_FL)
   2.880 ++              map = ext4fs_block_map (blk);
   2.881 ++	  else
   2.882 + 	  map = ext2fs_block_map (blk);
   2.883 + #ifdef E2DEBUG
   2.884 + 	  printf ("fs block=%d\n", map);
   2.885 + #endif /* E2DEBUG */
   2.886 + 	  mapblock2 = -1;
   2.887 +-	  if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))
   2.888 ++	  if (map < 0) 
   2.889 ++	  {
   2.890 ++	      *rest = ch;
   2.891 ++	      return 0;
   2.892 ++	  }
   2.893 ++          if (!ext2_rdfsb (map, DATABLOCK2))
   2.894 + 	    {
   2.895 + 	      errnum = ERR_FSYS_CORRUPT;
   2.896 + 	      *rest = ch;
   2.897 +@@ -811,22 +1150,36 @@
   2.898 + 
   2.899 + 	  if (dp->inode)
   2.900 + 	    {
   2.901 +-	      int saved_c = dp->name[dp->name_len];
   2.902 ++	      //int saved_c = dp->name[dp->name_len];
   2.903 ++	      int j, k;
   2.904 ++	      char ch1;
   2.905 ++	      char *tmp_name= NAME_BUF;	/* EXT2_NAME_LEN is 255, so 512 byte buffer is needed. */
   2.906 + 
   2.907 +-	      dp->name[dp->name_len] = 0;
   2.908 +-	      str_chk = substring (dirname, dp->name);
   2.909 ++	      /* copy dp->name to tmp_name, and quote the spaces with a '\\' */
   2.910 ++	      for (j = 0, k = 0; j < dp->name_len; j++)
   2.911 ++	      {
   2.912 ++		if (! (ch1 = dp->name[j]))
   2.913 ++			break;
   2.914 ++		if (ch1 == ' ')
   2.915 ++			tmp_name[k++] = '\\';
   2.916 ++		tmp_name[k++] = ch1;
   2.917 ++	      }
   2.918 ++	      tmp_name[k] = 0;
   2.919 + 
   2.920 ++	      //dp->name[dp->name_len] = 0;
   2.921 ++	      str_chk = substring (dirname, tmp_name, 0);
   2.922 ++
   2.923 + # ifndef STAGE1_5
   2.924 + 	      if (print_possibilities && ch != '/'
   2.925 + 		  && (!*dirname || str_chk <= 0))
   2.926 + 		{
   2.927 + 		  if (print_possibilities > 0)
   2.928 + 		    print_possibilities = -print_possibilities;
   2.929 +-		  print_a_completion (dp->name);
   2.930 ++		  print_a_completion (tmp_name);
   2.931 + 		}
   2.932 + # endif
   2.933 + 
   2.934 +-	      dp->name[dp->name_len] = saved_c;
   2.935 ++	      //dp->name[dp->name_len] = saved_c;
   2.936 + 	    }
   2.937 + 
   2.938 + 	}
     3.1 --- a/grub/stuff/ext3_256byte_inode.diff	Mon Feb 26 19:03:16 2018 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,102 +0,0 @@
     3.4 -
     3.5 -Patch from Red Hat. See #463236, #463123 (and #491076 for the reviewed version)
     3.6 -
     3.7 -diff -ur grub-0.97/stage2/fsys_ext2fs.c grub-0.97.new/stage2/fsys_ext2fs.c
     3.8 ---- grub-0.97/stage2/fsys_ext2fs.c	2008-07-23 01:18:18.000000000 +0200
     3.9 -+++ grub-0.97.new/stage2/fsys_ext2fs.c	2008-07-25 14:33:29.000000000 +0200
    3.10 -@@ -79,7 +79,52 @@
    3.11 -     __u32 s_rev_level;		/* Revision level */
    3.12 -     __u16 s_def_resuid;		/* Default uid for reserved blocks */
    3.13 -     __u16 s_def_resgid;		/* Default gid for reserved blocks */
    3.14 --    __u32 s_reserved[235];	/* Padding to the end of the block */
    3.15 -+    /*
    3.16 -+     * These fields are for EXT2_DYNAMIC_REV superblocks only.
    3.17 -+     *
    3.18 -+     * Note: the difference between the compatible feature set and
    3.19 -+     * the incompatible feature set is that if there is a bit set
    3.20 -+     * in the incompatible feature set that the kernel doesn't
    3.21 -+     * know about, it should refuse to mount the filesystem.
    3.22 -+     *
    3.23 -+     * e2fsck's requirements are more strict; if it doesn't know
    3.24 -+     * about a feature in either the compatible or incompatible
    3.25 -+     * feature set, it must abort and not try to meddle with
    3.26 -+     * things it doesn't understand...
    3.27 -+     */
    3.28 -+    __u32 s_first_ino;		/* First non-reserved inode */
    3.29 -+    __u16 s_inode_size;		/* size of inode structure */
    3.30 -+    __u16 s_block_group_nr;	/* block group # of this superblock */
    3.31 -+    __u32 s_feature_compat;	/* compatible feature set */
    3.32 -+    __u32 s_feature_incompat;	/* incompatible feature set */
    3.33 -+    __u32 s_feature_ro_compat;	/* readonly-compatible feature set */
    3.34 -+    __u8  s_uuid[16];		/* 128-bit uuid for volume */
    3.35 -+    char  s_volume_name[16];	/* volume name */
    3.36 -+    char  s_last_mounted[64];	/* directory where last mounted */
    3.37 -+    __u32 s_algorithm_usage_bitmap; /* For compression */
    3.38 -+    /*
    3.39 -+     * Performance hints.  Directory preallocation should only
    3.40 -+     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
    3.41 -+     */
    3.42 -+    __u8  s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
    3.43 -+    __u8  s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
    3.44 -+    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
    3.45 -+    /*
    3.46 -+     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
    3.47 -+     */
    3.48 -+    __u8 s_journal_uuid[16];	/* uuid of journal superblock */
    3.49 -+    __u32 s_journal_inum;	/* inode number of journal file */
    3.50 -+    __u32 s_journal_dev;	/* device number of journal file */
    3.51 -+    __u32 s_last_orphan;	/* start of list of inodes to delete */
    3.52 -+    __u32 s_hash_seed[4];	/* HTREE hash seed */
    3.53 -+    __u8  s_def_hash_version;	/* Default hash version to use */
    3.54 -+    __u8  s_jnl_backup_type; 	/* Default type of journal backup */
    3.55 -+    __u16 s_reserved_word_pad;
    3.56 -+    __u32 s_default_mount_opts;
    3.57 -+    __u32 s_first_meta_bg;	/* First metablock group */
    3.58 -+    __u32 s_mkfs_time;		/* When the filesystem was created */
    3.59 -+    __u32 s_jnl_blocks[17]; 	/* Backup of the journal inode */
    3.60 -+    __u32 s_reserved[172];	/* Padding to the end of the block */
    3.61 -   };
    3.62 - 
    3.63 - struct ext2_group_desc
    3.64 -@@ -218,6 +263,14 @@
    3.65 - #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
    3.66 - #define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))
    3.67 - 
    3.68 -+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
    3.69 -+#define EXT2_DYNAMIC_REV	1	/* V2 format w/ dynamic inode sizes */
    3.70 -+#define EXT2_GOOD_OLD_INODE_SIZE 128
    3.71 -+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
    3.72 -+				EXT2_GOOD_OLD_INODE_SIZE : \
    3.73 -+				(s)->s_inode_size)
    3.74 -+#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
    3.75 -+
    3.76 - /* linux/ext2_fs.h */
    3.77 - #define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
    3.78 - /* kind of from ext2/super.c */
    3.79 -@@ -553,7 +606,7 @@
    3.80 -       gdp = GROUP_DESC;
    3.81 -       ino_blk = gdp[desc].bg_inode_table +
    3.82 - 	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
    3.83 --	 >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
    3.84 -+	 >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
    3.85 - #ifdef E2DEBUG
    3.86 -       printf ("inode table fsblock=%d\n", ino_blk);
    3.87 - #endif /* E2DEBUG */
    3.88 -@@ -565,13 +618,12 @@
    3.89 -       /* reset indirect blocks! */
    3.90 -       mapblock2 = mapblock1 = -1;
    3.91 - 
    3.92 --      raw_inode = INODE +
    3.93 --	((current_ino - 1)
    3.94 --	 & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
    3.95 -+      raw_inode = (struct ext2_inode *)((char *)INODE +
    3.96 -+	((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
    3.97 -+	EXT2_INODE_SIZE (SUPERBLOCK));
    3.98 - #ifdef E2DEBUG
    3.99 -       printf ("ipb=%d, sizeof(inode)=%d\n",
   3.100 --	      (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
   3.101 --	      sizeof (struct ext2_inode));
   3.102 -+	      EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
   3.103 -       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
   3.104 -       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
   3.105 -       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;