|
|
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.