Hi, This is a patch to support second super block of nilfs2. It will use the second super block when first one is accidentally collapsed or not synced properly.
NILFS has redundant super blocks. Those are identical if unmounted cleanly. However when one of these is collapsed or old, correct one or newer one should be used to find latest log correctly. Test on both PPC and x86. Thanks, Regards, -- Jiro SEKIBA <j...@unicus.jp>
=== modified file 'fs/nilfs2.c' --- fs/nilfs2.c 2010-04-24 20:09:08 +0000 +++ fs/nilfs2.c 2010-05-12 13:53:04 +0000 @@ -703,6 +703,42 @@ 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; + int valid[2]; + int swp = 0; + + /* Read first super block. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), + &data->sblock); + + /* Read second super block. */ + grub_disk_read (disk, (disk->total_sectors - 8), 0, + sizeof (struct grub_nilfs2_super_block), &sb2); + + /* Make sure super blocks are valid. */ + valid[0] = grub_nilfs2_valid_sb (&data->sblock); + valid[1] = grub_nilfs2_valid_sb (&sb2); + + 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 oloder 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 * grub_nilfs2_mount (grub_disk_t disk) { @@ -717,19 +753,13 @@ if (!data) return 0; + data->disk = disk; + /* Read the superblock. */ - grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), - &data->sblock); + grub_nilfs2_load_sb (data); if (grub_errno) 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)); /* Read the last segment summary. */ @@ -748,8 +778,6 @@ if (grub_errno) goto fail; - data->disk = disk; - grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); if (grub_errno)
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel