pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pkg/40258: sysutils/grub does not work with ffs file systems with blocksize > 8K

>Number:         40258
>Category:       pkg
>Synopsis:       sysutils/grub does not work with ffs file systems with 
>blocksize > 8K
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Dec 23 06:50:00 +0000 2008
>Originator:     Michael L. Hitch
>Release:        NetBSD 5.0_BETA
Montana State University
System: NetBSD Pavilion 5.0_BETA NetBSD 5.0_BETA (GENERIC) #0: Fri Dec 19 
23:17:57 MST 2008 
Architecture: x86_64
Machine: amd64
Sysutils/grub has a well-known problem of not working with ffs file systems 
with a blocksize > 8K.  Since NetBSD typically defaults to 16K, that results
in a file system that grub fails to work with.  It's sometimes a pain to
rebuild the filesystem, so it would be nice if grub would work with larger
block sizes.
Install grub on a file system with 16K blocksize and watch it (usually) fail.
Not wanting to rebuild a root file system I had, I looked at how grub handles
ffs file systems.  After puzzling over it for a while, I finally figured out
there was a rather minor bug in how fsys_ffs.c handles the indirect blocks.
The following patch fixes that bug.  It also changes the layout of the file
system buffer area to put the superblock at the end of that buffer to
reduce the likelyhood of it getting overwritten when the directory is
read into the file system buffer.  Most root directories are likely to be
less than 24K in size and shouldn't cause any problems.  I've been able to
boot from file systems with blocksizes of 64K, as well as with larger partitions
beyond the limit noted in the ffs restrictions I've seen documented.

diff -u work/grub-0.97/stage2/fsys_ffs.c
---        2008-07-22 11:06:41.000000000 
+++ work/grub-0.97/stage2/fsys_ffs.c    2008-07-22 11:07:37.000000000 -0600
@@ -71,9 +71,9 @@
 static int mapblock_bsize;
 /* pointer to superblock */
-#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
+#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 24576 ))
 #define INODE ((struct icommon *) ( FSYS_BUF + 16384 ))
-#define MAPBUF ( FSYS_BUF + 24576 )
+#define MAPBUF ( FSYS_BUF + 8192 )
 #define MAPBUF_LEN 8192
@@ -106,15 +106,16 @@
   /* If the blockmap loaded does not include FILE_BLOCK,
      load a new blockmap.  */
+  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
   if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock
-      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
+      || ( offset < mapblock_offset || offset >= mapblock_offset + (MAPBUF_LEN 
/ sizeof(int))))
       if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
          offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
          bsize = MAPBUF_LEN;
-         if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
+         if (offset * sizeof (int) + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
            offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);


Home | Main Index | Thread Index | Old Index