~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to fs/afs.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <grub/types.h>
27
27
#include <grub/fshelp.h>
28
28
 
29
 
#ifdef MODE_BIGENDIAN
30
 
#define GRUB_AFS_FSNAME_SUFFIX "_be"
31
 
#else
32
 
#define GRUB_AFS_FSNAME_SUFFIX ""
33
 
#endif
34
 
 
35
29
#ifdef MODE_BFS
36
 
#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
 
30
#define GRUB_AFS_FSNAME "befs"
37
31
#else
38
 
#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
 
32
#define GRUB_AFS_FSNAME "afs"
39
33
#endif
40
34
 
41
35
#define GRUB_AFS_DIRECT_BLOCK_COUNT     12
71
65
 
72
66
#define GRUB_AFS_NULL_VAL       ((grub_afs_bvalue_t)-1)
73
67
 
74
 
#ifdef MODE_BIGENDIAN
75
 
#define grub_afs_to_cpu16(x) grub_be_to_cpu16 (x)
76
 
#define grub_afs_to_cpu32(x) grub_be_to_cpu32 (x)
77
 
#define grub_afs_to_cpu64(x) grub_be_to_cpu64 (x)
78
 
#else
79
 
#define grub_afs_to_cpu16(x) grub_le_to_cpu16 (x)
80
 
#define grub_afs_to_cpu32(x) grub_le_to_cpu32 (x)
81
 
#define grub_afs_to_cpu64(x) grub_le_to_cpu64 (x)
82
 
#endif
 
68
#define U16(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
 
69
                    grub_le_to_cpu16 (u) : grub_be_to_cpu16 (u))
 
70
 
 
71
#define U32(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
 
72
                    grub_le_to_cpu32 (u) : grub_be_to_cpu32 (u))
 
73
 
 
74
#define U64(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
 
75
                    grub_le_to_cpu64 (u) : grub_be_to_cpu64 (u))
83
76
 
84
77
#ifdef MODE_BFS
85
78
#define B_KEY_INDEX_ALIGN 8
97
90
                                   ((char *) B_KEY_INDEX_OFFSET (node) + \
98
91
                                    node->key_count * 2))
99
92
 
 
93
enum
 
94
{
 
95
  GRUB_AFS_BO_LITTLE_ENDIAN,
 
96
  GRUB_AFS_BO_BIG_ENDIAN
 
97
};
 
98
 
100
99
typedef grub_uint64_t grub_afs_off_t;
101
100
typedef grub_uint64_t grub_afs_bigtime;
102
101
typedef grub_uint64_t grub_afs_bvalue_t;
155
154
} __attribute__ ((packed));
156
155
#endif
157
156
 
158
 
/* Beware that following structure describes AtheFS and if you write code
159
 
   which uses currently unused fields check it with both AtheFS and BeFS.
160
 
 */
