* include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro.
* fs/nilfs.c: Support 2nd super block in case 1st one is accidently corrupted or not synced properly.
This commit is contained in:
parent
c2ffc8e956
commit
dfbfe00473
3 changed files with 65 additions and 11 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2010-05-31 Jiro SEKIBA <jir@unicus.jp>
|
||||||
|
|
||||||
|
* include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro.
|
||||||
|
* fs/nilfs.c: Support 2nd super block in case 1st one is accidently
|
||||||
|
corrupted or not synced properly.
|
||||||
|
|
||||||
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
|
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* normal/main.c (grub_normal_add_menu_entry): Avoid going out of args.
|
* normal/main.c (grub_normal_add_menu_entry): Avoid going out of args.
|
||||||
|
|
67
fs/nilfs2.c
67
fs/nilfs2.c
|
@ -49,6 +49,13 @@
|
||||||
#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
|
#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
|
||||||
#define NILFS_BTREE_LEVEL_MAX 14
|
#define NILFS_BTREE_LEVEL_MAX 14
|
||||||
|
|
||||||
|
/* nilfs 1st super block posission from beginning of the partition
|
||||||
|
in 512 block size */
|
||||||
|
#define NILFS_1ST_SUPER_BLOCK 2
|
||||||
|
/* nilfs 2nd super block posission from end of the partition
|
||||||
|
in 512 block size */
|
||||||
|
#define NILFS_2ND_SUPER_BLOCK 8
|
||||||
|
|
||||||
struct grub_nilfs2_inode
|
struct grub_nilfs2_inode
|
||||||
{
|
{
|
||||||
grub_uint64_t i_blocks;
|
grub_uint64_t i_blocks;
|
||||||
|
@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_nilfs2_load_sb (struct grub_nilfs2_data *data)
|
||||||
|
{
|
||||||
|
grub_disk_t disk = data->disk;
|
||||||
|
struct grub_nilfs2_super_block sb2;
|
||||||
|
grub_uint64_t partition_size;
|
||||||
|
int valid[2];
|
||||||
|
int swp = 0;
|
||||||
|
|
||||||
|
/* Read first super block. */
|
||||||
|
grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0,
|
||||||
|
sizeof (struct grub_nilfs2_super_block), &data->sblock);
|
||||||
|
/* Make sure if 1st super block is valid. */
|
||||||
|
valid[0] = grub_nilfs2_valid_sb (&data->sblock);
|
||||||
|
|
||||||
|
partition_size = grub_disk_get_size (disk);
|
||||||
|
if (partition_size != GRUB_DISK_SIZE_UNKNOWN)
|
||||||
|
{
|
||||||
|
/* Read second super block. */
|
||||||
|
grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0,
|
||||||
|
sizeof (struct grub_nilfs2_super_block), &sb2);
|
||||||
|
/* Make sure if 2nd super block is valid. */
|
||||||
|
valid[1] = grub_nilfs2_valid_sb (&sb2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* 2nd super block may not exist, so it's invalid. */
|
||||||
|
valid[1] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!valid[0] && !valid[1])
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
|
||||||
|
|
||||||
|
swp = valid[1] && (!valid[0] ||
|
||||||
|
grub_le_to_cpu64 (data->sblock.s_last_cno) <
|
||||||
|
grub_le_to_cpu64 (sb2.s_last_cno));
|
||||||
|
|
||||||
|
/* swap if first super block is invalid or older than second one. */
|
||||||
|
if (swp)
|
||||||
|
grub_memcpy (&data->sblock, &sb2,
|
||||||
|
sizeof (struct grub_nilfs2_super_block));
|
||||||
|
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return grub_errno;
|
||||||
|
}
|
||||||
|
|
||||||
static struct grub_nilfs2_data *
|
static struct grub_nilfs2_data *
|
||||||
grub_nilfs2_mount (grub_disk_t disk)
|
grub_nilfs2_mount (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
|
@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk)
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
data->disk = disk;
|
||||||
|
|
||||||
/* Read the superblock. */
|
/* Read the superblock. */
|
||||||
grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block),
|
grub_nilfs2_load_sb (data);
|
||||||
&data->sblock);
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Make sure this is an nilfs2 filesystem. */
|
|
||||||
if (!grub_nilfs2_valid_sb (&data->sblock))
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
|
||||||
|
|
||||||
/* Read the last segment summary. */
|
/* Read the last segment summary. */
|
||||||
|
@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk)
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data->disk = disk;
|
|
||||||
|
|
||||||
grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
|
grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
|
||||||
|
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
|
|
|
@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
|
||||||
#define GRUB_DISK_CACHE_SIZE 8
|
#define GRUB_DISK_CACHE_SIZE 8
|
||||||
#define GRUB_DISK_CACHE_BITS 3
|
#define GRUB_DISK_CACHE_BITS 3
|
||||||
|
|
||||||
|
/* Return value of grub_disk_get_size() in case disk size is unknown. */
|
||||||
|
#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL
|
||||||
|
|
||||||
/* This is called from the memory manager. */
|
/* This is called from the memory manager. */
|
||||||
void grub_disk_cache_invalidate_all (void);
|
void grub_disk_cache_invalidate_all (void);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue