26
26
#include <grub/types.h>
27
27
#include <grub/fshelp.h>
30
#define GRUB_AFS_FSNAME_SUFFIX "_be"
32
#define GRUB_AFS_FSNAME_SUFFIX ""
36
#define GRUB_AFS_FSNAME "befs" GRUB_AFS_FSNAME_SUFFIX
30
#define GRUB_AFS_FSNAME "befs"
38
#define GRUB_AFS_FSNAME "afs" GRUB_AFS_FSNAME_SUFFIX
32
#define GRUB_AFS_FSNAME "afs"
41
35
#define GRUB_AFS_DIRECT_BLOCK_COUNT 12
72
66
#define GRUB_AFS_NULL_VAL ((grub_afs_bvalue_t)-1)
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)
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)
68
#define U16(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
69
grub_le_to_cpu16 (u) : grub_be_to_cpu16 (u))
71
#define U32(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
72
grub_le_to_cpu32 (u) : grub_be_to_cpu32 (u))
74
#define U64(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
75
grub_le_to_cpu64 (u) : grub_be_to_cpu64 (u))
85
78
#define B_KEY_INDEX_ALIGN 8
231
227
grub_afs_run_to_num (struct grub_afs_sblock *sb,
232
228
struct grub_afs_blockrun *run)
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));
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;
255
if (fileblock < grub_afs_to_cpu64 (ds->max_direct_range))
251
if (fileblock < U64 (sb, ds->max_direct_range))
259
255
for (i = 0; i < GRUB_AFS_DIRECT_BLOCK_COUNT; i++)
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);
266
else if (fileblock < grub_afs_to_cpu64 (ds->max_indirect_range))
262
else if (fileblock < U64 (sb, ds->max_indirect_range))
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);
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++)
284
280
for (j = 0; j < ptrs_per_blk; j++)
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;
289
fileblock -= grub_afs_to_cpu16 (indir[j].len);
285
fileblock -= U16 (sb, indir[j].len);
296
292
struct grub_afs_blockrun indir[ptrs_per_blk];
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);
301
297
int dptr_size = GRUB_AFS_BLOCKS_PER_DI_RUN;
302
298
int dblk_size = dptr_size * ptrs_per_blk;
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);
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;
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))
386
384
grub_afs_read_file (dir, 0, 0, sizeof (head), (char *) &head);
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);
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++)
397
395
grub_afs_bvalue_t blk;
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);
414
412
index = B_KEY_INDEX_OFFSET (node);
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)
421
418
char filename [key_size + 1];
429
426
fdiro->data = dir->data;
430
427
if (grub_afs_read_inode (dir->data,
432
(B_KEY_VALUE_OFFSET (node) [cur_key]),
428
U64 (sb, B_KEY_VALUE_OFFSET (node) [cur_key]),
436
432
grub_memcpy (filename, &node->key_data[key_start], key_size);
437
433
filename [key_size] = 0;
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)
454
if (cur_key >= grub_afs_to_cpu32 (node->key_count))
450
if (cur_key >= U32 (sb, node->key_count))
456
452
if (node->right == GRUB_AFS_NULL_VAL)
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);
473
469
grub_afs_validate_sblock (struct grub_afs_sblock *sb)
475
if (grub_afs_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
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)
474
if (grub_le_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_LITTLE_ENDIAN)
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);
492
else if (grub_be_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
495
if (grub_be_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_BIG_ENDIAN)
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);
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)
625
648
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
626
649
info.mtimeset = 1;
628
info.mtime = grub_afs_to_cpu64 (node->inode.modified_time) >> 16;
651
info.mtime = U64 (&data->sblock, node->inode.modified_time) >> 16;
630
info.mtime = grub_divmod64 (grub_afs_to_cpu64 (node->inode.modified_time),
653
info.mtime = grub_divmod64 (U64 (&data->sblock,
654
node->inode.modified_time), 1000000, 0);
633
656
grub_free (node);
634
657
return hook (filename, &info);