Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 250829 | Differences between
and this patch

Collapse All | Expand All

(-)grub-0.97/stage2/fsys_ext2fs.c (-74 / +141 lines)
Lines 50-55 typedef unsigned int __u32; Link Here
50
#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
50
#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
51
#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
51
#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
52
#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)
52
#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)
53
/* Inode flags */
54
#define EXT4_EXTENTS_FL                 0x00080000 /* Inode uses extents */
53
55
54
/* include/linux/ext2_fs.h */
56
/* include/linux/ext2_fs.h */
55
struct ext2_super_block
57
struct ext2_super_block
Lines 235-241 struct ext2_dir_entry Link Here
235
#define EXT2_DIR_ROUND                  (EXT2_DIR_PAD - 1)
237
#define EXT2_DIR_ROUND                  (EXT2_DIR_PAD - 1)
236
#define EXT2_DIR_REC_LEN(name_len)      (((name_len) + 8 + EXT2_DIR_ROUND) & \
238
#define EXT2_DIR_REC_LEN(name_len)      (((name_len) + 8 + EXT2_DIR_ROUND) & \
237
                                         ~EXT2_DIR_ROUND)
239
                                         ~EXT2_DIR_ROUND)
240
/* linux/ext4_fs_extents.h */
241
/*
242
 * This is the extent on-disk structure.
243
 * It's used at the bottom of the tree.
244
 */
245
struct ext4_extent {
246
    __u32 ee_block;       /* first logical block extent covers */
247
    __u16 ee_len;         /* number of blocks covered by extent */
248
    __u16 ee_start_hi;    /* high 16 bits of physical block */
249
    __u32 ee_start;       /* low 32 bits of physical block */
250
};
238
251
252
/*
253
 * This is index on-disk structure.
254
 * It's used at all the levels except the bottom.
255
 */
256
struct ext4_extent_idx {
257
    __u32 ei_block;       /* index covers logical blocks from 'block' */
258
    __u32 ei_leaf;        /* pointer to the physical block of the next *
259
                                 * level. leaf or next index could be there */
260
    __u16 ei_leaf_hi;     /* high 16 bits of physical block */
261
    __u16 ei_unused;
262
};
263
264
/*
265
 * Each block (leaves and indexes), even inode-stored has header.
266
 */
267
struct ext4_extent_header {
268
    __u16  eh_magic;       /* probably will support different formats */
269
    __u16  eh_entries;     /* number of valid entries */
270
    __u16  eh_max;         /* capacity of store in entries */
271
    __u16  eh_depth;       /* has tree real underlying blocks? */
272
    __u32  eh_generation;  /* generation of the tree */
273
};
274
275
#define EXT4_EXT_MAGIC          0xf30a
239
276
240
/* ext2/super.c */
277
/* ext2/super.c */
241
#define log2(n) ffz(~(n))
278
#define log2(n) ffz(~(n))
Lines 327-332 ext2_rdfsb (int fsblock, int buffer) Link Here
327
		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
364
		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
328
}
365
}
329
366
367
/* Walk through extents index tree to find the good leaf */
368
static struct ext4_extent_header * 
369
ext4_recurse_extent_index(struct ext4_extent_header *extent_block, int logical_block)
370
{
371
  int i;
372
  struct ext4_extent_idx *index = (struct ext4_extent_idx *) (extent_block + 1);
373
  if (extent_block->eh_magic != EXT4_EXT_MAGIC)
374
    return NULL;
375
  if (extent_block->eh_depth == 0)
376
    return extent_block;
377
  for (i = 0; i < extent_block->eh_entries; i++)
378
    {
379
      if (logical_block < index[i].ei_block)
380
        break;
381
    }
382
  if (i == 0 || !ext2_rdfsb(index[i-1].ei_leaf, DATABLOCK1))
383
    return NULL;
384
  return (ext4_recurse_extent_index((struct ext4_extent_header *) DATABLOCK1, logical_block));
385
}
386
330
/* from
387
/* from
331
  ext2/inode.c:ext2_bmap()
388
  ext2/inode.c:ext2_bmap()
332
*/
389
*/
Lines 355-437 ext2fs_block_map (int logical_block) Link Here
355
    }
412
    }
356
  printf ("logical block %d\n", logical_block);
413
  printf ("logical block %d\n", logical_block);
357
#endif /* E2DEBUG */
414
#endif /* E2DEBUG */
358
415
/* standard ext2 inode */
359
  /* if it is directly pointed to by the inode, return that physical addr */
416
if (!(INODE->i_flags & EXT4_EXTENTS_FL))  
360
  if (logical_block < EXT2_NDIR_BLOCKS)
