xref: /freebsd/usr.sbin/makefs/ffs/ffs_subr.c (revision a2f733abcff64628b7771a47089628b7327a88bd)
1 /*	$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $	*/
2 
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright (c) 1982, 1986, 1989, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. 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 
34 #include <sys/cdefs.h>
35 #include <sys/param.h>
36 #include <sys/types.h>
37 
38 #include <ufs/ufs/dinode.h>
39 #include <ufs/ffs/fs.h>
40 #include "ffs/ffs_extern.h"
41 #include "ffs/ufs_bswap.h"
42 
43 /*
44  * Update the frsum fields to reflect addition or deletion
45  * of some frags.
46  */
47 void
48 ffs_fragacct_swap(struct fs *fs, int fragmap, uint32_t fraglist[], int cnt, int needswap)
49 {
50 	int inblk;
51 	int field, subfield;
52 	int siz, pos;
53 
54 	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
55 	fragmap <<= 1;
56 	for (siz = 1; siz < fs->fs_frag; siz++) {
57 		if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0)
58 			continue;
59 		field = around[siz];
60 		subfield = inside[siz];
61 		for (pos = siz; pos <= fs->fs_frag; pos++) {
62 			if ((fragmap & field) == subfield) {
63 				fraglist[siz] = ufs_rw32(
64 				    ufs_rw32(fraglist[siz], needswap) + cnt,
65 				    needswap);
66 				pos += siz;
67 				field <<= siz;
68 				subfield <<= siz;
69 			}
70 			field <<= 1;
71 			subfield <<= 1;
72 		}
73 	}
74 }
75 
76 /*
77  * block operations
78  *
79  * check if a block is available
80  *  returns true if all the corresponding bits in the free map are 1
81  *  returns false if any corresponding bit in the free map is 0
82  */
83 int
84 ffs_isblock(struct fs *fs, u_char *cp, int32_t h)
85 {
86 	u_char mask;
87 
88 	switch ((int)fs->fs_fragshift) {
89 	case 3:
90 		return (cp[h] == 0xff);
91 	case 2:
92 		mask = 0x0f << ((h & 0x1) << 2);
93 		return ((cp[h >> 1] & mask) == mask);
94 	case 1:
95 		mask = 0x03 << ((h & 0x3) << 1);
96 		return ((cp[h >> 2] & mask) == mask);
97 	case 0:
98 		mask = 0x01 << (h & 0x7);
99 		return ((cp[h >> 3] & mask) == mask);
100 	default:
101 		panic("ffs_isblock: unknown fs_fragshift %d",
102 		    (int)fs->fs_fragshift);
103 	}
104 }
105 
106 /*
107  * check if a block is completely allocated
108  *  returns true if all the corresponding bits in the free map are 0
109  *  returns false if any corresponding bit in the free map is 1
110  */
111 int
112 ffs_isfreeblock(struct fs *fs, u_char *cp, int32_t h)
113 {
114 
115 	switch ((int)fs->fs_fragshift) {
116 	case 3:
117 		return (cp[h] == 0);
118 	case 2:
119 		return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
120 	case 1:
121 		return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
122 	case 0:
123 		return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
124 	default:
125 		panic("ffs_isfreeblock: unknown fs_fragshift %d",
126 		    (int)fs->fs_fragshift);
127 	}
128 }
129 
130 /*
131  * take a block out of the map
132  */
133 void
134 ffs_clrblock(struct fs *fs, u_char *cp, int32_t h)
135 {
136 
137 	switch ((int)fs->fs_fragshift) {
138 	case 3:
139 		cp[h] = 0;
140 		return;
141 	case 2:
142 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
143 		return;
144 	case 1:
145 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
146 		return;
147 	case 0:
148 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
149 		return;
150 	default:
151 		panic("ffs_clrblock: unknown fs_fragshift %d",
152 		    (int)fs->fs_fragshift);
153 	}
154 }
155 
156 /*
157  * put a block into the map
158  */
159 void
160 ffs_setblock(struct fs *fs, u_char *cp, int32_t h)
161 {
162 
163 	switch ((int)fs->fs_fragshift) {
164 	case 3:
165 		cp[h] = 0xff;
166 		return;
167 	case 2:
168 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
169 		return;
170 	case 1:
171 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
172 		return;
173 	case 0:
174 		cp[h >> 3] |= (0x01 << (h & 0x7));
175 		return;
176 	default:
177 		panic("ffs_setblock: unknown fs_fragshift %d",
178 		    (int)fs->fs_fragshift);
179 	}
180 }
181