Hi,
Thank you for the comments.
At Tue, 18 May 2010 18:21:18 +0200,
Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>
> Jiro SEKIBA wrote:
> > 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.
> >
> >
> Is it limited to only 2 blocks?
Yes, nilfs2 has super blocks at the beginning and the end of the partition.
> > 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.
> >
> >
>
> + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block),
> + &data->sblock);
> Please macroify
>
> + grub_disk_read (disk, (disk->total_sectors - 8), 0,
> + sizeof (struct grub_nilfs2_super_block), &sb2);
> total_sectors is a size of disk, not partition. Use grub_disk_get_size to
> automatically get the size of underlying object (disk or partition).
> Some disks have unknown size. CDROM is an example of it. Even worse trying to
> read from a sector past the boundary will hang the system for few minutes.
> Disks on OFW suffer the same problem. Perhaps we should add
> GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL for this case
Thank you the correction.
I fixed to use grub_disk_get_size() to obtain the size.
Also, I added the macro in grub/disk.h for the case that size
of partition is unknown.
> as an indicator and avoid querying back labels of such disks
> + /* Swap if first super block is invalid or oloder than second one. */
>
> Typo
>
> Could you supply the ChangeLog entry?
>
> --
> Regards
> Vladimir 'φ-coder/phcoder' Serbinenko
>
>
--
Jiro SEKIBA <[email protected]>
=== modified file 'fs/nilfs2.c'
--- fs/nilfs2.c 2010-04-24 20:09:08 +0000
+++ fs/nilfs2.c 2010-05-23 19:50:16 +0000
@@ -49,6 +49,13 @@
#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
#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
{
grub_uint64_t i_blocks;
@@ -703,6 +710,52 @@
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 *
grub_nilfs2_mount (grub_disk_t disk)
{
@@ -717,19 +770,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 +795,6 @@
if (grub_errno)
goto fail;
- data->disk = disk;
-
grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
if (grub_errno)
=== modified file 'include/grub/disk.h'
--- include/grub/disk.h 2010-01-07 00:58:54 +0000
+++ include/grub/disk.h 2010-05-23 18:53:34 +0000
@@ -138,6 +138,9 @@
#define GRUB_DISK_CACHE_SIZE 8
#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. */
void grub_disk_cache_invalidate_all (void);
_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel