Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
7188ac27 KM |
2 | * Copyright (c) 1982, 1986, 1989 Regents of the University of California. |
3 | * All rights reserved. | |
da7c5cc6 | 4 | * |
b702c21d | 5 | * %sccs.include.redist.c% |
7188ac27 | 6 | * |
c43604c7 | 7 | * @(#)ffs_subr.c 7.27 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
764e2379 | 9 | |
764e2379 | 10 | #include <sys/param.h> |
26c16549 | 11 | #include <ufs/ffs/fs.h> |
26c16549 | 12 | |
9f98958c | 13 | #ifdef KERNEL |
e792e7e5 | 14 | #include <sys/systm.h> |
1b9fbe4b KM |
15 | #include <sys/vnode.h> |
16 | #include <ufs/ffs/ffs_extern.h> | |
b2e0afbf | 17 | #include <sys/buf.h> |
b2e0afbf KM |
18 | #include <ufs/ufs/quota.h> |
19 | #include <ufs/ufs/inode.h> | |
9f98958c | 20 | |
26c16549 KB |
21 | /* |
22 | * Return buffer with the contents of block "offset" from the beginning of | |
23 | * directory "ip". If "res" is non-zero, fill it in with a pointer to the | |
24 | * remaining space in the directory. | |
25 | */ | |
26 | int | |
dc45e6d9 KM |
27 | ffs_blkatoff(ap) |
28 | struct vop_blkatoff_args /* { | |
29 | struct vnode *a_vp; | |
30 | off_t a_offset; | |
31 | char **a_res; | |
32 | struct buf **a_bpp; | |
33 | } */ *ap; | |
26c16549 | 34 | { |
a9013e03 | 35 | struct inode *ip; |
26c16549 KB |
36 | register struct fs *fs; |
37 | struct buf *bp; | |
38 | daddr_t lbn; | |
39 | int bsize, error; | |
40 | ||
e1b76915 | 41 | ip = VTOI(ap->a_vp); |
26c16549 | 42 | fs = ip->i_fs; |
e1b76915 | 43 | lbn = lblkno(fs, ap->a_offset); |
26c16549 KB |
44 | bsize = blksize(fs, ip, lbn); |
45 | ||
e1b76915 JH |
46 | *ap->a_bpp = NULL; |
47 | if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { | |
26c16549 KB |
48 | brelse(bp); |
49 | return (error); | |
50 | } | |
e1b76915 JH |
51 | if (ap->a_res) |
52 | *ap->a_res = bp->b_un.b_addr + blkoff(fs, ap->a_offset); | |
53 | *ap->a_bpp = bp; | |
26c16549 KB |
54 | return (0); |
55 | } | |
9f98958c | 56 | #endif |
764e2379 BJ |
57 | |
58 | /* | |
59 | * Update the frsum fields to reflect addition or deletion | |
60 | * of some frags. | |
61 | */ | |
26c16549 KB |
62 | void |
63 | ffs_fragacct(fs, fragmap, fraglist, cnt) | |
764e2379 BJ |
64 | struct fs *fs; |
65 | int fragmap; | |
66 | long fraglist[]; | |
67 | int cnt; | |
68 | { | |
69 | int inblk; | |
70 | register int field, subfield; | |
71 | register int siz, pos; | |
72 | ||
73 | inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; | |
74 | fragmap <<= 1; | |
75 | for (siz = 1; siz < fs->fs_frag; siz++) { | |
76 | if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) | |
77 | continue; | |
78 | field = around[siz]; | |
79 | subfield = inside[siz]; | |
80 | for (pos = siz; pos <= fs->fs_frag; pos++) { | |
81 | if ((fragmap & field) == subfield) { | |
82 | fraglist[siz] += cnt; | |
83 | pos += siz; | |
84 | field <<= siz; | |
85 | subfield <<= siz; | |
86 | } | |
87 | field <<= 1; | |
88 | subfield <<= 1; | |
89 | } | |
90 | } | |
91 | } | |
92 | ||
9f98958c | 93 | #if defined(KERNEL) && defined(DIAGNOSTIC) |
26c16549 KB |
94 | void |
95 | ffs_checkoverlap(bp, ip) | |
96 | struct buf *bp; | |
97 | struct inode *ip; | |
98 | { | |
99 | register struct buf *ebp, *ep; | |
100 | register daddr_t start, last; | |
101 | struct vnode *vp; | |
102 | ||
103 | ebp = &buf[nbuf]; | |
104 | start = bp->b_blkno; | |
105 | last = start + btodb(bp->b_bcount) - 1; | |
106 | for (ep = buf; ep < ebp; ep++) { | |
107 | if (ep == bp || (ep->b_flags & B_INVAL) || | |
108 | ep->b_vp == NULLVP) | |
109 | continue; | |
c43604c7 | 110 | if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL)) |
26c16549 KB |
111 | continue; |
112 | if (vp != ip->i_devvp) | |
113 | continue; | |
114 | /* look for overlap */ | |
115 | if (ep->b_bcount == 0 || ep->b_blkno > last || | |
116 | ep->b_blkno + btodb(ep->b_bcount) <= start) | |
117 | continue; | |
118 | vprint("Disk overlap", vp); | |
119 | (void)printf("\tstart %d, end %d overlap start %d, end %d\n", | |
120 | start, last, ep->b_blkno, | |
121 | ep->b_blkno + btodb(ep->b_bcount) - 1); | |
122 | panic("Disk buffer overlap"); | |
123 | } | |
124 | } | |
125 | #endif /* DIAGNOSTIC */ | |
126 | ||
764e2379 BJ |
127 | /* |
128 | * block operations | |
129 | * | |
130 | * check if a block is available | |
131 | */ | |
26c16549 KB |
132 | int |
133 | ffs_isblock(fs, cp, h) | |
764e2379 BJ |
134 | struct fs *fs; |
135 | unsigned char *cp; | |
136 | daddr_t h; | |
137 | { | |
138 | unsigned char mask; | |
139 | ||
cae611dc | 140 | switch ((int)fs->fs_frag) { |
764e2379 BJ |
141 | case 8: |
142 | return (cp[h] == 0xff); | |
143 | case 4: | |
144 | mask = 0x0f << ((h & 0x1) << 2); | |
145 | return ((cp[h >> 1] & mask) == mask); | |
146 | case 2: | |
147 | mask = 0x03 << ((h & 0x3) << 1); | |
148 | return ((cp[h >> 2] & mask) == mask); | |
149 | case 1: | |
150 | mask = 0x01 << (h & 0x7); | |
151 | return ((cp[h >> 3] & mask) == mask); | |
152 | default: | |
26c16549 | 153 | panic("ffs_isblock"); |
764e2379 BJ |
154 | } |
155 | } | |
156 | ||
157 | /* | |
158 | * take a block out of the map | |
159 | */ | |
26c16549 KB |
160 | void |
161 | ffs_clrblock(fs, cp, h) | |
764e2379 | 162 | struct fs *fs; |
39d536e6 | 163 | u_char *cp; |
764e2379 BJ |
164 | daddr_t h; |
165 | { | |
166 | ||
cae611dc | 167 | switch ((int)fs->fs_frag) { |
764e2379 BJ |
168 | case 8: |
169 | cp[h] = 0; | |
170 | return; | |
171 | case 4: | |
172 | cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); | |
173 | return; | |
174 | case 2: | |
175 | cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); | |
176 | return; | |
177 | case 1: | |
178 | cp[h >> 3] &= ~(0x01 << (h & 0x7)); | |
179 | return; | |
180 | default: | |
26c16549 | 181 | panic("ffs_clrblock"); |
764e2379 BJ |
182 | } |
183 | } | |
184 | ||
185 | /* | |
186 | * put a block into the map | |
187 | */ | |
26c16549 KB |
188 | void |
189 | ffs_setblock(fs, cp, h) | |
764e2379 BJ |
190 | struct fs *fs; |
191 | unsigned char *cp; | |
192 | daddr_t h; | |
193 | { | |
194 | ||
cae611dc | 195 | switch ((int)fs->fs_frag) { |
764e2379 BJ |
196 | |
197 | case 8: | |
198 | cp[h] = 0xff; | |
199 | return; | |
200 | case 4: | |
201 | cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); | |
202 | return; | |
203 | case 2: | |
204 | cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); | |
205 | return; | |
206 | case 1: | |
207 | cp[h >> 3] |= (0x01 << (h & 0x7)); | |
208 | return; | |
209 | default: | |
26c16549 | 210 | panic("ffs_setblock"); |
764e2379 BJ |
211 | } |
212 | } |