ffs_subr.c revision 186261
1/*	$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $	*/
2
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. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 *	@(#)ffs_subr.c	8.5 (Berkeley) 3/21/95
32 */
33
34#include <sys/cdefs.h>
35#if 0
36__KERNEL_RCSID(0, "$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $");
37#endif
38__FBSDID("$FreeBSD$");
39
40#include <sys/param.h>
41
42#include <ufs/ufs/dinode.h>
43#include <ufs/ffs/fs.h>
44/* XXX temporary */
45struct ufsmount;
46struct bufobj;
47struct mount;
48struct vnode;
49typedef int vfs_vget_t(struct mount *mp, ino_t ino, int flags,
50                    struct vnode **vpp);
51#include <ufs/ffs/ffs_extern.h>
52#include "ffs/ufs_bswap.h"
53void    panic __P((const char *, ...))
54    __attribute__((__noreturn__,__format__(__printf__,1,2)));
55
56/*
57 * Update the frsum fields to reflect addition or deletion
58 * of some frags.
59 */
60void
61ffs_fragacct_swap(struct fs *fs, int fragmap, int32_t fraglist[], int cnt, int needswap)
62{
63	int inblk;
64	int field, subfield;
65	int siz, pos;
66
67	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
68	fragmap <<= 1;
69	for (siz = 1; siz < fs->fs_frag; siz++) {
70		if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0)
71			continue;
72		field = around[siz];
73		subfield = inside[siz];
74		for (pos = siz; pos <= fs->fs_frag; pos++) {
75			if ((fragmap & field) == subfield) {
76				fraglist[siz] = ufs_rw32(
77				    ufs_rw32(fraglist[siz], needswap) + cnt,
78				    needswap);
79				pos += siz;
80				field <<= siz;
81				subfield <<= siz;
82			}
83			field <<= 1;
84			subfield <<= 1;
85		}
86	}
87}
88
89/*
90 * block operations
91 *
92 * check if a block is available
93 *  returns true if all the correponding bits in the free map are 1
94 *  returns false if any corresponding bit in the free map is 0
95 */
96int
97ffs_isblock(fs, cp, h)
98	struct fs *fs;
99	u_char *cp;
100	int32_t h;
101{
102	u_char mask;
103
104	switch ((int)fs->fs_fragshift) {
105	case 3:
106		return (cp[h] == 0xff);
107	case 2:
108		mask = 0x0f << ((h & 0x1) << 2);
109		return ((cp[h >> 1] & mask) == mask);
110	case 1:
111		mask = 0x03 << ((h & 0x3) << 1);
112		return ((cp[h >> 2] & mask) == mask);
113	case 0:
114		mask = 0x01 << (h & 0x7);
115		return ((cp[h >> 3] & mask) == mask);
116	default:
117		panic("ffs_isblock: unknown fs_fragshift %d",
118		    (int)fs->fs_fragshift);
119	}
120}
121
122/*
123 * check if a block is completely allocated
124 *  returns true if all the corresponding bits in the free map are 0
125 *  returns false if any corresponding bit in the free map is 1
126 */
127int
128ffs_isfreeblock(fs, cp, h)
129	struct fs *fs;
130	u_char *cp;
131	int32_t h;
132{
133
134	switch ((int)fs->fs_fragshift) {
135	case 3:
136		return (cp[h] == 0);
137	case 2:
138		return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
139	case 1:
140		return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
141	case 0:
142		return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
143	default:
144		panic("ffs_isfreeblock: unknown fs_fragshift %d",
145		    (int)fs->fs_fragshift);
146	}
147}
148
149/*
150 * take a block out of the map
151 */
152void
153ffs_clrblock(fs, cp, h)
154	struct fs *fs;
155	u_char *cp;
156	int32_t h;
157{
158
159	switch ((int)fs->fs_fragshift) {
160	case 3:
161		cp[h] = 0;
162		return;
163	case 2:
164		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
165		return;
166	case 1:
167		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
168		return;
169	case 0:
170		cp[h >> 3] &= ~(0x01 << (h & 0x7));
171		return;
172	default:
173		panic("ffs_clrblock: unknown fs_fragshift %d",
174		    (int)fs->fs_fragshift);
175	}
176}
177
178/*
179 * put a block into the map
180 */
181void
182ffs_setblock(fs, cp, h)
183	struct fs *fs;
184	u_char *cp;
185	int32_t h;
186{
187
188	switch ((int)fs->fs_fragshift) {
189	case 3:
190		cp[h] = 0xff;
191		return;
192	case 2:
193		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
194		return;
195	case 1:
196		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
197		return;
198	case 0:
199		cp[h >> 3] |= (0x01 << (h & 0x7));
200		return;
201	default:
202		panic("ffs_setblock: unknown fs_fragshift %d",
203		    (int)fs->fs_fragshift);
204	}
205}
206