2009-07-20 Vladimir Serbinenko <phcoder@gmail.com>

Add BFS support

	* conf/common.rmk (grub_probe_SOURCES): Add fs/befs.c.
	(grub_fstest_SOURCES): Likewise.
	(pkglib_MODULES): Add befs.mod.
	(befs_mod_SOURCES): New variable.
	(befs_mod_CFLAGS): Likewise.
	(befs_mod_LDFLAGS): Likewise.
	* conf/i386-coreboot.rmk (grub_emu_SOURCES): Likewise.
	* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
	* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
	* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
	(grub_setup_SOURCES): Likewise.
	* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
	* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
	(grub_setup_SOURCES): Likewise.
	* fs/befs.c: New file.
	* fs/afs.c (GRUB_AFS_FSNAME): New declaration.
	(GRUB_AFS_SBLOCK_SECTOR): Likewise.
	(GRUB_AFS_SBLOCK_MAGIC1) [MODE_BFS]: New conditional declaration.
	(GRUB_AFS_BTREE_MAGIC) [MODE_BFS]: Likewise
	(B_KEY_INDEX_ALIGN): New declaration.
	(B_KEY_INDEX_OFFSET): Use B_KEY_INDEX_ALIGN.
	(grub_afs_bnode) [MODE_BFS]: Make key_count and key_size 16-bit
	(grub_afs_btree) [MODE_BFS]: New conditional declaration.
	(grub_afs_sblock) [MODE_BFS]: Remove link_count.
	(grub_afs_validate_sblock) [MODE_BFS]: Support BFS
	(grub_afs_mount) [MODE_BFS]: Likewise.
	(grub_afs_dir) [MODE_BFS]: Divide mtime by 65536 and not 1000000.
	(grub_afs_fs): Use GRUB_AFS_FSNAME
	(GRUB_MOD_INIT (afs)) [MODE_BFS]: Rename to ...
	(GRUB_MOD_INIT (befs)) [MODE_BFS]: ... this
	(GRUB_MOD_FINI (afs)) [MODE_BFS]: Rename to ...
	(GRUB_MOD_FINI (befs)) [MODE_BFS]: ... this
This commit is contained in:
phcoder 2009-07-20 21:18:59 +00:00
parent 4f253044ec
commit 1ef44b802b
10 changed files with 139 additions and 27 deletions

View file

