xref: /freebsd/usr.sbin/makefs/ffs/ffs_subr.c (revision 4d65a7c6951cea0333f1a0c1b32c38489cdfa6c5)
1d347a0daSSam Leffler /*	$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $	*/
2d347a0daSSam Leffler 
38a16b7a1SPedro F. Giffuni /*-
48a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
58a16b7a1SPedro F. Giffuni  *
6d347a0daSSam Leffler  * Copyright (c) 1982, 1986, 1989, 1993
7d347a0daSSam Leffler  *	The Regents of the University of California.  All rights reserved.
8d347a0daSSam Leffler  *
9d347a0daSSam Leffler  * Redistribution and use in source and binary forms, with or without
10d347a0daSSam Leffler  * modification, are permitted provided that the following conditions
11d347a0daSSam Leffler  * are met:
12d347a0daSSam Leffler  * 1. Redistributions of source code must retain the above copyright
13d347a0daSSam Leffler  *    notice, this list of conditions and the following disclaimer.
14d347a0daSSam Leffler  * 2. Redistributions in binary form must reproduce the above copyright
15d347a0daSSam Leffler  *    notice, this list of conditions and the following disclaimer in the
16d347a0daSSam Leffler  *    documentation and/or other materials provided with the distribution.
17d347a0daSSam Leffler  * 3. Neither the name of the University nor the names of its contributors
18d347a0daSSam Leffler  *    may be used to endorse or promote products derived from this software
19d347a0daSSam Leffler  *    without specific prior written permission.
20d347a0daSSam Leffler  *
21d347a0daSSam Leffler  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22d347a0daSSam Leffler  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23d347a0daSSam Leffler  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24d347a0daSSam Leffler  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25d347a0daSSam Leffler  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26d347a0daSSam Leffler  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27d347a0daSSam Leffler  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28d347a0daSSam Leffler  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29d347a0daSSam Leffler  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30d347a0daSSam Leffler  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31d347a0daSSam Leffler  * SUCH DAMAGE.
32d347a0daSSam Leffler  */
33d347a0daSSam Leffler 
34d347a0daSSam Leffler #include <sys/param.h>
355d71efbeSMarcel Moolenaar #include <sys/types.h>
36d347a0daSSam Leffler 
37d347a0daSSam Leffler #include <ufs/ufs/dinode.h>
38d347a0daSSam Leffler #include <ufs/ffs/fs.h>
3955a1bde9SEd Schouten #include "ffs/ffs_extern.h"
40d347a0daSSam Leffler #include "ffs/ufs_bswap.h"
41ff13f23fSKirk McKusick 
42d347a0daSSam Leffler /*
43d347a0daSSam Leffler  * Update the frsum fields to reflect addition or deletion
44d347a0daSSam Leffler  * of some frags.
45d347a0daSSam Leffler  */
46d347a0daSSam Leffler void
ffs_fragacct_swap(struct fs * fs,int fragmap,uint32_t fraglist[],int cnt,int needswap)47*fe41c64bSAlex Richardson ffs_fragacct_swap(struct fs *fs, int fragmap, uint32_t fraglist[], int cnt, int needswap)
48d347a0daSSam Leffler {
49d347a0daSSam Leffler 	int inblk;
50d347a0daSSam Leffler 	int field, subfield;
51d347a0daSSam Leffler 	int siz, pos;
52d347a0daSSam Leffler 
53d347a0daSSam Leffler 	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
54d347a0daSSam Leffler 	fragmap <<= 1;
55d347a0daSSam Leffler 	for (siz = 1; siz < fs->fs_frag; siz++) {
56d347a0daSSam Leffler 		if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0)
57d347a0daSSam Leffler 			continue;
58d347a0daSSam Leffler 		field = around[siz];
59d347a0daSSam Leffler 		subfield = inside[siz];
60d347a0daSSam Leffler 		for (pos = siz; pos <= fs->fs_frag; pos++) {
61d347a0daSSam Leffler 			if ((fragmap & field) == subfield) {
62d347a0daSSam Leffler 				fraglist[siz] = ufs_rw32(
63d347a0daSSam Leffler 				    ufs_rw32(fraglist[siz], needswap) + cnt,
64d347a0daSSam Leffler 				    needswap);
65d347a0daSSam Leffler 				pos += siz;
66d347a0daSSam Leffler 				field <<= siz;
67d347a0daSSam Leffler 				subfield <<= siz;
68d347a0daSSam Leffler 			}
69d347a0daSSam Leffler 			field <<= 1;
70d347a0daSSam Leffler 			subfield <<= 1;
71d347a0daSSam Leffler 		}
72d347a0daSSam Leffler 	}
73d347a0daSSam Leffler }
74d347a0daSSam Leffler 
75d347a0daSSam Leffler /*
76d347a0daSSam Leffler  * block operations
77d347a0daSSam Leffler  *
78d347a0daSSam Leffler  * check if a block is available
793df5ecacSUlrich Spörlein  *  returns true if all the corresponding bits in the free map are 1
80d347a0daSSam Leffler  *  returns false if any corresponding bit in the free map is 0
81d347a0daSSam Leffler  */
82d347a0daSSam Leffler int
ffs_isblock(struct fs * fs,u_char * cp,int32_t h)83ab6f27aaSEd Maste ffs_isblock(struct fs *fs, u_char *cp, int32_t h)
84d347a0daSSam Leffler {
85d347a0daSSam Leffler 	u_char mask;
86d347a0daSSam Leffler 
87d347a0daSSam Leffler 	switch ((int)fs->fs_fragshift) {
88d347a0daSSam Leffler 	case 3:
89d347a0daSSam Leffler 		return (cp[h] == 0xff);
90d347a0daSSam Leffler 	case 2:
91d347a0daSSam Leffler 		mask = 0x0f << ((h & 0x1) << 2);
92d347a0daSSam Leffler 		return ((cp[h >> 1] & mask) == mask);
93d347a0daSSam Leffler 	case 1:
94d347a0daSSam Leffler 		mask = 0x03 << ((h & 0x3) << 1);
95d347a0daSSam Leffler 		return ((cp[h >> 2] & mask) == mask);
96d347a0daSSam Leffler 	case 0:
97d347a0daSSam Leffler 		mask = 0x01 << (h & 0x7);
98d347a0daSSam Leffler 		return ((cp[h >> 3] & mask) == mask);
99d347a0daSSam Leffler 	default:
100d347a0daSSam Leffler 		panic("ffs_isblock: unknown fs_fragshift %d",
101d347a0daSSam Leffler 		    (int)fs->fs_fragshift);
102d347a0daSSam Leffler 	}
103d347a0daSSam Leffler }
104d347a0daSSam Leffler 
105d347a0daSSam Leffler /*
106d347a0daSSam Leffler  * check if a block is completely allocated
107d347a0daSSam Leffler  *  returns true if all the corresponding bits in the free map are 0
108d347a0daSSam Leffler  *  returns false if any corresponding bit in the free map is 1
109d347a0daSSam Leffler  */
110d347a0daSSam Leffler int
ffs_isfreeblock(struct fs * fs,u_char * cp,int32_t h)111ab6f27aaSEd Maste ffs_isfreeblock(struct fs *fs, u_char *cp, int32_t h)
112d347a0daSSam Leffler {
113d347a0daSSam Leffler 
114d347a0daSSam Leffler 	switch ((int)fs->fs_fragshift) {
115d347a0daSSam Leffler 	case 3:
116d347a0daSSam Leffler 		return (cp[h] == 0);
117d347a0daSSam Leffler 	case 2:
118d347a0daSSam Leffler 		return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
119d347a0daSSam Leffler 	case 1:
120d347a0daSSam Leffler 		return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
121d347a0daSSam Leffler 	case 0:
122d347a0daSSam Leffler 		return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
123d347a0daSSam Leffler 	default:
124d347a0daSSam Leffler 		panic("ffs_isfreeblock: unknown fs_fragshift %d",
125d347a0daSSam Leffler 		    (int)fs->fs_fragshift);
126d347a0daSSam Leffler 	}
127d347a0daSSam Leffler }
128d347a0daSSam Leffler 
129d347a0daSSam Leffler /*
130d347a0daSSam Leffler  * take a block out of the map
131d347a0daSSam Leffler  */
132d347a0daSSam Leffler void
ffs_clrblock(struct fs * fs,u_char * cp,int32_t h)133ab6f27aaSEd Maste ffs_clrblock(struct fs *fs, u_char *cp, int32_t h)
134d347a0daSSam Leffler {
135d347a0daSSam Leffler 
136d347a0daSSam Leffler 	switch ((int)fs->fs_fragshift) {
137d347a0daSSam Leffler 	case 3:
138d347a0daSSam Leffler 		cp[h] = 0;
139d347a0daSSam Leffler 		return;
140d347a0daSSam Leffler 	case 2:
141d347a0daSSam Leffler 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
142d347a0daSSam Leffler 		return;
143d347a0daSSam Leffler 	case 1:
144d347a0daSSam Leffler 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
145d347a0daSSam Leffler 		return;
146d347a0daSSam Leffler 	case 0:
147d347a0daSSam Leffler 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
148d347a0daSSam Leffler 		return;
149d347a0daSSam Leffler 	default:
150d347a0daSSam Leffler 		panic("ffs_clrblock: unknown fs_fragshift %d",
151d347a0daSSam Leffler 		    (int)fs->fs_fragshift);
152d347a0daSSam Leffler 	}
153d347a0daSSam Leffler }
154d347a0daSSam Leffler 
155d347a0daSSam Leffler /*
156d347a0daSSam Leffler  * put a block into the map
157d347a0daSSam Leffler  */
158d347a0daSSam Leffler void
ffs_setblock(struct fs * fs,u_char * cp,int32_t h)159ab6f27aaSEd Maste ffs_setblock(struct fs *fs, u_char *cp, int32_t h)
160d347a0daSSam Leffler {
161d347a0daSSam Leffler 
162d347a0daSSam Leffler 	switch ((int)fs->fs_fragshift) {
163d347a0daSSam Leffler 	case 3:
164d347a0daSSam Leffler 		cp[h] = 0xff;
165d347a0daSSam Leffler 		return;
166d347a0daSSam Leffler 	case 2:
167d347a0daSSam Leffler 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
168d347a0daSSam Leffler 		return;
169d347a0daSSam Leffler 	case 1:
170d347a0daSSam Leffler 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
171d347a0daSSam Leffler 		return;
172d347a0daSSam Leffler 	case 0:
173d347a0daSSam Leffler 		cp[h >> 3] |= (0x01 << (h & 0x7));
174d347a0daSSam Leffler 		return;
175d347a0daSSam Leffler 	default:
176d347a0daSSam Leffler 		panic("ffs_setblock: unknown fs_fragshift %d",
177d347a0daSSam Leffler 		    (int)fs->fs_fragshift);
178d347a0daSSam Leffler 	}
179d347a0daSSam Leffler }
180