161
157
struct grub_afs_sblock
162
158
{
163
159
  char name[32];
231
227
grub_afs_run_to_num (struct grub_afs_sblock *sb,
232
228
                     struct grub_afs_blockrun *run)
233
229
{
234
 
  return ((grub_afs_off_t) grub_afs_to_cpu32 (run->group)
235
 
          * sb->block_per_group + grub_afs_to_cpu16 (run->start));
 
230
  return ((grub_afs_off_t) U32 (sb, run->group) * sb->block_per_group +
 
231
          U16 (sb, run->start));
236
232
}
237
233
 
238
234
static grub_err_t
252
248
  struct grub_afs_sblock *sb = &node->data->sblock;
253
249
  struct grub_afs_datastream *ds = &node->inode.stream;
254
250
 
255
 
  if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
 
251
  if (fileblock < U64 (sb, ds->max_direct_range))
256
252
    {
257
253
      int i;
258
254
 
259
255
      for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
260
256
        {
261
 
          if (fileblock < grub_afs_to_cpu16 (ds->direct[i].len))
 
257
          if (fileblock < U16 (sb, ds->direct[i].len))
262
258
            return grub_afs_run_to_num (sb, &ds->direct[i]) + fileblock;
263
 
          fileblock -= grub_afs_to_cpu16 (ds->direct[i].len);
 
259
          fileblock -= U16 (sb, ds->direct[i].len);
264
260
        }
265
261
    }
266
 
  else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
 
262
  else if (fileblock < U64 (sb, ds->max_indirect_range))
267
263
    {
268
264
      int ptrs_per_blk = sb->block_size / sizeof (struct grub_afs_blockrun);
269
265
      struct grub_afs_blockrun indir[ptrs_per_blk];
270
266
      grub_afs_off_t blk = grub_afs_run_to_num (sb, &ds->indirect);
271
267
      int i;
272
268
 
273
 
      fileblock -= grub_afs_to_cpu64 (ds->max_direct_range);
 
269
      fileblock -= U64 (sb, ds->max_direct_range);
274
270
      for (i = 0; i < ds->indirect.len; i++, blk++)
275
271
        {
276
272
          int j;
283
279
 
284
280
          for (j = 0; j < ptrs_per_blk; j++)
285
281
            {
286
 
              if (fileblock < grub_afs_to_cpu16 (indir[j].len))
 
282
              if (fileblock < U16 (sb, indir[j].len))
287
283
                return grub_afs_run_to_num (sb, &indir[j]) + fileblock;
288
284
 
289
 
              fileblock -= grub_afs_to_cpu16 (indir[j].len);
 
285
              fileblock -= U16 (sb, indir[j].len);
290
286
            }
291
287
        }
292
288
    }
296
292
      struct grub_afs_blockrun indir[ptrs_per_blk];
297
293
 
298
294
      /* ([idblk][idptr]) ([dblk][dptr]) [blk]  */
299
 
      int cur_pos = fileblock - grub_afs_to_cpu64 (ds->max_indirect_range);
 
295
      int cur_pos = fileblock - U64 (sb, ds->max_indirect_range);
300
296
 
301
297
      int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
302
298
      int dblk_size = dptr_size * ptrs_per_blk;
338
334
{
339
335
  return grub_fshelp_read_file (node->data->disk, node, read_hook,
340
336
                                pos, len, buf, grub_afs_read_block,
341
 
                                grub_afs_to_cpu64 (node->inode.stream.size),
 
337
                                U64 (&node->data->sblock,
 
338
                                     node->inode.stream.size),
342
339
                                node->data->sblock.block_shift
343
340
                                - GRUB_DISK_SECTOR_BITS);
344
341
}
347
344
grub_afs_read_symlink (grub_fshelp_node_t node)
348
345
{
349
346
  char *ret;
350
 
  grub_afs_off_t size = grub_afs_to_cpu64 (node->inode.stream.size);
 
347
  struct grub_afs_sblock *sb = &node->data->sblock;
 
348
  grub_afs_off_t size = U64 (sb, node->inode.stream.size);
351
349
 
352
350
  if (size == 0)
353
351
    {
376
374
  struct grub_afs_btree head;
377
375
  char node_data [GRUB_AFS_BNODE_SIZE];
378
376
  struct grub_afs_bnode *node = (struct grub_afs_bnode *) node_data;
 
377
  struct grub_afs_sblock *sb = &dir->data->sblock;
379
378
  int i;
380
379
 
381
380
  if ((dir->inode.stream.size == 0)
382
 
      || ((grub_afs_to_cpu32 (dir->inode.mode) & GRUB_AFS_S_IFMT)
383
 
          != GRUB_AFS_S_IFDIR))
 
381
      || ((U32 (sb, dir->inode.mode) & GRUB_AFS_S_IFMT) != GRUB_AFS_S_IFDIR))
384
382
    return 0;
385
383
 
386
384
  grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
387
385
  if (grub_errno)
388
386
    return 0;
389
387
 
390
 
  grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (head.root),
 
388
  grub_afs_read_file (dir, 0, U64 (sb, head.root),
391
389
                      GRUB_AFS_BNODE_SIZE, (char *) node);
392
390
  if (grub_errno)
393
391
    return 0;
394
392
 
395
 
  for (i = 0; i < (int) grub_afs_to_cpu32 (head.tree_depth) - 1; i++)
 
393
  for (i = 0; i < (int) U32 (sb, head.tree_depth) - 1; i++)
396
394
    {
397
395
      grub_afs_bvalue_t blk;
398
396
 
399
 
      blk = grub_afs_to_cpu64(B_KEY_VALUE_OFFSET (node) [0]);
 
397
      blk = U64(sb, B_KEY_VALUE_OFFSET (node) [0]);
400
398
      grub_afs_read_file (dir, 0, blk, GRUB_AFS_BNODE_SIZE, (char *) node);
401
399
      if (grub_errno)
402
400
        return 0;
413
411
 
414
412
          index = B_KEY_INDEX_OFFSET (node);
415
413
 
416
 
          key_start = (cur_key > 0)
417
 
            ? grub_afs_to_cpu16 (index[cur_key - 1]) : 0;
418
 
          key_size = grub_afs_to_cpu16 (index[cur_key]) - key_start;
 
414
          key_start = U16 (sb, (cur_key > 0) ? index[cur_key - 1] : 0);
 
415
          key_size = U16 (sb, index[cur_key]) - key_start;
419
416
          if (key_size > 0)
420
417
            {
421
418
              char filename [key_size + 1];
428
425
 
429
426
              fdiro->data = dir->data;
430
427
              if (grub_afs_read_inode (dir->data,
431
 
                                       grub_afs_to_cpu64
432
 
                                       (B_KEY_VALUE_OFFSET (node) [cur_key]),
 
428
                                       U64 (sb, B_KEY_VALUE_OFFSET (node) [cur_key]),
433
429
                                       &fdiro->inode))
434
430
                return 0;
435
431
 
436
432
              grub_memcpy (filename, &node->key_data[key_start], key_size);
437
433
              filename [key_size] = 0;
438
434
 
439
 
              mode = (grub_afs_to_cpu32 (fdiro->inode.mode) & GRUB_AFS_S_IFMT);
 
435
              mode = (U32 (sb, fdiro->inode.mode) & GRUB_AFS_S_IFMT);
440
436
              if (mode == GRUB_AFS_S_IFDIR)
441
437
                type = GRUB_FSHELP_DIR;
442
438
              else if (mode == GRUB_AFS_S_IFREG)
451
447
            }
452
448
 
453
449
          cur_key++;
454
 
          if (cur_key >= grub_afs_to_cpu32 (node->key_count))
 
450
          if (cur_key >= U32 (sb, node->key_count))
455
451
            {
456
452
              if (node->right == GRUB_AFS_NULL_VAL)
457
453
                break;
458
454
 
459
 
              grub_afs_read_file (dir, 0, grub_afs_to_cpu64 (node->right),
 
455
              grub_afs_read_file (dir, 0, U64 (sb, node->right),
460
456
                                  GRUB_AFS_BNODE_SIZE, (char *) node);
461
457
              if (grub_errno)
462
458
                return 0;
472
468
static int
473
469
grub_afs_validate_sblock (struct grub_afs_sblock *sb)
474
470
{
475
 
  if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
476
 
    {
477
 
      sb->magic2 = grub_afs_to_cpu32 (sb->magic2);
478
 
      sb->magic3 = grub_afs_to_cpu32 (sb->magic3);
479
 
      sb->block_shift = grub_afs_to_cpu32 (sb->block_shift);
480
 
      sb->block_size = grub_afs_to_cpu32 (sb->block_size);
481
 
      sb->used_blocks = grub_afs_to_cpu64 (sb->used_blocks);
482
 
      sb->num_blocks = grub_afs_to_cpu64 (sb->num_blocks);
483
 
      sb->inode_size = grub_afs_to_cpu32 (sb->inode_size);
484
 
      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
485
 
      sb->alloc_group_shift = grub_afs_to_cpu32 (sb->alloc_group_shift);
486
 
      sb->block_per_group = grub_afs_to_cpu32 (sb->block_per_group);
487
 
      sb->alloc_group_count = grub_afs_to_cpu32 (sb->alloc_group_count);
488
 
      sb->log_size = grub_afs_to_cpu32 (sb->log_size);
 
471
  if (grub_le_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
 
472
    {
 
473
#ifndef MODE_BFS
 
474
      if (grub_le_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_LITTLE_ENDIAN)
 
475
        return 0;
 
476
#endif
 
477
 
 
478
      sb->byte_order = GRUB_AFS_BO_LITTLE_ENDIAN;
 
479
      sb->magic2 = grub_le_to_cpu32 (sb->magic2);
 
480
      sb->magic3 = grub_le_to_cpu32 (sb->magic3);
 
481
      sb->block_shift = grub_le_to_cpu32 (sb->block_shift);
 
482
      sb->block_size = grub_le_to_cpu32 (sb->block_size);
 
483
      sb->used_blocks = grub_le_to_cpu64 (sb->used_blocks);
 
484
      sb->num_blocks = grub_le_to_cpu64 (sb->num_blocks);
 
485
      sb->inode_size = grub_le_to_cpu32 (sb->inode_size);
 
486
      sb->alloc_group_count = grub_le_to_cpu32 (sb->alloc_group_count);
 
487
      sb->alloc_group_shift = grub_le_to_cpu32 (sb->alloc_group_shift);
 
488
      sb->block_per_group = grub_le_to_cpu32 (sb->block_per_group);
 
489
      sb->alloc_group_count = grub_le_to_cpu32 (sb->alloc_group_count);
 
490
      sb->log_size = grub_le_to_cpu32 (sb->log_size);
 
491
    }
 
492
  else if (grub_be_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
 
493
    {
 
494
#ifndef MODE_BFS
 
495
      if (grub_be_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_BIG_ENDIAN)
 
496
        return 0;
 
497
#endif
 
498
 
 
499
      sb->byte_order = GRUB_AFS_BO_BIG_ENDIAN;
 
500
      sb->magic2 = grub_be_to_cpu32 (sb->magic2);
 
501
      sb->magic3 = grub_be_to_cpu32 (sb->magic3);
 
502
      sb->block_shift = grub_be_to_cpu32 (sb->block_shift);
 
503
      sb->block_size = grub_be_to_cpu32 (sb->block_size);
 
504
      sb->used_blocks = grub_be_to_cpu64 (sb->used_blocks);
 
505
      sb->num_blocks = grub_be_to_cpu64 (sb->num_blocks);
 
506
      sb->inode_size = grub_be_to_cpu32 (sb->inode_size);
 
507
      sb->alloc_group_count = grub_be_to_cpu32 (sb->alloc_group_count);
 
508
      sb->alloc_group_shift = grub_be_to_cpu32 (sb->alloc_group_shift);
 
509
      sb->block_per_group = grub_be_to_cpu32 (sb->block_per_group);
 
510
      sb->alloc_group_count = grub_be_to_cpu32 (sb->alloc_group_count);
 
511
      sb->log_size = grub_be_to_cpu32 (sb->log_size);
489
512
    }
490
513
  else
491
514
    return 0;
506
529
      || ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
507
530
          sb->block_per_group * sb->block_size)
508
531
      || (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
509
 
      || (grub_afs_to_cpu16 (sb->log_block.len) != sb->log_size)
510
 
      || (grub_afs_to_cpu32 (sb->valid_log_blocks) > sb->log_size)
 
532
      || (U16 (sb, sb->log_block.len) != sb->log_size)
 
533
      || (U32 (sb, sb->valid_log_blocks) > sb->log_size)
511
534
#endif
512
535
      )
513
536
    return 0;
571
594
  grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_afs_inode));
572
595
  grub_free (fdiro);
573
596
 
574
 
  file->size = grub_afs_to_cpu64 (data->inode->stream.size);
 
597
  file->size = U64 (&data->sblock, data->inode->stream.size);
575
598
  file->data = data;
576
599
  file->offset = 0;
577
600
 
625
648
      info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
626
649
      info.mtimeset = 1;
627
650
#ifdef MODE_BFS
628
 
      info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
 
651
      info.mtime = U64 (&data->sblock, node->inode.modified_time) >> 16;
629
652
#else
630
 
      info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
631
 
                                  1000000, 0);
 
653
      info.mtime = grub_divmod64 (U64 (&data->sblock,
 
654
                                       node->inode.modified_time), 1000000, 0);
632
655
#endif
633
656
      grub_free (node);
634
657
      return hook (filename, &info);
690
713
  .next = 0
691
714
};
692
715
 
693
 
#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
694
 
GRUB_MOD_INIT (befs_be)
695
 
#elif defined (MODE_BFS)
 
716
#ifdef MODE_BFS
696
717
GRUB_MOD_INIT (befs)
697
 
#elif defined (MODE_BIGENDIAN)
698
 
GRUB_MOD_INIT (afs_be)
699
718
#else
700
719
GRUB_MOD_INIT (afs)
701
720
#endif
704
723
  my_mod = mod;
705
724
}
706
725
 
707
 
#if defined (MODE_BIGENDIAN) && defined (MODE_BFS)
708
 
GRUB_MOD_FINI (befs_be)
709
 
#elif defined (MODE_BFS)
 
726
#ifdef MODE_BFS
710
727
GRUB_MOD_FINI (befs)
711
 
#elif defined (MODE_BIGENDIAN)
712
 
GRUB_MOD_FINI (afs_be)
713
728
#else
714
729
GRUB_MOD_FINI (afs)
715
730
#endif