@ -26,16 +26,33 @@
#include <grub/types.h>
#include <grub/fshelp.h>
#ifdef MODE_BFS
#define GRUB_AFS_FSNAME "befs"
#else
#define GRUB_AFS_FSNAME "afs"
#endif
#define GRUB_AFS_DIRECT_BLOCK_COUNT 12
#define GRUB_AFS_BLOCKS_PER_DI_RUN 4
#ifdef MODE_BFS
#define GRUB_AFS_SBLOCK_SECTOR 1
#define GRUB_AFS_SBLOCK_MAGIC1 0x42465331 /* BFS1. */
#else
#define GRUB_AFS_SBLOCK_SECTOR 2
#define GRUB_AFS_SBLOCK_MAGIC1 0x41465331 /* AFS1. */
#endif
#define GRUB_AFS_SBLOCK_MAGIC2 0xdd121031
#define GRUB_AFS_SBLOCK_MAGIC3 0x15b6830e
#define GRUB_AFS_INODE_MAGIC 0x64358428
#ifdef MODE_BFS
#define GRUB_AFS_BTREE_MAGIC 0x69f6c2e8
#else
#define GRUB_AFS_BTREE_MAGIC 0x65768995
#endif
#define GRUB_AFS_BNODE_SIZE 1024
@ -57,10 +74,17 @@
#define U64(sb, u) (((sb)->byte_order == GRUB_AFS_BO_LITTLE_ENDIAN) ? \
grub_le_to_cpu64 (u) : grub_be_to_cpu64 (u))
#ifdef MODE_BFS
#define B_KEY_INDEX_ALIGN 8
#else
#define B_KEY_INDEX_ALIGN 4
#endif
#define B_KEY_INDEX_OFFSET(node) ((grub_uint16_t *) \
((char *) (node) + \
sizeof (struct grub_afs_bnode) + \
((node->key_size + 3) & ~3)))
((char *) (node) \
+ ALIGN_UP (sizeof (struct grub_afs_bnode) \
+ node->key_size, \
B_KEY_INDEX_ALIGN)))
#define B_KEY_VALUE_OFFSET(node) ((grub_afs_bvalue_t *) \
((char *) B_KEY_INDEX_OFFSET (node) + \
@ -99,11 +123,27 @@ struct grub_afs_bnode
grub_afs_bvalue_t left;
grub_afs_bvalue_t right;
grub_afs_bvalue_t overflow;
#ifdef MODE_BFS
grub_uint16_t key_count;
grub_uint16_t key_size;
#else
grub_uint32_t key_count;
grub_uint32_t key_size;
#endif
char key_data[0];
} __attribute__ ((packed));
#ifdef MODE_BFS
struct grub_afs_btree
{
grub_uint32_t magic;
grub_uint32_t unused1;
grub_uint32_t tree_depth;
grub_uint32_t unused2;
grub_afs_bvalue_t root;
grub_uint32_t unused3[4];
} __attribute__ ((packed));
#else
struct grub_afs_btree
{
grub_uint32_t magic;
@ -112,6 +152,7 @@ struct grub_afs_btree
grub_afs_bvalue_t last_node;
grub_afs_bvalue_t first_free;
} __attribute__ ((packed));
#endif
struct grub_afs_sblock
{
@ -151,7 +192,9 @@ struct grub_afs_inode
grub_uint32_t gid;
grub_uint32_t mode;
grub_uint32_t flags;
#ifndef MODE_BFS
grub_uint32_t link_count;
#endif
grub_afs_bigtime create_time;
grub_afs_bigtime modified_time;
struct grub_afs_blockrun parent;
@ -427,8 +470,10 @@ grub_afs_validate_sblock (struct grub_afs_sblock *sb)
{
if (grub_le_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
{
#ifndef MODE_BFS
if (grub_le_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_LITTLE_ENDIAN)
return 0;
#endif
sb->byte_order = GRUB_AFS_BO_LITTLE_ENDIAN;
sb->magic2 = grub_le_to_cpu32 (sb->magic2);
@ -446,8 +491,10 @@ grub_afs_validate_sblock (struct grub_afs_sblock *sb)
}
else if (grub_be_to_cpu32 (sb->magic1) == GRUB_AFS_SBLOCK_MAGIC1)
{
#ifndef MODE_BFS
if (grub_be_to_cpu32 (sb->byte_order) != GRUB_AFS_BO_BIG_ENDIAN)
return 0;
#endif
sb->byte_order = GRUB_AFS_BO_BIG_ENDIAN;
sb->magic2 = grub_be_to_cpu32 (sb->magic2);
@ -470,15 +517,22 @@ grub_afs_validate_sblock (struct grub_afs_sblock *sb)
(sb->magic3 != GRUB_AFS_SBLOCK_MAGIC3))
return 0;
if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size) ||
(sb->used_blocks > sb->num_blocks ) ||
(sb->inode_size != sb->block_size) ||
(0 == sb->block_size) ||
((grub_uint32_t) (1 << sb->alloc_group_shift) !=
sb->block_per_group * sb->block_size) ||
(sb->alloc_group_count * sb->block_per_group < sb->num_blocks) ||
(U16 (sb, sb->log_block.len) != sb->log_size) ||
(U32 (sb, sb->valid_log_blocks) > sb->log_size))
#ifdef MODE_BFS
sb->block_per_group = 1 << (sb->alloc_group_shift);
#endif
if (((grub_uint32_t) (1 << sb->block_shift) != sb->block_size)
|| (sb->used_blocks > sb->num_blocks )
|| (sb->inode_size != sb->block_size)
|| (0 == sb->block_size)
#ifndef MODE_BFS
|| ((grub_uint32_t) (1 << sb->alloc_group_shift) !=
sb->block_per_group * sb->block_size)
|| (sb->alloc_group_count * sb->block_per_group < sb->num_blocks)
|| (U16 (sb, sb->log_block.len) != sb->log_size)
|| (U32 (sb, sb->valid_log_blocks) > sb->log_size)
#endif
)
return 0;
return 1;
@ -494,8 +548,8 @@ grub_afs_mount (grub_disk_t disk)
return 0;
/* Read the superblock. */
if (grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_afs_sblock),
&data->sblock))
if (grub_disk_read (disk, GRUB_AFS_SBLOCK_SECTOR, 0,
sizeof (struct grub_afs_sblock), &data->sblock))
goto fail;
if (! grub_afs_validate_sblock (&data->sblock))
@ -514,7 +568,8 @@ grub_afs_mount (grub_disk_t disk)
return data;
fail:
grub_error (GRUB_ERR_BAD_FS, "not an afs filesystem");
grub_error (GRUB_ERR_BAD_FS, "not an " GRUB_AFS_FSNAME " filesystem");
grub_free (data);
return 0;
}
@ -592,8 +647,12 @@ grub_afs_dir (grub_device_t device, const char *path,
grub_memset (&info, 0, sizeof (info));
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
#ifdef MODE_BFS
info.mtime = U64 (&data->sblock, node->inode.modified_time) >> 16;
#else
info.mtime = grub_divmod64 (U64 (&data->sblock,
node->inode.modified_time), 1000000, 0);
#endif
grub_free (node);
return hook (filename, &info);
}
@ -645,7 +704,7 @@ grub_afs_label (grub_device_t device, char **label)
static struct grub_fs grub_afs_fs = {
.name = "afs",
.name = GRUB_AFS_FSNAME,
.dir = grub_afs_dir,
.open = grub_afs_open,
.read = grub_afs_read,
@ -654,13 +713,21 @@ static struct grub_fs grub_afs_fs = {
.next = 0
};
#ifdef MODE_BFS
GRUB_MOD_INIT (befs)
#else
GRUB_MOD_INIT (afs)
#endif
{
grub_fs_register (&grub_afs_fs);
my_mod = mod;
}
#ifdef MODE_BFS
GRUB_MOD_FINI (befs)
#else
GRUB_MOD_FINI (afs)
#endif
{
grub_fs_unregister (&grub_afs_fs);
}