Annotation of qemu/roms/openbios/fs/grubfs/fsys_ffs.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  GRUB  --  GRand Unified Bootloader
        !             3:  *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
        !             4:  *
        !             5:  *  This program is free software; you can redistribute it and/or modify
        !             6:  *  it under the terms of the GNU General Public License as published by
        !             7:  *  the Free Software Foundation; either version 2 of the License, or
        !             8:  *  (at your option) any later version.
        !             9:  *
        !            10:  *  This program is distributed in the hope that it will be useful,
        !            11:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13:  *  GNU General Public License for more details.
        !            14:  *
        !            15:  *  You should have received a copy of the GNU General Public License
        !            16:  *  along with this program; if not, write to the Free Software
        !            17:  *  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
        !            18:  *  MA 02110-1301, USA.
        !            19:  */
        !            20: 
        !            21: /*
        !            22:  * Elements of this file were originally from the FreeBSD "biosboot"
        !            23:  * bootloader file "disk.c" dated 4/12/95.
        !            24:  *
        !            25:  * The license and header comments from that file are included here.
        !            26:  */
        !            27: 
        !            28: /*
        !            29:  * Mach Operating System
        !            30:  * Copyright (c) 1992, 1991 Carnegie Mellon University
        !            31:  * All Rights Reserved.
        !            32:  *
        !            33:  * Permission to use, copy, modify and distribute this software and its
        !            34:  * documentation is hereby granted, provided that both the copyright
        !            35:  * notice and this permission notice appear in all copies of the
        !            36:  * software, derivative works or modified versions, and any portions
        !            37:  * thereof, and that both notices appear in supporting documentation.
        !            38:  *
        !            39:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            40:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            41:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            42:  *
        !            43:  * Carnegie Mellon requests users of this software to return to
        !            44:  *
        !            45:  *  Software Distribution Coordinator  or  [email protected]
        !            46:  *  School of Computer Science
        !            47:  *  Carnegie Mellon University
        !            48:  *  Pittsburgh PA 15213-3890
        !            49:  *
        !            50:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            51:  * the rights to redistribute these changes.
        !            52:  *
        !            53:  *     from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
        !            54:  *     $Id: fsys_ffs.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
        !            55:  */
        !            56: 
        !            57: #ifdef FSYS_FFS
        !            58: 
        !            59: #include "shared.h"
        !            60: 
        !            61: #include "filesys.h"
        !            62: 
        !            63: #include "defs.h"
        !            64: #include "disk_inode.h"
        !            65: #include "disk_inode_ffs.h"
        !            66: #include "dir.h"
        !            67: #include "fs.h"
        !            68: 
        !            69: /* used for filesystem map blocks */
        !            70: static int mapblock;
        !            71: static int mapblock_offset;
        !            72: static int mapblock_bsize;
        !            73: 
        !            74: /* pointer to superblock */
        !            75: #define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
        !            76: #define INODE ((struct icommon *) ( FSYS_BUF + 16384 ))
        !            77: #define MAPBUF ( FSYS_BUF + 24576 )
        !            78: #define MAPBUF_LEN 8192
        !            79: 
        !            80: 
        !            81: int
        !            82: ffs_mount (void)
        !            83: {
        !            84:   int retval = 1;
        !            85: 
        !            86:   if ((((current_drive & 0x80) || (current_slice != 0))
        !            87:        && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
        !            88:       || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
        !            89:       || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
        !            90:       || SUPERBLOCK->fs_magic != FS_MAGIC)
        !            91:     retval = 0;
        !            92: 
        !            93:   mapblock = -1;
        !            94:   mapblock_offset = -1;
        !            95: 
        !            96:   return retval;
        !            97: }
        !            98: 
        !            99: static int
        !           100: block_map (int file_block)
        !           101: {
        !           102:   int bnum, offset, bsize;
        !           103: 
        !           104:   if (file_block < NDADDR)
        !           105:     return (INODE->i_db[file_block]);
        !           106: 
        !           107:   /* If the blockmap loaded does not include FILE_BLOCK,
        !           108:      load a new blockmap.  */
        !           109:   if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock
        !           110:       || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
        !           111:     {
        !           112:       if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
        !           113:        {
        !           114:          offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
        !           115:          bsize = MAPBUF_LEN;
        !           116: 
        !           117:          if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
        !           118:            offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
        !           119:        }
        !           120:       else
        !           121:        {
        !           122:          bsize = SUPERBLOCK->fs_bsize;
        !           123:          offset = 0;
        !           124:        }
        !           125: 
        !           126:       if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
        !           127:        {
        !           128:          mapblock = -1;
        !           129:          mapblock_bsize = -1;
        !           130:          mapblock_offset = -1;
        !           131:          errnum = ERR_FSYS_CORRUPT;
        !           132:          return -1;
        !           133:        }
        !           134: 
        !           135:       mapblock = bnum;
        !           136:       mapblock_bsize = bsize;
        !           137:       mapblock_offset = offset;
        !           138:     }
        !           139: 
        !           140:   return (((int *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
        !           141:                          - mapblock_offset]);
        !           142: }
        !           143: 
        !           144: 
        !           145: int
        !           146: ffs_read (char *buf, int len)
        !           147: {
        !           148:   int logno, off, size, map, ret = 0;
        !           149: 
        !           150:   while (len && !errnum)
        !           151:     {
        !           152:       off = blkoff (SUPERBLOCK, filepos);
        !           153:       logno = lblkno (SUPERBLOCK, filepos);
        !           154:       size = blksize (SUPERBLOCK, INODE, logno);
        !           155: 
        !           156:       if ((map = block_map (logno)) < 0)
        !           157:        break;
        !           158: 
        !           159:       size -= off;
        !           160: 
        !           161:       if (size > len)
        !           162:        size = len;
        !           163: 
        !           164:       disk_read_func = disk_read_hook;
        !           165: 
        !           166:       devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
        !           167: 
        !           168:       disk_read_func = NULL;
        !           169: 
        !           170:       buf += size;
        !           171:       len -= size;
        !           172:       filepos += size;
        !           173:       ret += size;
        !           174:     }
        !           175: 
        !           176:   if (errnum)
        !           177:     ret = 0;
        !           178: 
        !           179:   return ret;
        !           180: }
        !           181: 
        !           182: 
        !           183: int
        !           184: ffs_dir (char *dirname)
        !           185: {
        !           186:   char *rest, ch;
        !           187:   int block, off, loc, map, ino = ROOTINO;
        !           188:   struct direct *dp;
        !           189: 
        !           190: /* main loop to find destination inode */
        !           191: loop:
        !           192: 
        !           193:   /* load current inode (defaults to the root inode) */
        !           194: 
        !           195:        if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)),
        !           196:                                                                ino % (SUPERBLOCK->fs_inopb) * sizeof (struct dinode),
        !           197:                                                                sizeof (struct dinode), (char *) INODE))
        !           198:                        return 0;                       /* XXX what return value? */
        !           199: 
        !           200:   /* if we have a real file (and we're not just printing possibilities),
        !           201:      then this is where we want to exit */
        !           202: 
        !           203:   if (!*dirname || isspace (*dirname))
        !           204:     {
        !           205:       if ((INODE->i_mode & IFMT) != IFREG)
        !           206:        {
        !           207:          errnum = ERR_BAD_FILETYPE;
        !           208:          return 0;
        !           209:        }
        !           210: 
        !           211:       filemax = INODE->i_size;
        !           212: 
        !           213:       /* incomplete implementation requires this! */
        !           214:       fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
        !           215:       return 1;
        !           216:     }
        !           217: 
        !           218:   /* continue with file/directory name interpretation */
        !           219: 
        !           220:   while (*dirname == '/')
        !           221:     dirname++;
        !           222: 
        !           223:   if (!(INODE->i_size) || ((INODE->i_mode & IFMT) != IFDIR))
        !           224:     {
        !           225:       errnum = ERR_BAD_FILETYPE;
        !           226:       return 0;
        !           227:     }
        !           228: 
        !           229:   for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
        !           230: 
        !           231:   *rest = 0;
        !           232:   loc = 0;
        !           233: 
        !           234:   /* loop for reading a the entries in a directory */
        !           235: 
        !           236:   do
        !           237:     {
        !           238:       if (loc >= INODE->i_size)
        !           239:        {
        !           240: #if 0
        !           241:          putchar ('\n');
        !           242: #endif
        !           243: 
        !           244:          if (print_possibilities < 0)
        !           245:            return 1;
        !           246: 
        !           247:          errnum = ERR_FILE_NOT_FOUND;
        !           248:          *rest = ch;
        !           249:          return 0;
        !           250:        }
        !           251: 
        !           252:       if (!(off = blkoff (SUPERBLOCK, loc)))
        !           253:        {
        !           254:          block = lblkno (SUPERBLOCK, loc);
        !           255: 
        !           256:          if ((map = block_map (block)) < 0
        !           257:              || !devread (fsbtodb (SUPERBLOCK, map), 0,
        !           258:                           blksize (SUPERBLOCK, INODE, block),
        !           259:                           (char *) FSYS_BUF))
        !           260:            {
        !           261:              errnum = ERR_FSYS_CORRUPT;
        !           262:              *rest = ch;
        !           263:              return 0;
        !           264:            }
        !           265:        }
        !           266: 
        !           267:       dp = (struct direct *) (FSYS_BUF + off);
        !           268:       loc += dp->d_reclen;
        !           269: 
        !           270: #ifndef STAGE1_5
        !           271:       if (dp->d_ino && print_possibilities && ch != '/'
        !           272:          && (!*dirname || substring (dirname, dp->d_name) <= 0))
        !           273:        {
        !           274:          if (print_possibilities > 0)
        !           275:            print_possibilities = -print_possibilities;
        !           276: 
        !           277:          print_a_completion (dp->d_name);
        !           278:        }
        !           279: #endif /* STAGE1_5 */
        !           280:     }
        !           281:   while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
        !           282:                        || (print_possibilities && ch != '/')));
        !           283: 
        !           284:   /* only get here if we have a matching directory entry */
        !           285: 
        !           286:   ino = dp->d_ino;
        !           287:   *(dirname = rest) = ch;
        !           288: 
        !           289:   /* go back to main loop at top of function */
        !           290:   goto loop;
        !           291: }
        !           292: 
        !           293: int
        !           294: ffs_embed (int *start_sector, int needed_sectors)
        !           295: {
        !           296:   /* XXX: I don't know if this is really correct. Someone who is
        !           297:      familiar with BSD should check for this.  */
        !           298:   if (needed_sectors > 14)
        !           299:     return 0;
        !           300: 
        !           301:   *start_sector = 1;
        !           302: #if 1
        !           303:   /* FIXME: Disable the embedding in FFS until someone checks if
        !           304:      the code above is correct.  */
        !           305:   return 0;
        !           306: #else
        !           307:   return 1;
        !           308: #endif
        !           309: }
        !           310: 
        !           311: #endif /* FSYS_FFS */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.