source:
patches/grub-0.97-ext4-1.patch@
720552d3
Last change on this file since 720552d3 was fd60f98, checked in by , 16 years ago | |
---|---|
|
|
File size: 9.1 KB |
-
stage2/fsys_ext2fs.c
Submitted By: Zack Winkles (eikniw AT gmail DOT com) Date: 2009-02-27 Initial Package Version: 0.97 Origin: http://www.mail-archive.com/bug-grub@gnu.org/msg11458.html Upstream Status: Not accepted (package no longer maintained) Description: Implement support extents, as implemented in ext4. diff -Naur grub-0.97.orig/stage2/fsys_ext2fs.c grub-0.97/stage2/fsys_ext2fs.c
old new 51 51 #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) 52 52 #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) 53 53 54 /* Inode flags */ 55 #define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ 56 54 57 /* include/linux/ext2_fs.h */ 55 58 struct ext2_super_block 56 59 { … … 191 194 #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ 192 195 ~EXT2_DIR_ROUND) 193 196 197 /* linux/ext4_fs_extents.h */ 198 /* 199 * This is the extent on-disk structure. 200 * It's used at the bottom of the tree. 201 */ 202 struct ext4_extent { 203 __u32 ee_block; /* first logical block extent covers */ 204 __u16 ee_len; /* number of blocks covered by extent */ 205 __u16 ee_start_hi; /* high 16 bits of physical block */ 206 __u32 ee_start; /* low 32 bits of physical block */ 207 }; 208 209 /* 210 * This is index on-disk structure. 211 * It's used at all the levels except the bottom. 212 */ 213 struct ext4_extent_idx { 214 __u32 ei_block; /* index covers logical blocks from 'block' */ 215 __u32 ei_leaf; /* pointer to the physical block of the next * 216 * level. leaf or next index could be there */ 217 __u16 ei_leaf_hi; /* high 16 bits of physical block */ 218 __u16 ei_unused; 219 }; 220 221 /* 222 * Each block (leaves and indexes), even inode-stored has header. 223 */ 224 struct ext4_extent_header { 225 __u16 eh_magic; /* probably will support different formats */ 226 __u16 eh_entries; /* number of valid entries */ 227 __u16 eh_max; /* capacity of store in entries */ 228 __u16 eh_depth; /* has tree real underlying blocks? */ 229 __u32 eh_generation; /* generation of the tree */ 230 }; 231 232 #define EXT4_EXT_MAGIC 0xf30a 194 233 195 234 /* ext2/super.c */ 196 235 #define log2(n) ffz(~(n)) … … 279 318 EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer); 280 319 } 281 320 321 /* Walk through extents index tree to find the good leaf */ 322 static struct ext4_extent_header * 323 ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block) 324 { 325 int i; 326 struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1); 327 if (extent_block->eh_magic != EXT4_EXT_MAGIC) 328 return NULL; 329 if (extent_block->eh_depth == 0) 330 return extent_block; 331 for (i = 0; i < extent_block->eh_entries; i++) 332 { 333 if (logical_block < index[i].ei_block) 334 break; 335 } 336 if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1)) 337 return NULL; 338 return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block)); 339 } 340 341 282 342 /* from 283 343 ext2/inode.c:ext2_bmap() 284 344 */ … … 287 347 static int 288 348 ext2fs_block_map (int logical_block) 289 349 { 290 291 350 #ifdef E2DEBUG 292 351 unsigned char *i; 293 352 for (i = (unsigned char *) INODE; … … 308 367 printf ("logical block %d\n", logical_block); 309 368 #endif /* E2DEBUG */ 310 369 311 /* if it is directly pointed to by the inode, return that physical addr */ 312 if (logical_block < EXT2_NDIR_BLOCKS) 370 if (!(INODE->i_flags & EXT4_EXTENTS_FL)) 313 371 { 314 #ifdef E2DEBUG 315 printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); 316 printf ("returning %d\n", INODE->i_block[logical_block]); 317 #endif /* E2DEBUG */ 318 return INODE->i_block[logical_block]; 319 } 320 /* else */ 321 logical_block -= EXT2_NDIR_BLOCKS; 322 /* try the indirect block */ 323 if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) 324 { 325 if (mapblock1 != 1 326 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) 327 { 328 errnum = ERR_FSYS_CORRUPT; 329 return -1; 330 } 331 mapblock1 = 1; 332 return ((__u32 *) DATABLOCK1)[logical_block]; 333 } 334 /* else */ 335 logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); 336 /* now try the double indirect block */ 337 if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) 338 { 339 int bnum; 340 if (mapblock1 != 2 341 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) 342 { 343 errnum = ERR_FSYS_CORRUPT; 344 return -1; 345 } 346 mapblock1 = 2; 347 if ((bnum = (((__u32 *) DATABLOCK1) 348 [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) 349 != mapblock2 350 && !ext2_rdfsb (bnum, DATABLOCK2)) 351 { 352 errnum = ERR_FSYS_CORRUPT; 353 return -1; 354 } 355 mapblock2 = bnum; 372 /* if it is directly pointed to by the inode, return that physical addr */ 373 if (logical_block < EXT2_NDIR_BLOCKS) 374 { 375 #ifdef E2DEBUG 376 printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block])); 377 printf ("returning %d\n", INODE->i_block[logical_block]); 378 #endif /* E2DEBUG */ 379 return INODE->i_block[logical_block]; 380 } 381 /* else */ 382 logical_block -= EXT2_NDIR_BLOCKS; 383 /* try the indirect block */ 384 if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK)) 385 { 386 if (mapblock1 != 1 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1)) 387 { 388 errnum = ERR_FSYS_CORRUPT; 389 return -1; 390 } 391 mapblock1 = 1; 392 return ((__u32 *) DATABLOCK1)[logical_block]; 393 } 394 /* else */ 395 logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK); 396 /* now try the double indirect block */ 397 if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2))) 398 { 399 int bnum; 400 if (mapblock1 != 2 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1)) 401 { 402 errnum = ERR_FSYS_CORRUPT; 403 return -1; 404 } 405 mapblock1 = 2; 406 if ((bnum = (((__u32 *) DATABLOCK1) 407 [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) 408 != mapblock2 409 && !ext2_rdfsb (bnum, DATABLOCK2)) 410 { 411 errnum = ERR_FSYS_CORRUPT; 412 return -1; 413 } 414 mapblock2 = bnum; 415 return ((__u32 *) DATABLOCK2) 416 [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; 417 } 418 /* else */ 419 mapblock2 = -1; 420 logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); 421 if (mapblock1 != 3 422 && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) 423 { 424 errnum = ERR_FSYS_CORRUPT; 425 return -1; 426 } 427 mapblock1 = 3; 428 if (!ext2_rdfsb (((__u32 *) DATABLOCK1) 429 [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) 430 * 2)], 431 DATABLOCK2)) 432 { 433 errnum = ERR_FSYS_CORRUPT; 434 return -1; 435 } 436 if (!ext2_rdfsb (((__u32 *) DATABLOCK2) 437 [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) 438 & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], 439 DATABLOCK2)) 440 { 441 errnum = ERR_FSYS_CORRUPT; 442 return -1; 443 } 444 356 445 return ((__u32 *) DATABLOCK2) 357 446 [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; 358 447 } 359 /* else */ 360 mapblock2 = -1; 361 logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)); 362 if (mapblock1 != 3 363 && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1)) 364 { 365 errnum = ERR_FSYS_CORRUPT; 366 return -1; 367 } 368 mapblock1 = 3; 369 if (!ext2_rdfsb (((__u32 *) DATABLOCK1) 370 [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) 371 * 2)], 372 DATABLOCK2)) 373 { 374 errnum = ERR_FSYS_CORRUPT; 375 return -1; 376 } 377 if (!ext2_rdfsb (((__u32 *) DATABLOCK2) 378 [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) 379 & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], 380 DATABLOCK2)) 448 /* inode is in extents format */ 449 else 381 450 { 451 int i; 452 struct ext4_extent_header *extent_hdr = 453 ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block); 454 struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1); 455 if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC) 456 { 457 errnum = ERR_FSYS_CORRUPT; 458 return -1; 459 } 460 for (i = 0; i<extent_hdr->eh_entries; i++) 461 { 462 if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15)) 463 return (logical_block - extent[i].ee_block + extent[i].ee_start); 464 } 465 /* We should not arrive here */ 466 382 467 errnum = ERR_FSYS_CORRUPT; 383 468 return -1; 384 469 } 385 return ((__u32 *) DATABLOCK2)386 [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];387 470 } 388 471 389 472 /* preconditions: all preconds of ext2fs_block_map */
Note:
See TracBrowser
for help on using the repository browser.