Oops I forgot to supply ChangeLog entry. I'll resend the patch. Sorry for the careless-miss.
At Sun, 23 May 2010 20:59:15 +0900, Jiro SEKIBA wrote: > > [1 <text/plain; ISO-8859-7 (quoted-printable)>] > 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 <j...@unicus.jp> > > [2 nilfs2-support-2nd-sbv2.patch <text/plain; US-ASCII (quoted-printable)>] > === 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); > > > [3 <text/plain; ISO-8859-1 (quoted-printable)>] > > [4 <text/plain; us-ascii (7bit)>] > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel -- Jiro SEKIBA <j...@unicus.jp> _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel