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