wok annotate grub/stuff/ext3_256byte_inode+ext4.diff @ rev 20257

Add giflossy
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Mar 13 23:27:32 2018 +0100 (2018-03-13)
parents b4680310d62a
children
rev   line source
pascal@20223 1 --- grub-0.97/stage2/fsys_ext2fs.c
pascal@20223 2 +++ grub-0.97/stage2/fsys_ext2fs.c
pascal@20223 3 @@ -17,6 +17,19 @@
pascal@20223 4 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
pascal@20223 5 */
pascal@20223 6
pascal@20223 7 +/*
pascal@20223 8 + * The patch about "ext3 with 256-byte inode size" was made by
pascal@20223 9 + * Stefan Lippers-Hollmann <s.L-H@gmx.de> for Debian in 2008-01-30.
pascal@20223 10 + * Thank Barton for submittal of this patch.
pascal@20223 11 + * ---- Tinybit, 2008-06-24
pascal@20223 12 + */
pascal@20223 13 +
pascal@20223 14 +/*
pascal@20223 15 + * The ext4 patch comes from Gentoo.
pascal@20223 16 + * Thank kraml for direction to this patch.
pascal@20223 17 + * ---- Tinybit, 2009-02-11
pascal@20223 18 + */
pascal@20223 19 +
pascal@20223 20 #ifdef FSYS_EXT2FS
pascal@20223 21
pascal@20223 22 #include "shared.h"
pascal@20223 23 @@ -41,6 +54,7 @@
pascal@20223 24 typedef unsigned short __u16;
pascal@20223 25 typedef __signed__ int __s32;
pascal@20223 26 typedef unsigned int __u32;
pascal@20223 27 +typedef unsigned long long __u64;
pascal@20223 28
pascal@20223 29 /*
pascal@20223 30 * Constants relative to the data blocks, from ext2_fs.h
pascal@20223 31 @@ -61,9 +75,9 @@
pascal@20223 32 __u32 s_free_inodes_count; /* Free inodes count */
pascal@20223 33 __u32 s_first_data_block; /* First Data Block */
pascal@20223 34 __u32 s_log_block_size; /* Block size */
pascal@20223 35 - __s32 s_log_frag_size; /* Fragment size */
pascal@20223 36 + __s32 s_obso_log_frag_size; /* Obsoleted Fragment size */
pascal@20223 37 __u32 s_blocks_per_group; /* # Blocks per group */
pascal@20223 38 - __u32 s_frags_per_group; /* # Fragments per group */
pascal@20223 39 + __u32 s_obso_frags_per_group; /* Obsoleted Fragments per group */
pascal@20223 40 __u32 s_inodes_per_group; /* # Inodes per group */
pascal@20223 41 __u32 s_mtime; /* Mount time */
pascal@20223 42 __u32 s_wtime; /* Write time */
pascal@20224 43 @@ -72,17 +86,63 @@
pascal@20223 44 __u16 s_magic; /* Magic signature */
pascal@20223 45 __u16 s_state; /* File system state */
pascal@20223 46 __u16 s_errors; /* Behaviour when detecting errors */
pascal@20223 47 - __u16 s_pad;
pascal@20223 48 + __u16 s_minor_rev_level; /* minor revision level */
pascal@20223 49 __u32 s_lastcheck; /* time of last check */
pascal@20223 50 __u32 s_checkinterval; /* max. time between checks */
pascal@20223 51 __u32 s_creator_os; /* OS */
pascal@20223 52 __u32 s_rev_level; /* Revision level */
pascal@20223 53 __u16 s_def_resuid; /* Default uid for reserved blocks */
pascal@20223 54 __u16 s_def_resgid; /* Default gid for reserved blocks */
pascal@20224 55 - __u32 s_reserved[235]; /* Padding to the end of the block */
pascal@20223 56 + //__u32 s_reserved[235]; /* Padding to the end of the block */
pascal@20224 57 + /*
pascal@20224 58 + * These fields are for EXT2_DYNAMIC_REV superblocks only.
pascal@20224 59 + *
pascal@20224 60 + * Note: the difference between the compatible feature set and
pascal@20224 61 + * the incompatible feature set is that if there is a bit set
pascal@20224 62 + * in the incompatible feature set that the kernel doesn't
pascal@20224 63 + * know about, it should refuse to mount the filesystem.
pascal@20224 64 + *
pascal@20224 65 + * e2fsck's requirements are more strict; if it doesn't know
pascal@20224 66 + * about a feature in either the compatible or incompatible
pascal@20224 67 + * feature set, it must abort and not try to meddle with
pascal@20224 68 + * things it doesn't understand...
pascal@20224 69 + */
pascal@20224 70 + __u32 s_first_ino; /* First non-reserved inode */
pascal@20224 71 + __u16 s_inode_size; /* size of inode structure */
pascal@20224 72 + __u16 s_block_group_nr; /* block group # of this superblock */
pascal@20224 73 + __u32 s_feature_compat; /* compatible feature set */
pascal@20224 74 + __u32 s_feature_incompat; /* incompatible feature set */
pascal@20224 75 + __u32 s_feature_ro_compat; /* readonly-compatible feature set */
pascal@20223 76 + __u8 s_uuid[16]; /* 128-bit uuid for volume */
pascal@20223 77 + char s_volume_name[16]; /* volume name */
pascal@20223 78 + char s_last_mounted[64]; /* directory where last mounted */
pascal@20223 79 + __u32 s_algorithm_usage_bitmap; /* For compression */
pascal@20224 80 + /*
pascal@20223 81 + * Performance hints. Directory preallocation should only
pascal@20224 82 + * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
pascal@20224 83 + */
pascal@20223 84 + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
pascal@20223 85 + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
pascal@20224 86 + __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
pascal@20224 87 + /*
pascal@20224 88 + * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
pascal@20224 89 + */
pascal@20224 90 + __u8 s_journal_uuid[16]; /* uuid of journal superblock */
pascal@20224 91 + __u32 s_journal_inum; /* inode number of journal file */
pascal@20224 92 + __u32 s_journal_dev; /* device number of journal file */
pascal@20224 93 + __u32 s_last_orphan; /* start of list of inodes to delete */
pascal@20224 94 + __u32 s_hash_seed[4]; /* HTREE hash seed */
pascal@20223 95 + __u8 s_def_hash_version; /* Default hash version to use */
pascal@20223 96 + __u8 s_jnl_backup_type; /* Default type of journal backup */
pascal@20223 97 + __u16 s_desc_size; /* size of group descriptor */
pascal@20224 98 + __u32 s_default_mount_opts;
pascal@20224 99 + __u32 s_first_meta_bg; /* First metablock group */
pascal@20224 100 + __u32 s_mkfs_time; /* When the filesystem was created */
pascal@20223 101 + __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
pascal@20224 102 + __u32 s_reserved[172]; /* Padding to the end of the block */
pascal@20223 103 };
pascal@20223 104
pascal@20223 105 -struct ext2_group_desc
pascal@20223 106 +struct ext4_group_desc
pascal@20223 107 {
pascal@20223 108 __u32 bg_block_bitmap; /* Blocks bitmap block */
pascal@20223 109 __u32 bg_inode_bitmap; /* Inodes bitmap block */
pascal@20224 110 @@ -90,8 +150,18 @@
pascal@20223 111 __u16 bg_free_blocks_count; /* Free blocks count */
pascal@20223 112 __u16 bg_free_inodes_count; /* Free inodes count */
pascal@20223 113 __u16 bg_used_dirs_count; /* Directories count */
pascal@20223 114 - __u16 bg_pad;
pascal@20223 115 - __u32 bg_reserved[3];
pascal@20223 116 + __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
pascal@20223 117 + __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
pascal@20223 118 + __u16 bg_itable_unused; /* Unused inodes count */
pascal@20223 119 + __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */
pascal@20223 120 + __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
pascal@20223 121 + __u32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
pascal@20223 122 + __u32 bg_inode_table_hi; /* Inodes table block MSB */
pascal@20223 123 + __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */
pascal@20223 124 + __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
pascal@20223 125 + __u16 bg_used_dirs_count_hi; /* Directories count MSB */
pascal@20223 126 + __u16 bg_itable_unused_hi; /* Unused inodes count MSB */
pascal@20223 127 + __u32 bg_reserved2[3];
pascal@20223 128 };
pascal@20223 129
pascal@20223 130 struct ext2_inode
pascal@20224 131 @@ -129,22 +199,22 @@
pascal@20223 132 __u32 i_block[EXT2_N_BLOCKS]; /* 40: Pointers to blocks */
pascal@20223 133 __u32 i_version; /* File version (for NFS) */
pascal@20223 134 __u32 i_file_acl; /* File ACL */
pascal@20223 135 - __u32 i_dir_acl; /* Directory ACL */
pascal@20223 136 - __u32 i_faddr; /* Fragment address */
pascal@20223 137 + __u32 i_size_high;
pascal@20223 138 + __u32 i_obso_faddr; /* Obsoleted fragment address */
pascal@20223 139 union
pascal@20223 140 {
pascal@20223 141 struct
pascal@20223 142 {
pascal@20223 143 - __u8 l_i_frag; /* Fragment number */
pascal@20223 144 - __u8 l_i_fsize; /* Fragment size */
pascal@20223 145 - __u16 i_pad1;
pascal@20223 146 - __u32 l_i_reserved2[2];
pascal@20223 147 + __u16 l_i_blocks_high; /* were l_i_reserved1 */
pascal@20223 148 + __u16 l_i_file_acl_high;
pascal@20223 149 + __u16 l_i_uid_high; /* these 2 fields */
pascal@20223 150 + __u16 l_i_gid_high; /* were reserved2[0] */
pascal@20223 151 + __u32 l_i_reserved2;
pascal@20223 152 }
pascal@20223 153 linux2;
pascal@20223 154 struct
pascal@20223 155 {
pascal@20223 156 - __u8 h_i_frag; /* Fragment number */
pascal@20223 157 - __u8 h_i_fsize; /* Fragment size */
pascal@20223 158 + __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
pascal@20223 159 __u16 h_i_mode_high;
pascal@20223 160 __u16 h_i_uid_high;
pascal@20223 161 __u16 h_i_gid_high;
pascal@20224 162 @@ -153,16 +223,36 @@
pascal@20223 163 hurd2;
pascal@20223 164 struct
pascal@20223 165 {
pascal@20223 166 - __u8 m_i_frag; /* Fragment number */
pascal@20223 167 - __u8 m_i_fsize; /* Fragment size */
pascal@20223 168 - __u16 m_pad1;
pascal@20223 169 + __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
pascal@20223 170 + __u16 m_i_file_acl_high;
pascal@20223 171 __u32 m_i_reserved2[2];
pascal@20223 172 }
pascal@20223 173 masix2;
pascal@20223 174 }
pascal@20223 175 osd2; /* OS dependent 2 */
pascal@20223 176 + __u16 i_extra_isize;
pascal@20223 177 + __u16 i_pad1;
pascal@20223 178 + __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
pascal@20223 179 + __u32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
pascal@20223 180 + __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
pascal@20223 181 + __u32 i_crtime; /* File Creation time */
pascal@20223 182 + __u32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
pascal@20223 183 + __u32 i_version_hi; /* high 32 bits for 64-bit version */
pascal@20223 184 };
pascal@20223 185
pascal@20223 186 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */
pascal@20223 187 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 /* grub not supported*/
pascal@20223 188 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
pascal@20223 189 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
pascal@20223 190 +
pascal@20223 191 +#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask) \
pascal@20223 192 + ( sb->s_feature_incompat & mask )
pascal@20223 193 +
pascal@20223 194 +#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
pascal@20223 195 +#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
pascal@20223 196 +
pascal@20223 197 +#define EXT4_MIN_DESC_SIZE 32
pascal@20223 198 +
pascal@20223 199 /* linux/limits.h */
pascal@20223 200 #define NAME_MAX 255 /* # chars in a file name */
pascal@20223 201
pascal@20224 202 @@ -180,6 +270,57 @@
pascal@20223 203 char name[EXT2_NAME_LEN]; /* File name */
pascal@20223 204 };
pascal@20223 205
pascal@20223 206 +/* linux/ext4_fs_extents.h */
pascal@20223 207 +/* This is the extent on-disk structure.
pascal@20223 208 + * It's used at the bottom of the tree.
pascal@20223 209 + */
pascal@20223 210 +struct ext4_extent
pascal@20223 211 + {
pascal@20223 212 + __u32 ee_block; /* first logical block extent covers */
pascal@20223 213 + __u16 ee_len; /* number of blocks covered by extent */
pascal@20223 214 + __u16 ee_start_hi; /* high 16 bits of physical block */
pascal@20223 215 + __u32 ee_start_lo; /* low 32 bits of physical block */
pascal@20223 216 + };
pascal@20223 217 +
pascal@20223 218 +/*
pascal@20223 219 + * This is index on-disk structure.
pascal@20223 220 + * It's used at all the levels except the bottom.
pascal@20223 221 + */
pascal@20223 222 +struct ext4_extent_idx
pascal@20223 223 + {
pascal@20223 224 + __u32 ei_block; /* index covers logical blocks from 'block' */
pascal@20223 225 + __u32 ei_leaf_lo; /* pointer to the physical block of the next *
pascal@20223 226 + * level. leaf or next index could be there */
pascal@20223 227 + __u16 ei_leaf_hi; /* high 16 bits of physical block */
pascal@20223 228 + __u16 ei_unused;
pascal@20223 229 + };
pascal@20223 230 +
pascal@20223 231 +/*
pascal@20223 232 + * Each block (leaves and indexes), even inode-stored has header.
pascal@20223 233 + */
pascal@20223 234 +struct ext4_extent_header
pascal@20223 235 + {
pascal@20223 236 + __u16 eh_magic; /* probably will support different formats */
pascal@20223 237 + __u16 eh_entries; /* number of valid entries */
pascal@20223 238 + __u16 eh_max; /* capacity of store in entries */
pascal@20223 239 + __u16 eh_depth; /* has tree real underlying blocks? */
pascal@20223 240 + __u32 eh_generation; /* generation of the tree */
pascal@20223 241 + };
pascal@20223 242 +
pascal@20223 243 +#define EXT4_EXT_MAGIC (0xf30a)
pascal@20223 244 +#define EXT_FIRST_EXTENT(__hdr__) \
pascal@20223 245 + ((struct ext4_extent *) (((char *) (__hdr__)) + \
pascal@20223 246 + sizeof(struct ext4_extent_header)))
pascal@20223 247 +#define EXT_FIRST_INDEX(__hdr__) \
pascal@20223 248 + ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
pascal@20223 249 + sizeof(struct ext4_extent_header)))
pascal@20223 250 +#define EXT_LAST_EXTENT(__hdr__) \
pascal@20223 251 + (EXT_FIRST_EXTENT((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
pascal@20223 252 +#define EXT_LAST_INDEX(__hdr__) \
pascal@20223 253 + (EXT_FIRST_INDEX((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
pascal@20223 254 +
pascal@20223 255 +
pascal@20223 256 +
pascal@20223 257 /* linux/ext2fs.h */
pascal@20223 258 /*
pascal@20223 259 * EXT2_DIR_PAD defines the directory entries boundaries
pascal@20224 260 @@ -193,7 +334,7 @@
pascal@20223 261
pascal@20223 262
pascal@20223 263 /* ext2/super.c */
pascal@20223 264 -#define log2(n) ffz(~(n))
pascal@20228 265 +#define log2(n) ffz(~(n))
pascal@20223 266
pascal@20223 267 #define EXT2_SUPER_MAGIC 0xEF53 /* include/linux/ext2_fs.h */
pascal@20223 268 #define EXT2_ROOT_INO 2 /* include/linux/ext2_fs.h */
pascal@20224 269 @@ -202,11 +343,12 @@
pascal@20223 270
pascal@20223 271 /* made up, these are pointers into FSYS_BUF */
pascal@20223 272 /* read once, always stays there: */
pascal@20223 273 +#define NAME_BUF ((char *)(FSYS_BUF)) /* 512 bytes */
pascal@20223 274 #define SUPERBLOCK \
pascal@20223 275 - ((struct ext2_super_block *)(FSYS_BUF))
pascal@20223 276 + ((struct ext2_super_block *)((FSYS_BUF)+512)) /* 1024 bytes */
pascal@20223 277 #define GROUP_DESC \
pascal@20223 278 ((struct ext2_group_desc *) \
pascal@20223 279 - ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))
pascal@20223 280 + ((int)SUPERBLOCK + sizeof(struct ext2_super_block))) /* 32 bytes */
pascal@20223 281 #define INODE \
pascal@20223 282 ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK)))
pascal@20223 283 #define DATABLOCK1 \
pascal@20224 284 @@ -216,15 +358,37 @@
pascal@20223 285
pascal@20223 286 /* linux/ext2_fs.h */
pascal@20223 287 #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
pascal@20223 288 -#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s)))
pascal@20227 289 +#define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s)))
pascal@20223 290
pascal@20223 291 +/* Revision levels */
pascal@20224 292 +#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
pascal@20224 293 +#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
pascal@20223 294 +
pascal@20223 295 +#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
pascal@20223 296 +#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
pascal@20223 297 +
pascal@20223 298 +#define EXT2_GOOD_OLD_INODE_SIZE 128
pascal@20223 299 +
pascal@20223 300 +#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
pascal@20223 301 +//#define EXT2_INODE_SIZE(s) (SUPERBLOCK->s_inode_size)
pascal@20224 302 +#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
pascal@20224 303 +
pascal@20223 304 /* linux/ext2_fs.h */
pascal@20224 305 #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
pascal@20223 306 /* kind of from ext2/super.c */
pascal@20223 307 #define EXT2_BLOCK_SIZE(s) (1 << EXT2_BLOCK_SIZE_BITS(s))
pascal@20223 308 /* linux/ext2fs.h */
pascal@20223 309 +/* sizeof(struct ext2_group_desc) is changed in ext4
pascal@20223 310 + * in kernel code, ext2/3 uses sizeof(struct ext2_group_desc) to calculate
pascal@20223 311 + * number of desc per block, while ext4 uses superblock->s_desc_size in stead
pascal@20223 312 + * superblock->s_desc_size is not available in ext2/3
pascal@20223 313 + * */
pascal@20223 314 +#define EXT2_DESC_SIZE(s) \
pascal@20223 315 + (EXT4_HAS_INCOMPAT_FEATURE(s,EXT4_FEATURE_INCOMPAT_64BIT)? \
pascal@20223 316 + s->s_desc_size : EXT4_MIN_DESC_SIZE)
pascal@20223 317 #define EXT2_DESC_PER_BLOCK(s) \
pascal@20223 318 - (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
pascal@20223 319 + (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
pascal@20223 320 +
pascal@20223 321 /* linux/stat.h */
pascal@20223 322 #define S_IFMT 00170000
pascal@20223 323 #define S_IFLNK 0120000
pascal@20224 324 @@ -234,38 +398,82 @@
pascal@20223 325 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
pascal@20223 326 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
pascal@20223 327
pascal@20223 328 +#ifndef GRUB_UTIL
pascal@20223 329 +static char *linkbuf = (char *)(FSYS_BUF - PATH_MAX); /* buffer for following symbolic links */
pascal@20223 330 +#else
pascal@20223 331 +static char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
pascal@20223 332 +#endif
pascal@20223 333 +
pascal@20223 334 /* include/asm-i386/bitops.h */
pascal@20223 335 /*
pascal@20223 336 * ffz = Find First Zero in word. Undefined if no zero exists,
pascal@20223 337 * so code should check against ~0UL first..
pascal@20223 338 */
pascal@20223 339 -static __inline__ unsigned long
pascal@20223 340 -ffz (unsigned long word)
pascal@20223 341 -{
pascal@20223 342 - __asm__ ("bsfl %1,%0"
pascal@20223 343 -: "=r" (word)
pascal@20223 344 -: "r" (~word));
pascal@20223 345 - return word;
pascal@20223 346 -}
pascal@20228 347 +static __inline__ unsigned long
pascal@20228 348 +ffz (unsigned long word)
pascal@20228 349 +{
pascal@20228 350 + __asm__ ("bsfl %1,%0"
pascal@20228 351 +: "=r" (word)
pascal@20228 352 +: "r" (~word));
pascal@20228 353 + return word;
pascal@20228 354 +}
pascal@20223 355
pascal@20223 356 /* check filesystem types and read superblock into memory buffer */
pascal@20223 357 int
pascal@20223 358 ext2fs_mount (void)
pascal@20223 359 {
pascal@20223 360 - int retval = 1;
pascal@20223 361 +// if (((current_drive & 0x80) || (current_slice != 0))
pascal@20223 362 +// && (current_slice != PC_SLICE_TYPE_EXT2FS)
pascal@20223 363 +// && (current_slice != PC_SLICE_TYPE_LINUX_RAID)
pascal@20223 364 +// && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
pascal@20223 365 +// && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
pascal@20223 366 +// return 0;
pascal@20223 367 +
pascal@20223 368 + if ((unsigned long)part_length < (SBLOCK + (sizeof(struct ext2_super_block) / DEV_BSIZE)))
pascal@20223 369 + return 0;
pascal@20223 370
pascal@20223 371 - if ((((current_drive & 0x80) || (current_slice != 0))
pascal@20223 372 - && (current_slice != PC_SLICE_TYPE_EXT2FS)
pascal@20223 373 - && (current_slice != PC_SLICE_TYPE_LINUX_RAID)
pascal@20223 374 - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
pascal@20223 375 - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
pascal@20223 376 - || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE))
pascal@20223 377 - || !devread (SBLOCK, 0, sizeof (struct ext2_super_block),
pascal@20223 378 - (char *) SUPERBLOCK)
pascal@20223 379 - || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
pascal@20223 380 - retval = 0;
pascal@20225 381 + if (!devread(SBLOCK, 0, sizeof(struct ext2_super_block), (char *)SUPERBLOCK))
pascal@20223 382 + return 0;
pascal@20223 383
pascal@20223 384 - return retval;
pascal@20223 385 + if (SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
pascal@20223 386 + return 0;
pascal@20223 387 +
pascal@20223 388 + if (SUPERBLOCK->s_inodes_count == 0)
pascal@20223 389 + return 0;
pascal@20223 390 +
pascal@20223 391 + if (SUPERBLOCK->s_blocks_count == 0)
pascal@20223 392 + return 0;
pascal@20223 393 +
pascal@20223 394 + if (SUPERBLOCK->s_blocks_per_group == 0)
pascal@20223 395 + return 0;
pascal@20223 396 +
pascal@20223 397 + if (SUPERBLOCK->s_inodes_per_group == 0)
pascal@20223 398 + return 0;
pascal@20223 399 +
pascal@20223 400 + if (SUPERBLOCK->s_first_data_block > 1) /* 1 for 1K block, 0 otherwise */
pascal@20223 401 + return 0;
pascal@20223 402 +
pascal@20223 403 + if (SUPERBLOCK->s_log_block_size > 4) /* max size of block is 16K. 0 for 1K */
pascal@20223 404 + return 0;
pascal@20223 405 +
pascal@20223 406 + if (SUPERBLOCK->s_first_data_block)
pascal@20223 407 + {
pascal@20223 408 + if (SUPERBLOCK->s_log_block_size)
pascal@20223 409 + return 0;
pascal@20223 410 + } else {
pascal@20223 411 + if (SUPERBLOCK->s_log_block_size == 0)
pascal@20223 412 + return 0;
pascal@20223 413 + }
pascal@20223 414 +
pascal@20223 415 + if (SUPERBLOCK->s_rev_level)
pascal@20223 416 + {
pascal@20223 417 + if (SUPERBLOCK->s_inode_size == 0)
pascal@20223 418 + return 0;
pascal@20223 419 + if (EXT2_BLOCK_SIZE(SUPERBLOCK) % (SUPERBLOCK->s_inode_size))
pascal@20223 420 + return 0;
pascal@20223 421 + }
pascal@20223 422 +
pascal@20223 423 + return 1;
pascal@20223 424 }
pascal@20223 425
pascal@20223 426 /* Takes a file system block number and reads it into BUFFER. */
pascal@20224 427 @@ -285,7 +493,7 @@
pascal@20223 428 /* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into
pascal@20223 429 a physical block (the location in the file system) via an inode. */
pascal@20223 430 static int
pascal@20223 431 -ext2fs_block_map (int logical_block)
pascal@20223 432 +ext2fs_block_map (unsigned long logical_block)
pascal@20223 433 {
pascal@20223 434
pascal@20223 435 #ifdef E2DEBUG
pascal@20224 436 @@ -359,13 +567,16 @@
pascal@20223 437 /* else */
pascal@20223 438 mapblock2 = -1;
pascal@20223 439 logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
pascal@20223 440 +
pascal@20223 441 if (mapblock1 != 3
pascal@20223 442 && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
pascal@20223 443 {
pascal@20223 444 errnum = ERR_FSYS_CORRUPT;
pascal@20223 445 return -1;
pascal@20223 446 }
pascal@20223 447 +
pascal@20223 448 mapblock1 = 3;
pascal@20223 449 +
pascal@20223 450 if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
pascal@20223 451 [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
pascal@20223 452 * 2)],
pascal@20224 453 @@ -374,7 +585,8 @@
pascal@20223 454 errnum = ERR_FSYS_CORRUPT;
pascal@20223 455 return -1;
pascal@20223 456 }
pascal@20223 457 - if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
pascal@20223 458 +
pascal@20223 459 + if (! ext2_rdfsb (((__u32 *) DATABLOCK2)
pascal@20223 460 [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
pascal@20223 461 & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
pascal@20223 462 DATABLOCK2))
pascal@20224 463 @@ -382,30 +594,148 @@
pascal@20223 464 errnum = ERR_FSYS_CORRUPT;
pascal@20223 465 return -1;
pascal@20223 466 }
pascal@20223 467 - return ((__u32 *) DATABLOCK2)
pascal@20223 468 - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
pascal@20223 469 +
pascal@20223 470 + return ((__u32 *) DATABLOCK2)[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
pascal@20223 471 }
pascal@20223 472
pascal@20223 473 +/* extent binary search index
pascal@20223 474 + * find closest index in the current level extent tree
pascal@20223 475 + * kind of from ext4_ext_binsearch_idx in ext4/extents.c
pascal@20223 476 + */
pascal@20223 477 +static struct ext4_extent_idx*
pascal@20223 478 +ext4_ext_binsearch_idx(struct ext4_extent_header* eh, int logical_block)
pascal@20223 479 +{
pascal@20223 480 + struct ext4_extent_idx *r, *l, *m;
pascal@20223 481 + l = EXT_FIRST_INDEX(eh) + 1;
pascal@20223 482 + r = EXT_LAST_INDEX(eh);
pascal@20223 483 + while (l <= r)
pascal@20223 484 + {
pascal@20223 485 + m = l + (r - l) / 2;
pascal@20223 486 + if (logical_block < m->ei_block)
pascal@20223 487 + r = m - 1;
pascal@20223 488 + else
pascal@20223 489 + l = m + 1;
pascal@20223 490 + }
pascal@20223 491 + return (struct ext4_extent_idx*)(l - 1);
pascal@20223 492 +}
pascal@20223 493 +
pascal@20223 494 +/* extent binary search
pascal@20223 495 + * find closest extent in the leaf level
pascal@20223 496 + * kind of from ext4_ext_binsearch in ext4/extents.c
pascal@20223 497 + */
pascal@20223 498 +static struct ext4_extent*
pascal@20223 499 +ext4_ext_binsearch(struct ext4_extent_header* eh, int logical_block)
pascal@20223 500 +{
pascal@20223 501 + struct ext4_extent *r, *l, *m;
pascal@20223 502 + l = EXT_FIRST_EXTENT(eh) + 1;
pascal@20223 503 + r = EXT_LAST_EXTENT(eh);
pascal@20223 504 + while (l <= r)
pascal@20223 505 + {
pascal@20223 506 + m = l + (r - l) / 2;
pascal@20223 507 + if (logical_block < m->ee_block)
pascal@20223 508 + r = m - 1;
pascal@20223 509 + else
pascal@20223 510 + l = m + 1;
pascal@20223 511 + }
pascal@20223 512 + return (struct ext4_extent*)(l - 1);
pascal@20223 513 +}
pascal@20223 514 +
pascal@20223 515 +/* Maps extents enabled logical block into physical block via an inode.
pascal@20223 516 + * EXT4_HUGE_FILE_FL should be checked before calling this.
pascal@20223 517 + */
pascal@20223 518 +static int
pascal@20223 519 +ext4fs_block_map (int logical_block)
pascal@20223 520 +{
pascal@20223 521 + struct ext4_extent_header *eh;
pascal@20223 522 + struct ext4_extent *ex;//, *extent;
pascal@20223 523 + struct ext4_extent_idx *ei;//, *index;
pascal@20223 524 + int depth;
pascal@20223 525 + //int i;
pascal@20223 526 +
pascal@20223 527 +#ifdef E2DEBUG
pascal@20223 528 + unsigned char *i;
pascal@20223 529 + for (i = (unsigned char *) INODE;
pascal@20223 530 + i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
pascal@20223 531 + i++)
pascal@20223 532 + {
pascal@20223 533 + printf ("%c", "0123456789abcdef"[*i >> 4]);
pascal@20223 534 + printf ("%c", "0123456789abcdef"[*i % 16]);
pascal@20223 535 + if (!((i + 1 - (unsigned char *) INODE) % 16))
pascal@20223 536 + {
pascal@20223 537 + printf ("\n");
pascal@20223 538 + }
pascal@20223 539 + else
pascal@20223 540 + {
pascal@20223 541 + printf (" ");
pascal@20223 542 + }
pascal@20223 543 + }
pascal@20223 544 + printf ("logical block %d\n", logical_block);
pascal@20223 545 +#endif /* E2DEBUG */
pascal@20223 546 + eh = (struct ext4_extent_header*)INODE->i_block;
pascal@20223 547 + if (eh->eh_magic != EXT4_EXT_MAGIC)
pascal@20223 548 + {
pascal@20223 549 + errnum = ERR_FSYS_CORRUPT;
pascal@20223 550 + return -1;
pascal@20223 551 + }
pascal@20223 552 + while((depth = eh->eh_depth) != 0)
pascal@20223 553 + { /* extent index */
pascal@20223 554 + if (eh->eh_magic != EXT4_EXT_MAGIC)
pascal@20223 555 + {
pascal@20223 556 + errnum = ERR_FSYS_CORRUPT;
pascal@20223 557 + return -1;
pascal@20223 558 + }
pascal@20223 559 + ei = ext4_ext_binsearch_idx(eh, logical_block);
pascal@20223 560 + if (ei->ei_leaf_hi)
pascal@20223 561 + {/* 64bit physical block number not supported */
pascal@20223 562 + errnum = ERR_FILELENGTH;
pascal@20223 563 + return -1;
pascal@20223 564 + }
pascal@20223 565 + if (!ext2_rdfsb(ei->ei_leaf_lo, DATABLOCK1))
pascal@20223 566 + {
pascal@20223 567 + errnum = ERR_FSYS_CORRUPT;
pascal@20223 568 + return -1;
pascal@20223 569 + }
pascal@20223 570 + eh = (struct ext4_extent_header*)DATABLOCK1;
pascal@20223 571 + }
pascal@20223 572 +
pascal@20223 573 + /* depth==0, we come to the leaf */
pascal@20223 574 + ex = ext4_ext_binsearch(eh, logical_block);
pascal@20223 575 + if (ex->ee_start_hi)
pascal@20223 576 + {/* 64bit physical block number not supported */
pascal@20223 577 + errnum = ERR_FILELENGTH;
pascal@20223 578 + return -1;
pascal@20223 579 + }
pascal@20223 580 + if ((ex->ee_block + ex->ee_len) < logical_block)
pascal@20223 581 + {
pascal@20223 582 + errnum = ERR_FSYS_CORRUPT;
pascal@20223 583 + return -1;
pascal@20223 584 + }
pascal@20223 585 + return ex->ee_start_lo + logical_block - ex->ee_block;
pascal@20223 586 +
pascal@20223 587 +}
pascal@20223 588 +
pascal@20223 589 /* preconditions: all preconds of ext2fs_block_map */
pascal@20225 590 int
pascal@20225 591 ext2fs_read (char *buf, int len)
pascal@20223 592 {
pascal@20223 593 - int logical_block;
pascal@20223 594 - int offset;
pascal@20223 595 + unsigned long logical_block;
pascal@20223 596 + unsigned long offset;
pascal@20223 597 + unsigned long ret = 0;
pascal@20223 598 + unsigned long size = 0;
pascal@20223 599 int map;
pascal@20223 600 - int ret = 0;
pascal@20223 601 - int size = 0;
pascal@20223 602
pascal@20223 603 #ifdef E2DEBUG
pascal@20223 604 static char hexdigit[] = "0123456789abcdef";
pascal@20223 605 unsigned char *i;
pascal@20223 606 +
pascal@20223 607 for (i = (unsigned char *) INODE;
pascal@20223 608 i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
pascal@20223 609 i++)
pascal@20223 610 {
pascal@20223 611 printf ("%c", hexdigit[*i >> 4]);
pascal@20223 612 printf ("%c", hexdigit[*i % 16]);
pascal@20223 613 - if (!((i + 1 - (unsigned char *) INODE) % 16))
pascal@20223 614 +
pascal@20223 615 + if (! ((i + 1 - (unsigned char *) INODE) % 16))
pascal@20223 616 {
pascal@20223 617 printf ("\n");
pascal@20223 618 }
pascal@20224 619 @@ -416,41 +746,53 @@
pascal@20223 620 }
pascal@20223 621 #endif /* E2DEBUG */
pascal@20223 622 while (len > 0)
pascal@20223 623 - {
pascal@20223 624 + {
pascal@20223 625 /* find the (logical) block component of our location */
pascal@20223 626 logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
pascal@20223 627 offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
pascal@20223 628 +
pascal@20223 629 + /* map extents enabled logical block number to physical fs on-dick block number */
pascal@20223 630 + if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS)
pascal@20223 631 + && INODE->i_flags & EXT4_EXTENTS_FL)
pascal@20223 632 + map = ext4fs_block_map (logical_block);
pascal@20223 633 + else
pascal@20223 634 map = ext2fs_block_map (logical_block);
pascal@20223 635 +
pascal@20223 636 #ifdef E2DEBUG
pascal@20223 637 printf ("map=%d\n", map);
pascal@20223 638 #endif /* E2DEBUG */
pascal@20223 639 +
pascal@20223 640 if (map < 0)
pascal@20223 641 - break;
pascal@20223 642 + break;
pascal@20223 643
pascal@20223 644 size = EXT2_BLOCK_SIZE (SUPERBLOCK);
pascal@20223 645 size -= offset;
pascal@20223 646 +
pascal@20223 647 if (size > len)
pascal@20223 648 - size = len;
pascal@20223 649 + size = len;
pascal@20223 650
pascal@20223 651 - if (map == 0) {
pascal@20223 652 - memset ((char *) buf, 0, size);
pascal@20223 653 + if (map == 0)
pascal@20223 654 + {
pascal@20223 655 + if (buf)
pascal@20223 656 + memset ((char *) buf, 0, size);
pascal@20223 657 } else {
pascal@20223 658 - disk_read_func = disk_read_hook;
pascal@20223 659 + disk_read_func = disk_read_hook;
pascal@20223 660
pascal@20223 661 - devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
pascal@20223 662 - offset, size, buf);
pascal@20223 663 + devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
pascal@20225 664 + offset, size, buf);
pascal@20223 665
pascal@20223 666 - disk_read_func = NULL;
pascal@20223 667 + disk_read_func = NULL;
pascal@20223 668 }
pascal@20223 669
pascal@20223 670 - buf += size;
pascal@20223 671 - len -= size;
pascal@20223 672 + if (buf)
pascal@20223 673 + buf += size;
pascal@20223 674 + len -= size; /* len always >= 0 */
pascal@20223 675 filepos += size;
pascal@20223 676 ret += size;
pascal@20223 677 - }
pascal@20223 678 + }
pascal@20223 679
pascal@20223 680 if (errnum)
pascal@20223 681 - ret = 0;
pascal@20223 682 + ret = 0;
pascal@20223 683
pascal@20223 684 return ret;
pascal@20223 685 }
pascal@20224 686 @@ -504,10 +846,10 @@
pascal@20223 687 int desc; /* index within that group */
pascal@20223 688 int ino_blk; /* fs pointer of the inode's information */
pascal@20223 689 int str_chk = 0; /* used to hold the results of a string compare */
pascal@20223 690 - struct ext2_group_desc *gdp;
pascal@20223 691 + struct ext4_group_desc *ext4_gdp;
pascal@20223 692 struct ext2_inode *raw_inode; /* inode info corresponding to current_ino */
pascal@20223 693
pascal@20223 694 - char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
pascal@20223 695 +//char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
pascal@20223 696 int link_count = 0;
pascal@20223 697
pascal@20223 698 char *rest;
pascal@20224 699 @@ -537,7 +879,7 @@
pascal@20223 700
pascal@20223 701 /* look up an inode */
pascal@20223 702 group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);
pascal@20223 703 - group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
pascal@20227 704 + group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
pascal@20223 705 desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1);
pascal@20223 706 #ifdef E2DEBUG
pascal@20223 707 printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group,
pascal@20224 708 @@ -550,10 +892,17 @@
pascal@20223 709 {
pascal@20223 710 return 0;
pascal@20223 711 }
pascal@20223 712 - gdp = GROUP_DESC;
pascal@20223 713 - ino_blk = gdp[desc].bg_inode_table +
pascal@20223 714 + ext4_gdp = (struct ext4_group_desc *)( (__u8*)GROUP_DESC +
pascal@20223 715 + desc * EXT2_DESC_SIZE(SUPERBLOCK));
pascal@20223 716 + if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK, EXT4_FEATURE_INCOMPAT_64BIT)
pascal@20223 717 + && (! ext4_gdp->bg_inode_table_hi))
pascal@20223 718 + {/* 64bit itable not supported */
pascal@20223 719 + errnum = ERR_FILELENGTH;
pascal@20223 720 + return -1;
pascal@20223 721 + }
pascal@20223 722 + ino_blk = ext4_gdp->bg_inode_table +
pascal@20223 723 (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
pascal@20224 724 - >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
pascal@20227 725 + >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
pascal@20223 726 #ifdef E2DEBUG
pascal@20223 727 printf ("inode table fsblock=%d\n", ino_blk);
pascal@20223 728 #endif /* E2DEBUG */
pascal@20224 729 @@ -565,13 +914,12 @@
pascal@20224 730 /* reset indirect blocks! */
pascal@20224 731 mapblock2 = mapblock1 = -1;
pascal@20223 732
pascal@20224 733 - raw_inode = INODE +
pascal@20224 734 - ((current_ino - 1)
pascal@20224 735 - & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
pascal@20224 736 + raw_inode = (struct ext2_inode *)((char *)INODE +
pascal@20224 737 + ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
pascal@20223 738 + EXT2_INODE_SIZE (SUPERBLOCK));
pascal@20223 739 #ifdef E2DEBUG
pascal@20223 740 printf ("ipb=%d, sizeof(inode)=%d\n",
pascal@20224 741 - (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
pascal@20224 742 - sizeof (struct ext2_inode));
pascal@20223 743 + EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
pascal@20223 744 printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
pascal@20223 745 printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
pascal@20223 746 for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
pascal@20224 747 @@ -609,13 +957,22 @@
pascal@20223 748 }
pascal@20223 749
pascal@20223 750 /* Find out how long our remaining name is. */
pascal@20223 751 - len = 0;
pascal@20223 752 - while (dirname[len] && !isspace (dirname[len]))
pascal@20223 753 - len++;
pascal@20223 754 + //len = 0;
pascal@20223 755 + //while (dirname[len] && !isspace (dirname[len]))
pascal@20223 756 + // len++;
pascal@20223 757 + for (len = 0; (ch = dirname[len]) && !isspace (ch); len++)
pascal@20223 758 + {
pascal@20223 759 + if (ch == '\\')
pascal@20223 760 + {
pascal@20223 761 + len++;
pascal@20223 762 + if (! (ch = dirname[len]))
pascal@20223 763 + break;
pascal@20223 764 + }
pascal@20223 765 + }
pascal@20223 766
pascal@20223 767 /* Get the symlink size. */
pascal@20223 768 filemax = (INODE->i_size);
pascal@20223 769 - if (filemax + len > sizeof (linkbuf) - 2)
pascal@20223 770 + if (filemax + len > PATH_MAX - 2)
pascal@20223 771 {
pascal@20223 772 errnum = ERR_FILELENGTH;
pascal@20223 773 return 0;
pascal@20224 774 @@ -629,18 +986,23 @@
pascal@20223 775 }
pascal@20223 776 linkbuf[filemax + len] = '\0';
pascal@20223 777
pascal@20223 778 - /* Read the symlink data. */
pascal@20223 779 + /* Read the symlink data.
pascal@20223 780 + * Slow symlink is extents enabled
pascal@20223 781 + * But since grub_read invokes ext2fs_read, nothing to change here
pascal@20223 782 + * */
pascal@20223 783 if (! ext2_is_fast_symlink ())
pascal@20223 784 {
pascal@20223 785 /* Read the necessary blocks, and reset the file pointer. */
pascal@20223 786 - len = grub_read (linkbuf, filemax);
pascal@20226 787 + len = grub_read (linkbuf, filemax);
pascal@20223 788 filepos = 0;
pascal@20223 789 if (!len)
pascal@20223 790 return 0;
pascal@20223 791 }
pascal@20223 792 else
pascal@20223 793 {
pascal@20223 794 - /* Copy the data directly from the inode. */
pascal@20223 795 + /* Copy the data directly from the inode.
pascal@20223 796 + * Fast symlink is not extents enabled
pascal@20223 797 + * */
pascal@20223 798 len = filemax;
pascal@20223 799 memmove (linkbuf, (char *) INODE->i_block, len);
pascal@20223 800 }
pascal@20224 801 @@ -674,6 +1036,13 @@
pascal@20223 802 errnum = ERR_BAD_FILETYPE;
pascal@20223 803 return 0;
pascal@20223 804 }
pascal@20223 805 + /* if file is too large, just stop and report an error*/
pascal@20223 806 + if ( (INODE->i_flags & EXT4_HUGE_FILE_FL) && !(INODE->i_size_high))
pascal@20223 807 + {
pascal@20223 808 + /* file too large, stop reading */
pascal@20223 809 + errnum = ERR_FILELENGTH;
pascal@20223 810 + return 0;
pascal@20223 811 + }
pascal@20223 812
pascal@20223 813 filemax = (INODE->i_size);
pascal@20223 814 return 1;
pascal@20224 815 @@ -694,8 +1063,17 @@
pascal@20223 816 }
pascal@20223 817
pascal@20223 818 /* skip to next slash or end of filename (space) */
pascal@20223 819 - for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
pascal@20223 820 - rest++);
pascal@20223 821 +// for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
pascal@20223 822 +// rest++);
pascal@20223 823 + for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++)
pascal@20223 824 + {
pascal@20223 825 + if (ch == '\\')
pascal@20223 826 + {
pascal@20223 827 + rest++;
pascal@20223 828 + if (! (ch = *rest))
pascal@20223 829 + break;
pascal@20223 830 + }
pascal@20223 831 + }
pascal@20223 832
pascal@20223 833 /* look through this directory and find the next filename component */
pascal@20223 834 /* invariant: rest points to slash after the next filename component */
pascal@20224 835 @@ -713,32 +1091,45 @@
pascal@20223 836 give up */
pascal@20223 837 if (loc >= INODE->i_size)
pascal@20223 838 {
pascal@20223 839 +# ifndef STAGE1_5
pascal@20223 840 if (print_possibilities < 0)
pascal@20223 841 {
pascal@20223 842 # if 0
pascal@20223 843 putchar ('\n');
pascal@20223 844 # endif
pascal@20223 845 + return 1;
pascal@20223 846 }
pascal@20223 847 - else
pascal@20223 848 - {
pascal@20223 849 - errnum = ERR_FILE_NOT_FOUND;
pascal@20223 850 - *rest = ch;
pascal@20223 851 - }
pascal@20223 852 - return (print_possibilities < 0);
pascal@20223 853 +# endif /* STAGE1_5 */
pascal@20223 854 +
pascal@20223 855 + errnum = ERR_FILE_NOT_FOUND;
pascal@20223 856 + *rest = ch;
pascal@20223 857 +
pascal@20223 858 + return 0;
pascal@20223 859 }
pascal@20223 860
pascal@20223 861 /* else, find the (logical) block component of our location */
pascal@20223 862 + /* ext4 logical block number the same as ext2/3 */
pascal@20223 863 blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
pascal@20223 864
pascal@20223 865 /* we know which logical block of the directory entry we are looking
pascal@20223 866 for, now we have to translate that to the physical (fs) block on
pascal@20223 867 the disk */
pascal@20223 868 + /* map extents enabled logical block number to physical fs on-dick block number */
pascal@20223 869 + if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS)
pascal@20223 870 + && INODE->i_flags & EXT4_EXTENTS_FL)
pascal@20223 871 + map = ext4fs_block_map (blk);
pascal@20223 872 + else
pascal@20223 873 map = ext2fs_block_map (blk);
pascal@20223 874 #ifdef E2DEBUG
pascal@20223 875 printf ("fs block=%d\n", map);
pascal@20223 876 #endif /* E2DEBUG */
pascal@20223 877 mapblock2 = -1;
pascal@20223 878 - if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))
pascal@20223 879 + if (map < 0)
pascal@20223 880 + {
pascal@20223 881 + *rest = ch;
pascal@20223 882 + return 0;
pascal@20223 883 + }
pascal@20223 884 + if (!ext2_rdfsb (map, DATABLOCK2))
pascal@20223 885 {
pascal@20223 886 errnum = ERR_FSYS_CORRUPT;
pascal@20223 887 *rest = ch;
pascal@20224 888 @@ -759,22 +1150,36 @@
pascal@20223 889
pascal@20223 890 if (dp->inode)
pascal@20223 891 {
pascal@20223 892 - int saved_c = dp->name[dp->name_len];
pascal@20223 893 + //int saved_c = dp->name[dp->name_len];
pascal@20223 894 + int j, k;
pascal@20223 895 + char ch1;
pascal@20223 896 + char *tmp_name= NAME_BUF; /* EXT2_NAME_LEN is 255, so 512 byte buffer is needed. */
pascal@20223 897
pascal@20223 898 - dp->name[dp->name_len] = 0;
pascal@20223 899 - str_chk = substring (dirname, dp->name);
pascal@20223 900 + /* copy dp->name to tmp_name, and quote the spaces with a '\\' */
pascal@20223 901 + for (j = 0, k = 0; j < dp->name_len; j++)
pascal@20223 902 + {
pascal@20223 903 + if (! (ch1 = dp->name[j]))
pascal@20223 904 + break;
pascal@20223 905 + if (ch1 == ' ')
pascal@20223 906 + tmp_name[k++] = '\\';
pascal@20223 907 + tmp_name[k++] = ch1;
pascal@20223 908 + }
pascal@20223 909 + tmp_name[k] = 0;
pascal@20223 910
pascal@20223 911 + //dp->name[dp->name_len] = 0;
pascal@20225 912 + str_chk = substring (dirname, tmp_name);
pascal@20223 913 +
pascal@20223 914 # ifndef STAGE1_5
pascal@20223 915 if (print_possibilities && ch != '/'
pascal@20223 916 && (!*dirname || str_chk <= 0))
pascal@20223 917 {
pascal@20223 918 if (print_possibilities > 0)
pascal@20223 919 print_possibilities = -print_possibilities;
pascal@20223 920 - print_a_completion (dp->name);
pascal@20223 921 + print_a_completion (tmp_name);
pascal@20223 922 }
pascal@20223 923 # endif
pascal@20223 924
pascal@20223 925 - dp->name[dp->name_len] = saved_c;
pascal@20223 926 + //dp->name[dp->name_len] = saved_c;
pascal@20223 927 }
pascal@20223 928
pascal@20223 929 }