2 * Mach Operating System
3 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
26 * from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
27 * fromL Id: sys.c,v 1.21 1997/06/09 05:10:56 bde Exp
28 * $FreeBSD: src/sys/boot/alpha/boot1/sys.c,v 1.4.2.2 2002/01/19 02:16:09 iedowse Exp $
29 * $DragonFly: src/sys/boot/alpha/boot1/Attic/sys.c,v 1.2 2003/06/17 04:28:16 dillon Exp $
33 #include <sys/param.h>
36 #include <ufs/ffs/fs.h>
37 #include <ufs/ufs/quota.h>
38 #include <ufs/ufs/inode.h>
40 #include <sys/dirent.h>
49 * We use 4k `virtual' blocks for filesystem data, whatever the actual
50 * filesystem block size. FFS blocks are always a multiple of 4k.
53 #define VBLKMASK (VBLKSIZE - 1)
54 #define DBPERVBLK (VBLKSIZE / DEV_BSIZE)
55 #define IPERVBLK (VBLKSIZE / sizeof(struct dinode))
56 #define INDIRPERVBLK (VBLKSIZE / sizeof(ufs_daddr_t))
57 #define INO_TO_VBA(fs, x) (fsbtodb(fs, ino_to_fsba(fs, x)) + \
58 (ino_to_fsbo(fs, x) / IPERVBLK) * DBPERVBLK)
59 #define INO_TO_VBO(fs, x) (ino_to_fsbo(fs, x) % IPERVBLK)
60 #define FS_TO_VBA(fs, fsb, off) (fsbtodb(fs, fsb) + \
61 ((off) / VBLKSIZE) * DBPERVBLK)
62 #define FS_TO_VBO(fs, fsb, off) ((off) & VBLKMASK)
64 static char fsbuf[SBSIZE], iobuf[VBLKSIZE];
65 ufs_daddr_t mapbuf[VBLKSIZE / sizeof(ufs_daddr_t)];
71 #define STARTBYTE 8192 /* Where on the media the kernel starts */
74 static int block_map(int file_block);
75 static int find(char *path);
78 readit(char *buffer, int count)
81 int cnt2, fsblk, bnum2;
85 if (poff + count > inode.i_size)
86 count = inode.i_size - poff;
87 while (count > 0 && poff < inode.i_size) {
89 off = blkoff(fs_copy, poff);
90 logno = lblkno(fs_copy, poff);
91 fsblk = block_map(logno);
92 cnt2 = blksize(fs_copy, &inode, logno) - (off & ~VBLKMASK);
96 bnum2 = FS_TO_VBA(fs_copy, fsblk, off) + boff;
97 off = FS_TO_VBO(fs_copy, fsblk, off);
98 if ( (!off) && (size <= count)) {
99 devread(buffer, bnum2, cnt2);
104 devread(iobuf, bnum2, cnt2);
105 bcopy(iobuf+off, buffer, size);
119 int block, blklen, fsboff, off, loc, ino = ROOTINO;
123 list_only = (path[0] == '?' && path[1] == '\0');
125 devread(iobuf, INO_TO_VBA(fs, ino) + boff, VBLKSIZE);
126 bcopy((void *)&((struct dinode *)iobuf)[INO_TO_VBO(fs, ino)],
127 (void *)&inode.i_din,
128 sizeof (struct dinode));
133 if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
135 for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
139 if (loc >= inode.i_size) {
147 if (!(off = (loc & VBLKMASK))) {
148 block = lblkno(fs, loc);
149 fsboff = blkoff(fs, loc);
150 blklen = blksize(fs, &inode, block) - fsboff;
151 if (blklen > VBLKSIZE)
153 devread(iobuf, FS_TO_VBA(fs, block_map(block), fsboff) + boff,
156 dp = (struct dirent *)(iobuf + off);
158 if (dp->d_fileno && list_only) {
162 } while (!dp->d_fileno || strcmp(path, dp->d_name));
170 block_map(int file_block)
173 if (file_block < NDADDR)
174 return(inode.i_db[file_block]);
175 bnum = FS_TO_VBA(fs, inode.i_ib[0], sizeof(mapbuf[0]) *
176 ((file_block - NDADDR) % NINDIR(fs))) + boff;
177 if (bnum != mapblock) {
178 devread(mapbuf, bnum, VBLKSIZE);
181 return (mapbuf[(file_block - NDADDR) % INDIRPERVBLK]);
186 #define max(a, b) ((a) > (b) ? (a) : (b))
189 * Sanity checks for old file systems.
191 * XXX - goes away some day.
199 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */
200 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */
201 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
202 fs->fs_nrpos = 8; /* XXX */
203 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
204 quad_t sizepb = fs->fs_bsize; /* XXX */
206 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
207 for (i = 0; i < NIADDR; i++) { /* XXX */
208 sizepb *= NINDIR(fs); /* XXX */
209 fs->fs_maxfilesize += sizepb; /* XXX */
211 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
212 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
227 * Load Filesystem info (mount the device).
229 devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
236 * Find the actual FILE on the mounted device.
237 * Make a copy of the name since find() is destructive.
239 strcpy(namecopy, name);
240 ret = find(namecopy);
250 bcopy(const void *src, void *dst, size_t len)
255 for (d = dst, s = src; len; len--)