|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.