417
   {
361
    {
418
/* if it is directly pointed to by the inode, return that physical addr */
362
#ifdef E2DEBUG
419
      if (logical_block < EXT2_NDIR_BLOCKS)
363
      printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
420
        {
364
      printf ("returning %d\n", INODE->i_block[logical_block]);
421
#ifdef E2DEBUG
365
#endif /* E2DEBUG */
422
          printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
366
      return INODE->i_block[logical_block];
423
          printf ("returning %d\n", INODE->i_block[logical_block]);
367
    }
424
#endif /* E2DEBUG */
368
  /* else */
425
          return INODE->i_block[logical_block];
369
  logical_block -= EXT2_NDIR_BLOCKS;
426
        }
370
  /* try the indirect block */
427
      /* else */
371
  if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
428
      logical_block -= EXT2_NDIR_BLOCKS;
372
    {
429
      /* try the indirect block */
373
      if (mapblock1 != 1
430
      if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
374
	  && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
431
        {
375
	{
432
          if (mapblock1 != 1 && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
376
	  errnum = ERR_FSYS_CORRUPT;
433
            {
377
	  return -1;
434
              errnum = ERR_FSYS_CORRUPT;
378
	}
435
              return -1;
379
      mapblock1 = 1;
436
            }
380
      return ((__u32 *) DATABLOCK1)[logical_block];
437
          mapblock1 = 1;
381
    }
438
          return ((__u32 *) DATABLOCK1)[logical_block];
382
  /* else */
439
        }
383
  logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
440
      /* else */
384
  /* now try the double indirect block */
441
      logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
385
  if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
442
      /* now try the double indirect block */
386
    {
443
      if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
387
      int bnum;
444
        {
388
      if (mapblock1 != 2
445
          int bnum;
389
	  && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
446
          if (mapblock1 != 2 && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
390
	{
447
            {
391
	  errnum = ERR_FSYS_CORRUPT;
448
              errnum = ERR_FSYS_CORRUPT;
392
	  return -1;
449
              return -1;
393
	}
450
            }
394
      mapblock1 = 2;
451
          mapblock1 = 2;
395
      if ((bnum = (((__u32 *) DATABLOCK1)
452
          if ((bnum = (((__u32 *) DATABLOCK1) [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)])) != mapblock2 && !ext2_rdfsb (bnum, DATABLOCK2))
396
		   [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))
453
            {
397
	  != mapblock2
454
              errnum = ERR_FSYS_CORRUPT;
398
	  && !ext2_rdfsb (bnum, DATABLOCK2))
455
              return -1;
399
	{
456
            }
400
	  errnum = ERR_FSYS_CORRUPT;
457
          mapblock2 = bnum;
401
	  return -1;
458
          return ((__u32 *) DATABLOCK2) [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
402
	}
459
        }
403
      mapblock2 = bnum;
460
      /* else */
404
      return ((__u32 *) DATABLOCK2)
461
      mapblock2 = -1;
405
	[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
462
      logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
406
    }
463
      if (mapblock1 != 3 && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
407
  /* else */
464
        {
408
  mapblock2 = -1;
465
          errnum = ERR_FSYS_CORRUPT;
409
  logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
466
          return -1;
410
  if (mapblock1 != 3
467
        }
411
      && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
468
      mapblock1 = 3;
412
    {
469
      if (!ext2_rdfsb (((__u32 *) DATABLOCK1) [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)], DATABLOCK2))
413
      errnum = ERR_FSYS_CORRUPT;
470
        {
414
      return -1;
471
          errnum = ERR_FSYS_CORRUPT;
415
    }
472
          return -1;
416
  mapblock1 = 3;
473
        }
417
  if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
474
      if (!ext2_rdfsb (((__u32 *) DATABLOCK2) [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)) & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)], DATABLOCK2))
418
		   [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
475
        {
419
				      * 2)],
476
          errnum = ERR_FSYS_CORRUPT;
420
		   DATABLOCK2))
477
          return -1;
421
    {
478
        }
422
      errnum = ERR_FSYS_CORRUPT;
479
        return ((__u32 *) DATABLOCK2)
423
      return -1;
480
		[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
424
    }
481
   }
425
  if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
482
   /* inode is in extents format */
426
		   [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
483
   else
427
		    & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
484
   {
428
		   DATABLOCK2))
485
     int i;
429
    {
486
     struct ext4_extent_header *extent_hdr = ext4_recurse_extent_index((struct ext4_extent_header *) INODE->i_block, logical_block);
487
     struct ext4_extent *extent = (struct ext4_extent *) (extent_hdr + 1);
488
     if ( extent_hdr == NULL || extent_hdr->eh_magic != EXT4_EXT_MAGIC)
489
      {
490
        errnum = ERR_FSYS_CORRUPT;
491
        return -1;
492
      }
493
      for (i = 0; i<extent_hdr->eh_entries; i++)
494
        {
495
          if (extent[i].ee_block <= logical_block && logical_block < extent[i].ee_block + extent[i].ee_len && !(extent[i].ee_len>>15))
496
            return (logical_block - extent[i].ee_block + extent[i].ee_start);
497
        }
498
      /* We should not arrive here */
430
      errnum = ERR_FSYS_CORRUPT;
499
      errnum = ERR_FSYS_CORRUPT;
431
      return -1;
500
      return -1;
432
    }
501
    }
433
  return ((__u32 *) DATABLOCK2)
434
    [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
435
}
502
}
436
503
437
/* preconditions: all preconds of ext2fs_block_map */
504
/* preconditions: all preconds of ext2fs_block_map */

Return to bug 250829