Annotation of qemu/roms/openbios/fs/grubfs/fsys_ffs.c, revision 1.1.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.