Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Gentoo, Grub, and FreeBSD 5.1
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
Craig_Williamson
n00b
n00b


Joined: 04 Mar 2003
Posts: 65
Location: New Zealand

PostPosted: Wed Jun 11, 2003 8:11 pm    Post subject: Gentoo, Grub, and FreeBSD 5.1 Reply with quote

Hi All,

I recently downloaded FreeBSD 5.1 to try it out. I am using Grub 0.92 with Gentoo as the bootloader.

When I try and boot FreeBSD after modifying the grub.conf file, a warning message appears that the file system is unknown. After doing some research, FreeBSD 5.1 now uses UFS2 as the default file system.

According to the grub docs, there is no mention of UFS2. So does grub support UFS2, and if not is there a way to get around this limitation?

If you can help it would be appreciated. Thanks in advance.


Craig
Back to top
View user's profile Send private message
tj
Apprentice
Apprentice


Joined: 10 Aug 2002
Posts: 199
Location: tokyo, japan

PostPosted: Wed Jun 11, 2003 8:25 pm    Post subject: Reply with quote

hi there

I set mine up like so
Code:

default 0
timeout 30
splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title=gentoo
root (hd0,0)
kernel /boot/bzImage root=/dev/hda3

title=FreeBSD 5.0
root (hd1,0)
chainloader (hd1,0)+1


where FreeBSD is on the 2nd drive - looks simple, but took a while to figure out

:D
_________________
I tried installing Suse Linux off the Internet. It got stuck in the middle somewhere.Installing off the Internet is for the birds.
Back to top
View user's profile Send private message
plate
Bodhisattva
Bodhisattva


Joined: 25 Jul 2002
Posts: 1663
Location: Berlin

PostPosted: Wed Jun 11, 2003 8:57 pm    Post subject: Reply with quote

Doesn't really come as a surprise, does it now: This cry for help* has been sticking around on the GRUB website for quite a while :? Unfortunately, they appear to be so much out of the loop that they haven't even realised yet that FreeBSD has become a problem, too...

*edited to point to the old version of the document that actually contained the "cry for help"...


Last edited by plate on Mon Mar 01, 2004 10:09 am; edited 1 time in total
Back to top
View user's profile Send private message
andyknownasabu
Apprentice
Apprentice


Joined: 06 Feb 2003
Posts: 281
Location: Zurich, Switzerland

PostPosted: Sun Feb 29, 2004 7:19 pm    Post subject: Reply with quote

plate wrote:
Doesn't really come as a surprise, does it now: This cry for help has been sticking around on the GRUB website for quite a while :? Unfortunately, they appear to be so much out of the loop that they haven't even realised yet that FreeBSD has become a problem, too...

In the meanwhile a patch which adds ufs2 support to grub has been submitted.

See:
http://savannah.gnu.org/bugs/?func=detailitem&item_id=7550

I've already sent it to the ebuild maintainer.

Chers
Back to top
View user's profile Send private message
plate
Bodhisattva
Bodhisattva


Joined: 25 Jul 2002
Posts: 1663
Location: Berlin

PostPosted: Sun Feb 29, 2004 7:34 pm    Post subject: Reply with quote

Great! We can mark this thread solved as soon as the patch hits the portage tree, I suppose? Have you tried the patch yourself yet?
Back to top
View user's profile Send private message
mezz
Tux's lil' helper
Tux's lil' helper


Joined: 01 Jun 2002
Posts: 111

PostPosted: Sun Feb 29, 2004 8:53 pm    Post subject: Reply with quote

tj wrote:
hi there

I set mine up like so
Code:

default 0
timeout 30
splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title=gentoo
root (hd0,0)
kernel /boot/bzImage root=/dev/hda3

title=FreeBSD 5.0
root (hd1,0)
chainloader (hd1,0)+1


where FreeBSD is on the 2nd drive - looks simple, but took a while to figure out

:D

FreeBSD 5.0 has the UFS1 set by default. The 5.1 has changed to UFS2 by default.
Back to top
View user's profile Send private message
andyknownasabu
Apprentice
Apprentice


Joined: 06 Feb 2003
Posts: 281
Location: Zurich, Switzerland

PostPosted: Sun Feb 29, 2004 9:23 pm    Post subject: Reply with quote

plate wrote:
Great! We can mark this thread solved as soon as the patch hits the portage tree, I suppose? Have you tried the patch yourself yet?

Yes, it works like a charm :D
I'm working at an ebuild at the moment...

UPDATE 3:
Unfortunately, still no support for ufs2 (05/10/2004)
but a new patch under
http://savannah.gnu.org/bugs/?func=detailitem&item_id=7550

UPDATE 2:
The maintainer told me that he will put the new ebuild into portage in a few days...

UPDATE:
Finished. Here it is:
Code:

# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
# $Header: /home/cvsroot/gentoo-x86/sys-boot/grub/grub-0.94-r2.ebuild,v 1.0 2004/02/29 22:39:10 bulling Exp $

inherit mount-boot eutils flag-o-matic gcc

DESCRIPTION="GNU GRUB boot loader"
HOMEPAGE="http://www.gnu.org/software/grub/"
SRC_URI="ftp://alpha.gnu.org/gnu/grub/${P}.tar.gz
        http://dev.gentoo.org/~spock/portage/distfiles/${P}-splash.patch.bz2"

