diff options
Diffstat (limited to 'qemu/roms/openbios/fs/grubfs/fsys_ufs.c')
-rw-r--r-- | qemu/roms/openbios/fs/grubfs/fsys_ufs.c | 391 |
1 files changed, 0 insertions, 391 deletions
diff --git a/qemu/roms/openbios/fs/grubfs/fsys_ufs.c b/qemu/roms/openbios/fs/grubfs/fsys_ufs.c deleted file mode 100644 index 8e0a0f776..000000000 --- a/qemu/roms/openbios/fs/grubfs/fsys_ufs.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (c) 2000, 2001 Free Software Foundation, Inc. - * Copyright (c) 2005 Rink Springer - * - * This file is based on FreeBSD 5.4-RELEASE's /sys/boot/common/ufsread.c, - * and has some minor patches so it'll work with Cromwell/GRUB. - * - */ -/*- - * Copyright (c) 2002 McAfee, Inc. - * All rights reserved. - * - * This software was developed for the FreeBSD Project by Marshall - * Kirk McKusick and McAfee Research,, the Security Research Division of - * McAfee, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as - * part of the DARPA CHATS research program - * - * 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. - * - * 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. - */ -/*- - * Copyright (c) 1998 Robert Nordier - * All rights reserved. - * - * Redistribution and use in source and binary forms are freely - * permitted provided that the above copyright notice and this - * paragraph and the following disclaimer are duplicated in all - * such forms. - * - * This software is provided "AS IS" and without any express or - * implied warranties, including, without limitation, the implied - * warranties of merchantability and fitness for a particular - * purpose. - */ -#ifdef FSYS_UFS - -#include "asm/types.h" - -#include "shared.h" -#include "filesys.h" - -#include "ufs_dinode.h" -#include "ufs_fs.h" - -#ifdef __i386__ -/* XXX: Revert to old (broken for over 1.5Tb filesystems) version of cgbase - (see sys/ufs/ffs/fs.h rev 1.39) so that i386 boot loader (boot2) can - support both UFS1 and UFS2 again. */ -#undef cgbase -#define cgbase(fs, c) ((ufs2_daddr_t)((fs)->fs_fpg * (c))) -#endif - -/* - * We use 4k `virtual' blocks for filesystem data, whatever the actual - * filesystem block size. FFS blocks are always a multiple of 4k. - */ -#define VBLKSHIFT 12 -#define VBLKSIZE (1 << VBLKSHIFT) -#define VBLKMASK (VBLKSIZE - 1) -#define DBPERVBLK (VBLKSIZE / DEV_BSIZE) -#define INDIRPERVBLK(fs) (NINDIR(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) -#define IPERVBLK(fs) (INOPB(fs) / ((fs)->fs_bsize >> VBLKSHIFT)) -#define INO_TO_VBA(fs, ipervblk, x) \ - (fsbtodb(fs, cgimin(fs, ino_to_cg(fs, x))) + \ - (((x) % (fs)->fs_ipg) / (ipervblk) * DBPERVBLK)) -#define INO_TO_VBO(ipervblk, x) ((x) % ipervblk) -#define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \ - ((off) / VBLKSIZE) * DBPERVBLK) -#define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK) - -/* Buffers that must not span a 64k boundary. */ -struct dmadat { - char blkbuf[VBLKSIZE]; /* filesystem blocks */ - char indbuf[VBLKSIZE]; /* indir blocks */ - char sbbuf[SBLOCKSIZE]; /* superblock */ - char secbuf[DEV_BSIZE]; /* for MBR/disklabel */ -}; -static struct dmadat *dmadat = (struct dmadat*)FSYS_BUF; - -#define SUPERBLOCK ((struct fs*)dmadat->sbbuf) - -ino_t lookup(const char *); -ssize_t fsread(ino_t, void *, size_t); - -static int dsk_meta; -static uint32_t fs_off; -static ino_t cur_ino = 0; - -static inline int -dskread (void* buf, unsigned lba, unsigned nblk) -{ - return !devread (lba, 0, nblk * DEV_BSIZE, buf) ? -1 : 0; -} - -#if defined(UFS2_ONLY) -#define DIP(field) dp2.field -#elif defined(UFS1_ONLY) -#define DIP(field) dp1.field -#else -#define DIP(field) fs->fs_magic == FS_UFS1_MAGIC ? dp1.field : dp2.field -#endif - -static __inline int -fsfind(const char *name, ino_t * ino) -{ - char buf[DEV_BSIZE]; - struct ufs_dirent *d; - char *s; - ssize_t n; -#ifndef UFS2_ONLY - static struct ufs1_dinode dp1; -#endif -#ifndef UFS1_ONLY - static struct ufs2_dinode dp2; -#endif - char* blkbuf = dmadat->blkbuf; - struct fs* fs = (struct fs *)dmadat->sbbuf; - - fs_off = 0; - while ((n = fsread(*ino, buf, DEV_BSIZE)) > 0) - for (s = buf; s < buf + DEV_BSIZE;) { - d = (void *)s; - if (!strcmp(name, d->d_name)) { - *ino = d->d_fileno; - - /* below is for grub, which wants the file size - */ - n = IPERVBLK(fs); - if (dskread(blkbuf, INO_TO_VBA(fs, n, (*ino)), DBPERVBLK)) - return -1; - n = INO_TO_VBO(n, (*ino)); -#if defined(UFS1_ONLY) - dp1 = ((struct ufs1_dinode *)blkbuf)[n]; -#elif defined(UFS2_ONLY) - dp2 = ((struct ufs2_dinode *)blkbuf)[n]; -#else - if (fs->fs_magic == FS_UFS1_MAGIC) - dp1 = ((struct ufs1_dinode *)blkbuf)[n]; - else - dp2 = ((struct ufs2_dinode *)blkbuf)[n]; -#endif - - filemax = DIP(di_size); - return d->d_type; - } - s += d->d_reclen; - } - return 0; -} - -ino_t -lookup(const char *path) -{ - char name[MAXNAMLEN + 1]; - const char *s; - ino_t ino; - ssize_t n; - int dt; - - ino = ROOTINO; - dt = DT_DIR; - name[0] = '/'; - name[1] = '\0'; - for (;;) { - if (*path == '/') - path++; - if (!*path) - break; - for (s = path; *s && *s != '/'; s++); - if ((n = s - path) > MAXNAMLEN) - return 0; - memcpy(name, path, n); - name[n] = 0; - if (dt != DT_DIR) { - printk("%s: not a directory.\n", name); - return (0); - } - if ((dt = fsfind(name, &ino)) <= 0) - break; - path = s; - } - return dt == DT_REG ? ino : 0; -} - -/* - * Possible superblock locations ordered from most to least likely. - */ -static const int sblock_try[] = SBLOCKSEARCH; - -ssize_t -fsread(ino_t inode, void *buf, size_t nbyte) -{ -#ifndef UFS2_ONLY - static struct ufs1_dinode dp1; -#endif -#ifndef UFS1_ONLY - static struct ufs2_dinode dp2; -#endif - static ino_t inomap; - char *blkbuf; - void *indbuf; - struct fs *fs; - char *s; - size_t n, nb, size, off, vboff; - ufs_lbn_t lbn; - ufs2_daddr_t addr, vbaddr; - static ufs2_daddr_t blkmap, indmap; - unsigned int u; - - - blkbuf = dmadat->blkbuf; - indbuf = dmadat->indbuf; - fs = (struct fs *)dmadat->sbbuf; - if (!dsk_meta) { - inomap = 0; - for (n = 0; sblock_try[n] != -1; n++) { - if (dskread(fs, sblock_try[n] / DEV_BSIZE, - SBLOCKSIZE / DEV_BSIZE)) - return -1; - if (( -#if defined(UFS1_ONLY) - fs->fs_magic == FS_UFS1_MAGIC -#elif defined(UFS2_ONLY) - (fs->fs_magic == FS_UFS2_MAGIC && - fs->fs_sblockloc == sblock_try[n]) -#else - fs->fs_magic == FS_UFS1_MAGIC || - (fs->fs_magic == FS_UFS2_MAGIC && - fs->fs_sblockloc == sblock_try[n]) -#endif - ) && - fs->fs_bsize <= MAXBSIZE && - fs->fs_bsize >= sizeof(struct fs)) - break; - } - if (sblock_try[n] == -1) { - printk("Not ufs\n"); - return -1; - } - dsk_meta++; - } - if (!inode) - return 0; - if (inomap != inode) { - n = IPERVBLK(fs); - if (dskread(blkbuf, INO_TO_VBA(fs, n, inode), DBPERVBLK)) - return -1; - n = INO_TO_VBO(n, inode); -#if defined(UFS1_ONLY) - dp1 = ((struct ufs1_dinode *)blkbuf)[n]; -#elif defined(UFS2_ONLY) - dp2 = ((struct ufs2_dinode *)blkbuf)[n]; -#else - if (fs->fs_magic == FS_UFS1_MAGIC) - dp1 = ((struct ufs1_dinode *)blkbuf)[n]; - else - dp2 = ((struct ufs2_dinode *)blkbuf)[n]; -#endif - inomap = inode; - fs_off = 0; - blkmap = indmap = 0; - } - s = buf; - size = DIP(di_size); - n = size - fs_off; - if (nbyte > n) - nbyte = n; - nb = nbyte; - while (nb) { - lbn = lblkno(fs, fs_off); - off = blkoff(fs, fs_off); - if (lbn < NDADDR) { - addr = DIP(di_db[lbn]); - } else if (lbn < NDADDR + NINDIR(fs)) { - n = INDIRPERVBLK(fs); - addr = DIP(di_ib[0]); - u = (unsigned int)(lbn - NDADDR) / (n * DBPERVBLK); - vbaddr = fsbtodb(fs, addr) + u; - if (indmap != vbaddr) { - if (dskread(indbuf, vbaddr, DBPERVBLK)) - return -1; - indmap = vbaddr; - } - n = (lbn - NDADDR) & (n - 1); -#if defined(UFS1_ONLY) - addr = ((ufs1_daddr_t *)indbuf)[n]; -#elif defined(UFS2_ONLY) - addr = ((ufs2_daddr_t *)indbuf)[n]; -#else - if (fs->fs_magic == FS_UFS1_MAGIC) - addr = ((ufs1_daddr_t *)indbuf)[n]; - else - addr = ((ufs2_daddr_t *)indbuf)[n]; -#endif - } else { - return -1; - } - vbaddr = fsbtodb(fs, addr) + (off >> VBLKSHIFT) * DBPERVBLK; - vboff = off & VBLKMASK; - n = sblksize(fs, size, lbn) - (off & ~VBLKMASK); - if (n > VBLKSIZE) - n = VBLKSIZE; - if (blkmap != vbaddr) { - if (dskread(blkbuf, vbaddr, n >> DEV_BSHIFT)) - return -1; - blkmap = vbaddr; - } - n -= vboff; - if (n > nb) - n = nb; - memcpy(s, blkbuf + vboff, n); - s += n; - fs_off += n; - nb -= n; - } - return nbyte; -} - -int -ufs_mount (void) -{ - int i, retval = 0; - - /* - * We don't care about stuff being in disklabels or not. If the magic - * matches, we're good to go. - */ - for (i = 0; sblock_try[i] != -1; ++i) - { - if (! (part_length < (sblock_try[i] + (SBLOCKSIZE / DEV_BSIZE)) - || ! devread (0, sblock_try[i], SBLOCKSIZE, (char *) SUPERBLOCK))) - { - if ( -#if defined(UFS1_ONLY) - SUPERBLOCK->fs_magic == FS_UFS1_MAGIC -#elif defined(UFS2_ONLY) - (SUPERBLOCK->fs_magic == FS_UFS2_MAGIC && - SUPERBLOCK->fs_sblockloc == sblock_try[i]) -#else - SUPERBLOCK->fs_magic == FS_UFS1_MAGIC || - (SUPERBLOCK->fs_magic == FS_UFS2_MAGIC && - SUPERBLOCK->fs_sblockloc == sblock_try[i]) -#endif - ) { - retval = 1; break; - } - } - } - return retval; -} - -int -ufs_read (char *buf, int len) -{ - return fsread(cur_ino, buf, len); -} - -int -ufs_dir (char *dirname) -{ - cur_ino = lookup(dirname); - return cur_ino & 0xffffffff; -} - -int -ufs_embed (int* start_sector, int needed_sectors) -{ - /* TODO; unused by Cromwell */ - return 0; -} - -#endif /* FSYS_UFS */ |