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