LICENSE="GPL-2"
SLOT="0"
KEYWORDS="-* ~x86"
IUSE="static"

DEPEND=">=sys-libs/ncurses-5.2-r5
        >=sys-devel/autoconf-2.5"
PROVIDE="virtual/bootloader"

src_unpack() {
        unpack ${A} || die
        cd ${S} || die

        epatch ${WORKDIR}/${P}-splash.patch
        epatch ${FILESDIR}/${P}-ufs2-0.3.patch

        # grub-0.93.20030118-gentoo.diff; <woodchip@gentoo.org> (18 Jan 2003)
        # -fixes from grub CVS pulled on 20030118
        # -vga16 patches; mined from Debian's grub-0.93+cvs20030102-1.diff
        # -special-raid-devices.patch
        # -addsyncs.patch
        # -splashimagehelp.patch
        # -configfile.patch
        # -installcopyonly.patch

        # This patchset is from SuSE -- hopefully fixes the acl symlink issue
        # And should add some boot prettification
#       epatch ${WORKDIR}/${PF}-gentoo.diff
#       epatch ${FILESDIR}/${P}-test.patch
}

src_compile() {
        ### i686-specific code in the boot loader is a bad idea; disabling to ensure
        ### at least some compatibility if the hard drive is moved to an older or
        ### incompatible system.
        unset CFLAGS

        filter-flags -fstack-protector

        append-flags -DNDEBUG
        [ `gcc-major-version` -eq 3 ] && append-flags -minline-all-stringops
        use static && append-ldflags -static

        # http://www.gentoo.org/proj/en/hardened/etdyn-ssp.xml
        if has_version 'sys-devel/hardened-gcc' && [ "$(gcc-getCC)" == "gcc" ] ; then
                # the configure script has problems with -nostdlib
                CC="${CC} -yet_exec -yno_propolice"
        fi

        autoconf || die
        aclocal || die
        automake || die

        # build the net-bootable grub first
        CFLAGS="" \
        econf \
                --datadir=/usr/lib/grub \
                --exec-prefix=/ \
                --disable-auto-linux-mem-opt \
                --enable-diskless \
                --enable-{3c{5{03,07,09,29,95},90x},cs89x0,davicom,depca,eepro{,100}} \
                --enable-{epic100,exos205,ni5210,lance,ne2100,ni{50,65}10,natsemi} \
                --enable-{ne,ns8390,wd,otulip,rtl8139,sis900,sk-g16,smc9000,tiara} \
                --enable-{tulip,via-rhine,w89c840} || die

        emake w89c840_o_CFLAGS="-O" || die "making netboot stuff"

        mv stage2/{nbgrub,pxegrub} ${S}
        mv stage2/stage2 stage2/stage2.netboot

        make clean || die

        # now build the regular grub
        CFLAGS="${CFLAGS}" \
        econf \
                        --datadir=/usr/lib/grub \
                        --exec-prefix=/ \
                        --disable-auto-linux-mem-opt || die
        emake || die "making regular stuff"
}

src_install() {
        make DESTDIR=${D} install || die
        exeinto /usr/lib/grub
        doexe nbgrub pxegrub stage2/stage2 stage2/stage2.netboot

        insinto /boot/grub
        doins ${FILESDIR}/splash.xpm.gz
        newins docs/menu.lst grub.conf.sample

        dodoc AUTHORS BUGS COPYING ChangeLog NEWS README THANKS TODO
        newdoc docs/menu.lst grub.conf.sample
}

pkg_postinst() {
        [ "$ROOT" != "/" ] && return 0

        # change menu.lst to grub.conf
        if [ ! -e /boot/grub/grub.conf -a -e /boot/grub/menu.lst ]
        then
                mv /boot/grub/menu.lst /boot/grub/grub.conf
                ewarn
                ewarn "*** IMPORTANT NOTE: menu.lst has been renamed to grub.conf"
                ewarn
        fi
        einfo "Linking from new grub.conf name to menu.lst"
        ln -s grub.conf /boot/grub/menu.lst

        [ -e /boot/grub/stage2 ] && mv /boot/grub/stage2{,.old}

        einfo "Copying files from /usr/lib/grub to /boot"
        cp -p /usr/lib/grub/* /boot/grub
        cp -p /usr/lib/grub/grub/*/* /boot/grub

        [ -e /boot/grub/grub.conf ] \
                && /usr/sbin/grub \
                        --batch \
                        --device-map=/boot/grub/device.map \
                        < /boot/grub/grub.conf > /dev/null 2>&1
}


And here is the patchfile to be named "grub-ufs2-0.3.patch" and put under *portagedir*/sys-boot/grub/files/

Code:

diff -uNr grub/configure.ac grub/configure.ac
--- grub/configure.ac   Tue Jan 27 05:21:01 2004
+++ grub/configure.ac   Tue Jan 27 05:21:39 2004
@@ -227,6 +227,13 @@
   FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FFS=1"
 fi
 
+AC_ARG_ENABLE(ufs2,
+  [  --disable-ufs2          disable UFS2 support in Stage 2])
+
+if test x"$enable_ufs2" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_UFS2=1"
+fi
+
 AC_ARG_ENABLE(minix,
   [  --disable-minix         disable Minix fs support in Stage 2])
 
