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