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