diff -uNr grub/grub/Makefile.am grub/grub/Makefile.am
--- grub/grub/Makefile.am   Tue Jan 27 05:21:00 2004
+++ grub/grub/Makefile.am   Tue Jan 27 05:21:39 2004
@@ -7,6 +7,7 @@
 endif
 
 AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 \
+   -DFSYS_UFS2=1 \
    -DFSYS_FFS=1 -DFSYS_MINIX=1 -DSUPPORT_HERCULES=1 \
    $(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
    -I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
diff -uNr grub/stage2/Makefile.am grub/stage2/Makefile.am
--- grub/stage2/Makefile.am   Tue Jan 27 05:21:01 2004
+++ grub/stage2/Makefile.am   Tue Jan 27 05:40:00 2004
@@ -17,10 +17,12 @@
 noinst_LIBRARIES = libgrub.a
 libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
    disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_jfs.c \
+   fsys_ufs2.c \
    fsys_minix.c fsys_reiserfs.c fsys_vstafs.c fsys_xfs.c gunzip.c \
    md5.c serial.c stage2.c terminfo.c tparm.c graphics.c
 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
    -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+   -DFSYS_UFS2=1 \
    -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 -DFSYS_VSTAFS=1 \
    -DFSYS_XFS=1 -DUSE_MD5_PASSWORDS=1 \
    -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 -fwritable-strings
@@ -33,21 +35,25 @@
 if DISKLESS_SUPPORT
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
    jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
+   ufs2_stage1_5 \
    xfs_stage1_5 nbgrub pxegrub
 noinst_DATA = pre_stage2 start nbloader pxeloader diskless
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
    fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
    minix_stage1_5.exec reiserfs_stage1_5.exec \
+   ufs2_stage1_5.exec \
    vstafs_stage1_5.exec xfs_stage1_5.exec nbloader.exec \
    pxeloader.exec diskless.exec
 else
 pkgdata_DATA = stage2 e2fs_stage1_5 fat_stage1_5 ffs_stage1_5 \
    jfs_stage1_5 minix_stage1_5 reiserfs_stage1_5 vstafs_stage1_5 \
+   ufs2_stage1_5 \
    xfs_stage1_5
 noinst_DATA = pre_stage2 start
 noinst_PROGRAMS = pre_stage2.exec start.exec e2fs_stage1_5.exec \
    fat_stage1_5.exec ffs_stage1_5.exec jfs_stage1_5.exec \
    minix_stage1_5.exec reiserfs_stage1_5.exec \
+   ufs2_stage1_5.exec \
    vstafs_stage1_5.exec xfs_stage1_5.exec
 endif
 MOSTLYCLEANFILES = $(noinst_PROGRAMS)
@@ -84,6 +90,7 @@
 # For stage2 target.
 pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
    cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+   fsys_ufs2.c \
    fsys_fat.c fsys_ffs.c fsys_jfs.c fsys_minix.c fsys_reiserfs.c \
    fsys_vstafs.c fsys_xfs.c gunzip.c hercules.c md5.c serial.c \
    smp-imps.c stage2.c terminfo.c tparm.c
@@ -148,6 +155,15 @@
 ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
    -DNO_BLOCK_FILES=1
 ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ufs2_stage1_5 target.
+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+   stage1_5.c fsys_ufs2.c bios.c
+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+   -DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+   -DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
 
 # For minix_stage1_5 target.
 minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
diff -uNr grub/stage2/builtins.c grub/stage2/builtins.c
--- grub/stage2/builtins.c   Tue Jan 27 05:21:01 2004
+++ grub/stage2/builtins.c   Tue Jan 27 05:21:39 2004
@@ -3747,6 +3747,7 @@
   {
     {"ext2fs",   "/e2fs_stage1_5"},
     {"fat",      "/fat_stage1_5"},
+    {"ufs2",     "/ufs2_stage1_5"},
     {"ffs",      "/ffs_stage1_5"},
     {"jfs",      "/jfs_stage1_5"},
     {"minix",    "/minix_stage1_5"},
diff -uNr grub/stage2/disk_io.c grub/stage2/disk_io.c
--- grub/stage2/disk_io.c   Tue Jan 27 05:21:01 2004
+++ grub/stage2/disk_io.c   Tue Jan 27 05:21:39 2004
@@ -72,6 +72,9 @@
 # ifdef FSYS_XFS
   {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0},
 # endif
+# ifdef FSYS_UFS2
+  {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed},
+# endif
   /* XX FFS should come last as it's superblock is commonly crossing tracks
      on floppies from track 1 to 2, while others only use 1.  */
 # ifdef FSYS_FFS
diff -uNr grub/stage2/filesys.h grub/stage2/filesys.h
--- grub/stage2/filesys.h   Tue Jan 27 05:21:01 2004
+++ grub/stage2/filesys.h   Tue Jan 27 05:21:39 2004
@@ -30,6 +30,16 @@
 #define FSYS_FFS_NUM 0
 #endif
 
+#ifdef FSYS_UFS2
+#define FSYS_UFS2_NUM 1
+int ufs2_mount (void);
+int ufs2_read (char *buf, int len);
+int ufs2_dir (char *dirname);
+int ufs2_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_UFS2_NUM 0
+#endif
+
 #ifdef FSYS_FAT
 #define FSYS_FAT_NUM 1
 int fat_mount (void);
@@ -109,6 +119,7 @@
 #define NUM_FSYS   \
   (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM   \
    + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM   \
+   + FSYS_UFS2_NUM \
    + FSYS_TFTP_NUM)
 #endif
 
diff -uNr grub/stage2/fsys_ufs2.c grub/stage2/fsys_ufs2.c
--- grub/stage2/fsys_ufs2.c   Thu Jan  1 03:00:00 1970
+++ grub/stage2/fsys_ufs2.c   Wed Jan 28 03:18:54 2004
@@ -0,0 +1,305 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Elements of this file were originally from the FreeBSD "biosboot"
+ * bootloader file "disk.c" dated 4/12/95.
+ *
+ * The license and header comments from that file are included here.
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ *   from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
+ *   $Id: fsys_ufs2.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
+ */
+
+#ifdef FSYS_UFS2
+
+#include "shared.h"
+#include "filesys.h"
+
+#include "ufs2.h"
+
+/* used for filesystem map blocks */
+static int mapblock;
+static int mapblock_offset;
+static int mapblock_bsize;
+
+/* pointer to superblock */
+#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
+#define INODE ((struct ufs2_dinode *) ( FSYS_BUF + 16384 ))
+#define MAPBUF ( FSYS_BUF + 24576 )
+#define MAPBUF_LEN 8192
+

+int
+ufs2_mount (void)
+{
+  int retval = 1;
+
+  if ((((current_drive & 0x80) || (current_slice != 0))
+       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
+      || part_length < (SBLOCK_UFS2 + (SBLOCKSIZE / DEV_BSIZE))
+      || !devread (0, SBLOCK_UFS2, SBLOCKSIZE, (char *) SUPERBLOCK)
+      || SUPERBLOCK->fs_magic != FS_UFS2_MAGIC)
+    retval = 0;
+
+  mapblock = -1;
+  mapblock_offset = -1;

+  return retval;
+}
+
+static int64_t
+block_map (int file_block)
+{
+  int bnum, offset, bsize;

+  if (file_block < NDADDR)
+    return (INODE->di_db[file_block]);

+  /* If the blockmap loaded does not include FILE_BLOCK,
+     load a new blockmap.  */
+  if ((bnum = fsbtodb (SUPERBLOCK, INODE->di_ib[0])) != mapblock
+      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
+    {
+      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
+   {
+     offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
+     bsize = MAPBUF_LEN;
+    
+     if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
+       offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
+   }
+      else
+   {
+     bsize = SUPERBLOCK->fs_bsize;
+     offset = 0;
+   }
+     
+      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
+   {
+     mapblock = -1;
+     mapblock_bsize = -1;
+     mapblock_offset = -1;
+     errnum = ERR_FSYS_CORRUPT;
+     return -1;
+   }
+     
+      mapblock = bnum;
+      mapblock_bsize = bsize;
+      mapblock_offset = offset;
+    }

+  return (((int64_t *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
+           - mapblock_offset]);
+}
+
+int
+ufs2_read (char *buf, int len)
+{
+  int logno, off, size, ret = 0;
+  int64_t map;
+
+  while (len && !errnum)
+    {
+      off = blkoff (SUPERBLOCK, filepos);
+      logno = lblkno (SUPERBLOCK, filepos);
+      size = blksize (SUPERBLOCK, INODE, logno);
+
+      if ((map = block_map (logno)) < 0)
+   break;
+
+      size -= off;
+
+      if (size > len)
+   size = len;
+
+      disk_read_func = disk_read_hook;
+
+      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
+
+      disk_read_func = NULL;
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+int
+ufs2_dir (char *dirname)
+{
+  char *rest, ch;
+  int block, off, loc, ino = ROOTINO;
+  int64_t map;
+  struct direct *dp;
+
+/* main loop to find destination inode */
+loop:
+
+  /* load current inode (defaults to the root inode) */
+
+   if (!devread (fsbtodb (SUPERBLOCK, ino_to_fsba (SUPERBLOCK, ino)),
+                        ino % (SUPERBLOCK->fs_inopb) * sizeof (struct ufs2_dinode),
+                        sizeof (struct ufs2_dinode), (char *) INODE))
+         return 0;         /* XXX what return value? */
+
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+
+  if (!*dirname || isspace (*dirname))
+    {
+      if ((INODE->di_mode & IFMT) != IFREG)
+   {
+     errnum = ERR_BAD_FILETYPE;
+     return 0;
+   }
+
+      filemax = INODE->di_size;
+
+      /* incomplete implementation requires this! */
+      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
+      return 1;
+    }
+
+  /* continue with file/directory name interpretation */
+
+  while (*dirname == '/')
+    dirname++;
+
+  if (!(INODE->di_size) || ((INODE->di_mode & IFMT) != IFDIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+
+  *rest = 0;
+  loc = 0;
+
+  /* loop for reading a the entries in a directory */
+
+  do
+    {
+      if (loc >= INODE->di_size)
+   {
+#if 0
+     putchar ('\n');
+#endif
+
+     if (print_possibilities < 0)
+       return 1;
+
+     errnum = ERR_FILE_NOT_FOUND;
+     *rest = ch;
+     return 0;
+   }
+
+      if (!(off = blkoff (SUPERBLOCK, loc)))
+   {
+     block = lblkno (SUPERBLOCK, loc);
+
+     if ((map = block_map (block)) < 0
+         || !devread (fsbtodb (SUPERBLOCK, map), 0,
+            blksize (SUPERBLOCK, INODE, block),
+            (char *) FSYS_BUF))
+       {
+         errnum = ERR_FSYS_CORRUPT;
+         *rest = ch;
+         return 0;
+       }
+   }
+
+      dp = (struct direct *) (FSYS_BUF + off);
+      loc += dp->d_reclen;
+
+#ifndef STAGE1_5
+      if (dp->d_ino && print_possibilities && ch != '/'
+     && (!*dirname || substring (dirname, dp->d_name) <= 0))
+   {
+     if (print_possibilities > 0)
+       print_possibilities = -print_possibilities;
+
+     print_a_completion (dp->d_name);
+   }
+#endif /* STAGE1_5 */
+    }
+  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
+         || (print_possibilities && ch != '/')));
+
+  /* only get here if we have a matching directory entry */
+
+  ino = dp->d_ino;
+  *(dirname = rest) = ch;
+
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+int
+ufs2_embed (int *start_sector, int needed_sectors)
+{
+  /* XXX: I don't know if this is really correct. Someone who is
+     familiar with BSD should check for this.  */
+  if (needed_sectors > 14)
+    return 0;

+  *start_sector = 1;
+#if 1
+  /* FIXME: Disable the embedding in FFS until someone checks if
+     the code above is correct.  */
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+#endif /* FSYS_UFS2 */
diff -uNr grub/stage2/shared.h grub/stage2/shared.h
--- grub/stage2/shared.h   Tue Jan 27 05:21:01 2004
+++ grub/stage2/shared.h   Tue Jan 27 05:21:39 2004
@@ -205,6 +205,7 @@
 #define STAGE2_ID_VSTAFS_STAGE1_5   6
 #define STAGE2_ID_JFS_STAGE1_5      7
 #define STAGE2_ID_XFS_STAGE1_5      8
+#define STAGE2_ID_UFS2_STAGE1_5         9
 
 #ifndef STAGE1_5
 # define STAGE2_ID   STAGE2_ID_STAGE2
@@ -225,6 +226,8 @@
 #  define STAGE2_ID   STAGE2_ID_JFS_STAGE1_5
 # elif defined(FSYS_XFS)
 #  define STAGE2_ID   STAGE2_ID_XFS_STAGE1_5
+# elif defined(FSYS_UFS2)
+#  define STAGE2_ID   STAGE2_ID_UFS2_STAGE1_5
 # else
 #  error "unknown Stage 2"
 # endif
diff -uNr grub/stage2/size_test grub/stage2/size_test
--- grub/stage2/size_test   Tue Jan 27 05:21:01 2004
+++ grub/stage2/size_test   Tue Jan 27 05:21:39 2004
@@ -40,6 +40,8 @@
 # The bootloader area of a FFS partition is 14 sectors.
 check ffs_stage1_5 7168
 
+check ufs2_stage1_5 7168
+
 # Stage 1.5 can be installed in the sectors immediately after MBR in the
 # first cylinder, so the size is (63 - 1) sectors.
 check fat_stage1_5 31744
diff -uNr grub/stage2/ufs2.h grub/stage2/ufs2.h
--- grub/stage2/ufs2.h   Thu Jan  1 03:00:00 1970
+++ grub/stage2/ufs2.h   Wed Jan 28 03:14:21 2004
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * Copyright (c) 1982, 1989, 1993
+ *   The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *   @(#)dinode.h   8.3 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.11 2002/07/16 22:36:00 mckusick Exp $
+ */
+
+#ifndef _GRUB_UFS2_H_
+#define _GRUB_UFS2_H_
+
+typedef signed char            int8_t;
+typedef signed short           int16_t;
+typedef signed int             int32_t;
+typedef signed long long int   int64_t;
+typedef unsigned char          uint8_t;
+typedef unsigned short         uint16_t;
+typedef unsigned int           uint32_t;
+typedef unsigned long long int uint64_t;
+
+typedef uint8_t                u_char;
+typedef uint32_t               u_int;
+
+typedef uint8_t                u_int8_t;
+typedef uint16_t               u_int16_t;
+typedef uint32_t               u_int32_t;
+typedef uint64_t               u_int64_t;
+
+/*
+ * __uint* constants already defined in
+ * FreeBSD's /usr/include/machine/_types.h
+ */
+#ifndef _MACHINE__TYPES_H_
+typedef uint8_t                __uint8_t;
+typedef uint16_t               __uint16_t;
+typedef uint32_t               __uint32_t;
+typedef uint64_t               __uint64_t;
+#endif /* _MACHINE__TYPES_H_ */
+
+#define i_size di_size
+
+
+#define DEV_BSIZE 512
+
+/*
+ * The root inode is the root of the filesystem.  Inode 0 can't be used for
+ * normal purposes and historically bad blocks were linked to inode 1, thus
+ * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
+ * numerous dump tapes make this assumption, so we are stuck with it).
+ */
+#define   ROOTINO   ((ino_t)2)
+
+/*
+ * The size of physical and logical block numbers and time fields in UFS.
+ */
+typedef   int64_t   ufs2_daddr_t;
+typedef int64_t ufs_lbn_t;
+typedef int64_t ufs_time_t;
+
+/* inode number */
+typedef __uint32_t      ino_t;
+
+/* File permissions. */
+#define   IEXEC      0000100      /* Executable. */
+#define   IWRITE      0000200      /* Writeable. */
+#define   IREAD      0000400      /* Readable. */
+#define   ISVTX      0001000      /* Sticky bit. */
+#define   ISGID      0002000      /* Set-gid. */
+#define   ISUID      0004000      /* Set-uid. */
+
+/* File types. */
+#define   IFMT      0170000      /* Mask of file type. */
+#define   IFIFO      0010000      /* Named pipe (fifo). */
+#define   IFCHR      0020000      /* Character device. */
+#define   IFDIR      0040000      /* Directory file. */
+#define   IFBLK      0060000      /* Block device. */
+#define   IFREG      0100000      /* Regular file. */
+#define   IFLNK      0120000      /* Symbolic link. */
+#define   IFSOCK      0140000      /* UNIX domain socket. */
+#define   IFWHT      0160000      /* Whiteout. */
+
+/*
+ * A dinode contains all the meta-data associated with a UFS2 file.
+ * This structure defines the on-disk format of a dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+
+#define   NXADDR   2         /* External addresses in inode. */
+#define   NDADDR   12         /* Direct addresses in inode. */
+#define   NIADDR   3         /* Indirect addresses in inode. */
+
+struct ufs2_dinode {
+   u_int16_t   di_mode;   /*   0: IFMT, permissions; see below. */
+   int16_t      di_nlink;   /*   2: File link count. */
+   u_int32_t   di_uid;      /*   4: File owner. */
+   u_int32_t   di_gid;      /*   8: File group. */
+   u_int32_t   di_blksize;   /*  12: Inode blocksize. */
+   u_int64_t   di_size;   /*  16: File byte count. */
+   u_int64_t   di_blocks;   /*  24: Bytes actually held. */
+   ufs_time_t   di_atime;   /*  32: Last access time. */
+   ufs_time_t   di_mtime;   /*  40: Last modified time. */
+   ufs_time_t   di_ctime;   /*  48: Last inode change time. */
+   ufs_time_t   di_birthtime;   /*  56: Inode creation time. */
+   int32_t      di_mtimensec;   /*  64: Last modified time. */
+   int32_t      di_atimensec;   /*  68: Last access time. */
+   int32_t      di_ctimensec;   /*  72: Last inode change time. */
+   int32_t      di_birthnsec;   /*  76: Inode creation time. */
+   int32_t      di_gen;      /*  80: Generation number. */
+   u_int32_t   di_kernflags;   /*  84: Kernel flags. */
+   u_int32_t   di_flags;   /*  88: Status flags (chflags). */
+   int32_t      di_extsize;   /*  92: External attributes block. */
+   ufs2_daddr_t   di_extb[NXADDR];/*  96: External attributes block. */
+   ufs2_daddr_t   di_db[NDADDR];   /* 112: Direct disk blocks. */
+   ufs2_daddr_t   di_ib[NIADDR];   /* 208: Indirect disk blocks. */
+   int64_t      di_spare[3];   /* 232: Reserved; currently unused */
+};
+
+#define   MAXNAMLEN   255
+
+struct   direct {
+   u_int32_t d_ino;      /* inode number of entry */
+   u_int16_t d_reclen;      /* length of this record */
+   u_int8_t  d_type;       /* file type, see below */
+   u_int8_t  d_namlen;      /* length of string in d_name */
+   char     d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
+};
+
+/*
+ * File types
+ */
+#define DT_UNKNOWN       0
+#define DT_FIFO          1
+#define DT_CHR           2
+#define DT_DIR           4
+#define DT_BLK           6
+#define DT_REG           8
+#define DT_LNK          10
+#define DT_SOCK         12
+#define DT_WHT          14
+
+#define SBLOCK_UFS2    65536
+#define SBLOCKSIZE     8192
+
+#define MAXMNTLEN   512
+
+#define   NOCSPTRS   ((128 / sizeof(void *)) - 4)
+
+/*
+ * The maximum number of snapshot nodes that can be associated
+ * with each filesystem. This limit affects only the number of
+ * snapshot files that can be recorded within the superblock so
+ * that they can be found when the filesystem is mounted. However,
+ * maintaining too many will slow the filesystem performance, so
+ * having this limit is a good idea.
+ */
+#define FSMAXSNAP 20
+   
+/*
+ * Per cylinder group information; summarized in blocks allocated
+ * from first cylinder group data blocks.  These blocks have to be
+ * read in from fs_csaddr (size fs_cssize) in addition to the
+ * super block.
+ */
+struct csum {
+   int32_t   cs_ndir;      /* number of directories */
+   int32_t   cs_nbfree;      /* number of free blocks */
+   int32_t   cs_nifree;      /* number of free inodes */
+   int32_t   cs_nffree;      /* number of free frags */
+};
+
+struct csum_total {
+   int64_t   cs_ndir;      /* number of directories */
+   int64_t   cs_nbfree;      /* number of free blocks */
+   int64_t   cs_nifree;      /* number of free inodes */
+   int64_t   cs_nffree;      /* number of free frags */
+   int64_t   cs_numclusters;      /* number of free clusters */
+   int64_t   cs_spare[3];      /* future expansion */
+};
+
+/*
+ * Super block for an FFS filesystem.
+ */
+struct fs {
+   int32_t    fs_firstfield;      /* historic filesystem linked list, */
+   int32_t    fs_unused_1;      /*     used for incore super blocks */
+   int32_t    fs_sblkno;      /* offset of super-block in filesys */
+   int32_t    fs_cblkno;      /* offset of cyl-block in filesys */
+   int32_t    fs_iblkno;      /* offset of inode-blocks in filesys */
+   int32_t    fs_dblkno;      /* offset of first data after cg */
+   int32_t    fs_old_cgoffset;   /* cylinder group offset in cylinder */
+   int32_t    fs_old_cgmask;      /* used to calc mod fs_ntrak */
+   int32_t  fs_old_time;      /* last time written */
+   int32_t    fs_old_size;      /* number of blocks in fs */
+   int32_t    fs_old_dsize;      /* number of data blocks in fs */
+   int32_t    fs_ncg;      /* number of cylinder groups */
+   int32_t    fs_bsize;      /* size of basic blocks in fs */
+   int32_t    fs_fsize;      /* size of frag blocks in fs */
+   int32_t    fs_frag;      /* number of frags in a block in fs */
+/* these are configuration parameters */
+   int32_t    fs_minfree;      /* minimum percentage of free blocks */
+   int32_t    fs_old_rotdelay;   /* num of ms for optimal next block */
+   int32_t    fs_old_rps;      /* disk revolutions per second */
+/* these fields can be computed from the others */
+   int32_t    fs_bmask;      /* ``blkoff'' calc of blk offsets */
+   int32_t    fs_fmask;      /* ``fragoff'' calc of frag offsets */
+   int32_t    fs_bshift;      /* ``lblkno'' calc of logical blkno */
+   int32_t    fs_fshift;      /* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+   int32_t    fs_maxcontig;      /* max number of contiguous blks */
+   int32_t    fs_maxbpg;      /* max number of blks per cyl group */
+/* these fields can be computed from the others */
+   int32_t    fs_fragshift;      /* block to frag shift */
+   int32_t    fs_fsbtodb;      /* fsbtodb and dbtofsb shift constant */
+   int32_t    fs_sbsize;      /* actual size of super block */
+   int32_t    fs_spare1[2];      /* old fs_csmask */
+               /* old fs_csshift */
+   int32_t    fs_nindir;      /* value of NINDIR */
+   int32_t    fs_inopb;      /* value of INOPB */
+   int32_t    fs_old_nspf;      /* value of NSPF */
+/* yet another configuration parameter */
+   int32_t    fs_optim;      /* optimization preference, see below */
+   int32_t    fs_old_npsect;      /* # sectors/track including spares */
+   int32_t    fs_old_interleave;   /* hardware sector interleave */
+   int32_t    fs_old_trackskew;   /* sector 0 skew, per track */
+   int32_t    fs_id[2];      /* unique filesystem id */
+/* sizes determined by number of cylinder groups and their sizes */
+   int32_t    fs_old_csaddr;      /* blk addr of cyl grp summary area */
+   int32_t    fs_cssize;      /* size of cyl grp summary area */
+   int32_t    fs_cgsize;      /* cylinder group size */
+   int32_t    fs_spare2;      /* old fs_ntrak */
+   int32_t    fs_old_nsect;      /* sectors per track */
+   int32_t  fs_old_spc;      /* sectors per cylinder */
+   int32_t    fs_old_ncyl;      /* cylinders in filesystem */
+   int32_t    fs_old_cpg;      /* cylinders per group */
+   int32_t    fs_ipg;      /* inodes per group */
+   int32_t    fs_fpg;      /* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+   struct   csum fs_old_cstotal;   /* cylinder summary information */
+/* these fields are cleared at mount time */
+   int8_t   fs_fmod;      /* super block modified flag */
+   int8_t   fs_clean;      /* filesystem is clean flag */
+   int8_t     fs_ronly;      /* mounted read-only flag */
+   int8_t   fs_old_flags;      /* old FS_ flags */
+   u_char    fs_fsmnt[MAXMNTLEN];   /* name mounted on */
+/* these fields retain the current block allocation info */
+   int32_t    fs_cgrotor;      /* last cg searched */
+   void    *fs_ocsp[NOCSPTRS];   /* padding; was list of fs_cs buffers */
+   u_int8_t *fs_contigdirs;   /* # of contiguously allocated dirs */
+   struct   csum *fs_csp;      /* cg summary info buffer for fs_cs */
+   int32_t   *fs_maxcluster;      /* max cluster in each cyl group */
+   u_int   *fs_active;      /* used by snapshots to track fs */
+   int32_t    fs_old_cpc;      /* cyl per cycle in postbl */
+   int32_t    fs_maxbsize;      /* maximum blocking factor permitted */
+   int64_t    fs_sparecon64[17];   /* old rotation block list head */
+   int64_t    fs_sblockloc;      /* byte offset of standard superblock */
+   struct   csum_total fs_cstotal;   /* cylinder summary information */
+   ufs_time_t fs_time;      /* last time written */
+   int64_t    fs_size;      /* number of blocks in fs */
+   int64_t    fs_dsize;      /* number of data blocks in fs */
+   ufs2_daddr_t fs_csaddr;      /* blk addr of cyl grp summary area */
+   int64_t    fs_pendingblocks;   /* blocks in process of being freed */
+   int32_t    fs_pendinginodes;   /* inodes in process of being freed */
+   int32_t    fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
+   int32_t    fs_avgfilesize;   /* expected average file size */
+   int32_t    fs_avgfpdir;      /* expected # of files per directory */
+   int32_t    fs_save_cgsize;   /* save real cg size to use fs_bsize */
+   int32_t    fs_sparecon32[26];   /* reserved for future constants */
+   int32_t  fs_flags;      /* see FS_ flags below */
+   int32_t    fs_contigsumsize;   /* size of cluster summary array */
+   int32_t    fs_maxsymlinklen;   /* max length of an internal symlink */
+   int32_t    fs_old_inodefmt;   /* format of on-disk inodes */
+   u_int64_t fs_maxfilesize;   /* maximum representable file size */
+   int64_t    fs_qbmask;      /* ~fs_bmask for use with 64-bit size */
+   int64_t    fs_qfmask;      /* ~fs_fmask for use with 64-bit size */
+   int32_t    fs_state;      /* validate fs_clean field */
+   int32_t    fs_old_postblformat;   /* format of positional layout tables */
+   int32_t    fs_old_nrpos;      /* number of rotational positions */
+   int32_t    fs_spare5[2];      /* old fs_postbloff */
+               /* old fs_rotbloff */
+   int32_t    fs_magic;      /* magic number */
+};
+
+/*
+ * Filesystem identification
+ */
+#define   FS_UFS2_MAGIC   0x19540119   /* UFS2 fast filesystem magic number */
+
+/*
+ * Turn filesystem block numbers into disk block addresses.
+ * This maps filesystem blocks to device size blocks.
+ */
+#define fsbtodb(fs, b)   ((b) << (fs)->fs_fsbtodb)
+#define   dbtofsb(fs, b)   ((b) >> (fs)->fs_fsbtodb)
+
+/*
+ * Cylinder group macros to locate things in cylinder groups.
+ * They calc filesystem addresses of cylinder group data structures.
+ */
+#define   cgbase(fs, c)   ((ufs2_daddr_t)((fs)->fs_fpg * (c)))
+#define   cgimin(fs, c)   (cgstart(fs, c) + (fs)->fs_iblkno)   /* inode blk */
+#define cgstart(fs, c)                     \
+       ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) :      \
+       (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask))))
+
+/*
+ * Macros for handling inode numbers:
+ *     inode number to filesystem block offset.
+ *     inode number to cylinder group number.
+ *     inode number to filesystem block address.
+ */
+#define   ino_to_cg(fs, x)   ((x) / (fs)->fs_ipg)
+#define   ino_to_fsba(fs, x)                  \
+   ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +         \
+       (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
+#define   ino_to_fsbo(fs, x)   ((x) % INOPB(fs))
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc)      /* calculates (loc % fs->fs_bsize) */ \
+   ((loc) & (fs)->fs_qbmask)
+
+/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
+#define smalllblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
+   ((blk) << (fs)->fs_bshift)
+
+
+#define lblkno(fs, loc)      /* calculates (loc / fs->fs_bsize) */ \
+   ((loc) >> (fs)->fs_bshift)
+
+#define fragroundup(fs, size)   /* calculates roundup(size, fs->fs_fsize) */ \
+   (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
+
+#define fragstoblks(fs, frags)   /* calculates (frags / fs->fs_frag) */ \
+   ((frags) >> (fs)->fs_fragshift)
+#define blkstofrags(fs, blks)   /* calculates (blks * fs->fs_frag) */ \
+   ((blks) << (fs)->fs_fragshift)
+#define fragnum(fs, fsb)   /* calculates (fsb % fs->fs_frag) */ \
+   ((fsb) & ((fs)->fs_frag - 1))
+#define blknum(fs, fsb)      /* calculates rounddown(fsb, fs->fs_frag) */ \
+   ((fsb) &~ ((fs)->fs_frag - 1))
+
+/*
+ * Determining the size of a file block in the filesystem.
+ */
+#define blksize(fs, ip, lbn) \
+   (((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
+       ? (fs)->fs_bsize \
+       : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define sblksize(fs, size, lbn) \
+   (((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
+     ? (fs)->fs_bsize \
+     : (fragroundup(fs, blkoff(fs, (size)))))
+
+
+/*
+ * Number of inodes in a secondary storage block/fragment.
+ */
+#define   INOPB(fs)   ((fs)->fs_inopb)
+#define   INOPF(fs)   ((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * Number of indirects in a filesystem block.
+ */
+#define   NINDIR(fs)   ((fs)->fs_nindir)
+
+#endif /* _GRUB_UFS2_H_ */
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum