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