|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*
27: * Copyright (c) 1982, 1986, 1989, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * Redistribution and use in source and binary forms, with or without
31: * modification, are permitted provided that the following conditions
32: * are met:
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. All advertising materials mentioning features or use of this software
39: * must display the following acknowledgement:
40: * This product includes software developed by the University of
41: * California, Berkeley and its contributors.
42: * 4. Neither the name of the University nor the names of its contributors
43: * may be used to endorse or promote products derived from this software
44: * without specific prior written permission.
45: *
46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56: * SUCH DAMAGE.
57: *
58: * @(#)ffs_subr.c 8.5 (Berkeley) 3/21/95
59: */
60:
61: #include <rev_endian_fs.h>
62: #include <sys/param.h>
63: #if REV_ENDIAN_FS
64: #include <sys/mount.h>
65: #endif /* REV_ENDIAN_FS */
66:
67: #ifndef _KERNEL
68: #include <ufs/ufs/dinode.h>
69: #include <ufs/ffs/fs.h>
70: #else
71:
72: #include <sys/systm.h>
73: #include <sys/vnode.h>
74: #include <sys/buf.h>
75: #include <ufs/ufs/quota.h>
76: #include <ufs/ufs/inode.h>
77: #include <ufs/ffs/fs.h>
78: #include <ufs/ffs/ffs_extern.h>
79: #if REV_ENDIAN_FS
80: #include <ufs/ufs/ufs_byte_order.h>
81: #include <architecture/byte_order.h>
82: #endif /* REV_ENDIAN_FS */
83:
84: /*
85: * Return buffer with the contents of block "offset" from the beginning of
86: * directory "ip". If "res" is non-zero, fill it in with a pointer to the
87: * remaining space in the directory.
88: */
89: int
90: ffs_blkatoff(ap)
91: struct vop_blkatoff_args /* {
92: struct vnode *a_vp;
93: off_t a_offset;
94: char **a_res;
95: struct buf **a_bpp;
96: } */ *ap;
97: {
98: struct inode *ip;
99: register struct fs *fs;
100: struct buf *bp;
101: ufs_daddr_t lbn;
102: int bsize, error;
103: #if REV_ENDIAN_FS
104: struct mount *mp=(ap->a_vp)->v_mount;
105: int rev_endian=(mp->mnt_flag & MNT_REVEND);
106: #endif /* REV_ENDIAN_FS */
107:
108: ip = VTOI(ap->a_vp);
109: fs = ip->i_fs;
110: lbn = lblkno(fs, ap->a_offset);
111: bsize = blksize(fs, ip, lbn);
112:
113: *ap->a_bpp = NULL;
114: if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
115: brelse(bp);
116: return (error);
117: }
118: #if REV_ENDIAN_FS
119: if (rev_endian)
120: byte_swap_dir_block_in(bp->b_data, bp->b_bcount);
121: #endif /* REV_ENDIAN_FS */
122:
123: if (ap->a_res)
124: *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset);
125: *ap->a_bpp = bp;
126: return (0);
127: }
128: #endif
129:
130: /*
131: * Update the frsum fields to reflect addition or deletion
132: * of some frags.
133: */
134: void
135: ffs_fragacct(fs, fragmap, fraglist, cnt)
136: struct fs *fs;
137: int fragmap;
138: int32_t fraglist[];
139: int cnt;
140: {
141: int inblk;
142: register int field, subfield;
143: register int siz, pos;
144:
145: inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
146: fragmap <<= 1;
147: for (siz = 1; siz < fs->fs_frag; siz++) {
148: if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
149: continue;
150: field = around[siz];
151: subfield = inside[siz];
152: for (pos = siz; pos <= fs->fs_frag; pos++) {
153: if ((fragmap & field) == subfield) {
154: fraglist[siz] += cnt;
155: pos += siz;
156: field <<= siz;
157: subfield <<= siz;
158: }
159: field <<= 1;
160: subfield <<= 1;
161: }
162: }
163: }
164:
165: #if defined(_KERNEL) && DIAGNOSTIC
166: void
167: ffs_checkoverlap(bp, ip)
168: struct buf *bp;
169: struct inode *ip;
170: {
171: register struct buf *ebp, *ep;
172: register ufs_daddr_t start, last;
173: struct vnode *vp;
174: #ifdef NeXT
175: int devBlockSize=0;
176: #endif /* NeXT */
177:
178: ebp = &buf[nbuf];
179: start = bp->b_blkno;
180: #ifdef NeXT
181: VOP_DEVBLOCKSIZE(ip->i_devvp,&devBlockSize);
182: last = start + btodb(bp->b_bcount, devBlockSize) - 1;
183: #else
184: last = start + btodb(bp->b_bcount) - 1;
185: #endif /* NeXT */
186: for (ep = buf; ep < ebp; ep++) {
187: if (ep == bp || (ep->b_flags & B_INVAL) ||
188: ep->b_vp == NULLVP)
189: continue;
190: if (VOP_BMAP(ep->b_vp, (ufs_daddr_t)0, &vp, (ufs_daddr_t)0,
191: NULL))
192: continue;
193: if (vp != ip->i_devvp)
194: continue;
195: /* look for overlap */
196: #ifdef NeXT
197: if (ep->b_bcount == 0 || ep->b_blkno > last ||
198: ep->b_blkno + btodb(ep->b_bcount, devBlockSize) <= start)
199: continue;
200: vprint("Disk overlap", vp);
201: (void)printf("\tstart %d, end %d overlap start %d, end %d\n",
202: start, last, ep->b_blkno,
203: ep->b_blkno + btodb(ep->b_bcount, devBlockSize) - 1);
204: #else
205: if (ep->b_bcount == 0 || ep->b_blkno > last ||
206: ep->b_blkno + btodb(ep->b_bcount) <= start)
207: continue;
208: vprint("Disk overlap", vp);
209: (void)printf("\tstart %d, end %d overlap start %d, end %d\n",
210: start, last, ep->b_blkno,
211: ep->b_blkno + btodb(ep->b_bcount) - 1);
212: #endif /* NeXT */
213: panic("Disk buffer overlap");
214: }
215: }
216: #endif /* DIAGNOSTIC */
217:
218: /*
219: * block operations
220: *
221: * check if a block is available
222: */
223: int
224: ffs_isblock(fs, cp, h)
225: struct fs *fs;
226: unsigned char *cp;
227: ufs_daddr_t h;
228: {
229: unsigned char mask;
230:
231: switch ((int)fs->fs_frag) {
232: case 8:
233: return (cp[h] == 0xff);
234: case 4:
235: mask = 0x0f << ((h & 0x1) << 2);
236: return ((cp[h >> 1] & mask) == mask);
237: case 2:
238: mask = 0x03 << ((h & 0x3) << 1);
239: return ((cp[h >> 2] & mask) == mask);
240: case 1:
241: mask = 0x01 << (h & 0x7);
242: return ((cp[h >> 3] & mask) == mask);
243: default:
244: panic("ffs_isblock");
245: }
246: }
247:
248: /*
249: * take a block out of the map
250: */
251: void
252: ffs_clrblock(fs, cp, h)
253: struct fs *fs;
254: u_char *cp;
255: ufs_daddr_t h;
256: {
257:
258: switch ((int)fs->fs_frag) {
259: case 8:
260: cp[h] = 0;
261: return;
262: case 4:
263: cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
264: return;
265: case 2:
266: cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
267: return;
268: case 1:
269: cp[h >> 3] &= ~(0x01 << (h & 0x7));
270: return;
271: default:
272: panic("ffs_clrblock");
273: }
274: }
275:
276: /*
277: * put a block into the map
278: */
279: void
280: ffs_setblock(fs, cp, h)
281: struct fs *fs;
282: unsigned char *cp;
283: ufs_daddr_t h;
284: {
285:
286: switch ((int)fs->fs_frag) {
287:
288: case 8:
289: cp[h] = 0xff;
290: return;
291: case 4:
292: cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
293: return;
294: case 2:
295: cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
296: return;
297: case 1:
298: cp[h >> 3] |= (0x01 << (h & 0x7));
299: return;
300: default:
301: panic("ffs_setblock");
302: }
303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.