Add extra argument to VOP_BMAP.
[unix-history] / usr / src / sys / ufs / ffs / ffs_subr.c
CommitLineData
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 */
26int
dc45e6d9
KM
27ffs_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
62void
63ffs_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
94void
95ffs_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
132int
133ffs_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
160void
161ffs_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
188void
189ffs_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}