1d347a0daSSam Leffler /* $NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $ */ 2d347a0daSSam Leffler 3*8a16b7a1SPedro F. Giffuni /*- 4*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 5*8a16b7a1SPedro 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 * @(#)ffs_subr.c 8.5 (Berkeley) 3/21/95 34d347a0daSSam Leffler */ 35d347a0daSSam Leffler 36d347a0daSSam Leffler #include <sys/cdefs.h> 37d347a0daSSam Leffler __FBSDID("$FreeBSD$"); 38d347a0daSSam Leffler 39d347a0daSSam Leffler #include <sys/param.h> 405d71efbeSMarcel Moolenaar #include <sys/types.h> 41d347a0daSSam Leffler 42d347a0daSSam Leffler #include <ufs/ufs/dinode.h> 43d347a0daSSam Leffler #include <ufs/ffs/fs.h> 4455a1bde9SEd Schouten #include "ffs/ffs_extern.h" 45d347a0daSSam Leffler #include "ffs/ufs_bswap.h" 46ff13f23fSKirk McKusick 47d347a0daSSam Leffler /* 48d347a0daSSam Leffler * Update the frsum fields to reflect addition or deletion 49d347a0daSSam Leffler * of some frags. 50d347a0daSSam Leffler */ 51d347a0daSSam Leffler void 52d347a0daSSam Leffler ffs_fragacct_swap(struct fs *fs, int fragmap, int32_t fraglist[], int cnt, int needswap) 53d347a0daSSam Leffler { 54d347a0daSSam Leffler int inblk; 55d347a0daSSam Leffler int field, subfield; 56d347a0daSSam Leffler int siz, pos; 57d347a0daSSam Leffler 58d347a0daSSam Leffler inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 59d347a0daSSam Leffler fragmap <<= 1; 60d347a0daSSam Leffler for (siz = 1; siz < fs->fs_frag; siz++) { 61d347a0daSSam Leffler if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0) 62d347a0daSSam Leffler continue; 63d347a0daSSam Leffler field = around[siz]; 64d347a0daSSam Leffler subfield = inside[siz]; 65d347a0daSSam Leffler for (pos = siz; pos <= fs->fs_frag; pos++) { 66d347a0daSSam Leffler if ((fragmap & field) == subfield) { 67d347a0daSSam Leffler fraglist[siz] = ufs_rw32( 68d347a0daSSam Leffler ufs_rw32(fraglist[siz], needswap) + cnt, 69d347a0daSSam Leffler needswap); 70d347a0daSSam Leffler pos += siz; 71d347a0daSSam Leffler field <<= siz; 72d347a0daSSam Leffler subfield <<= siz; 73d347a0daSSam Leffler } 74d347a0daSSam Leffler field <<= 1; 75d347a0daSSam Leffler subfield <<= 1; 76d347a0daSSam Leffler } 77d347a0daSSam Leffler } 78d347a0daSSam Leffler } 79d347a0daSSam Leffler 80d347a0daSSam Leffler /* 81d347a0daSSam Leffler * block operations 82d347a0daSSam Leffler * 83d347a0daSSam Leffler * check if a block is available 843df5ecacSUlrich Spörlein * returns true if all the corresponding bits in the free map are 1 85d347a0daSSam Leffler * returns false if any corresponding bit in the free map is 0 86d347a0daSSam Leffler */ 87d347a0daSSam Leffler int 88d347a0daSSam Leffler ffs_isblock(fs, cp, h) 89d347a0daSSam Leffler struct fs *fs; 90d347a0daSSam Leffler u_char *cp; 91d347a0daSSam Leffler int32_t h; 92d347a0daSSam Leffler { 93d347a0daSSam Leffler u_char mask; 94d347a0daSSam Leffler 95d347a0daSSam Leffler switch ((int)fs->fs_fragshift) { 96d347a0daSSam Leffler case 3: 97d347a0daSSam Leffler return (cp[h] == 0xff); 98d347a0daSSam Leffler case 2: 99d347a0daSSam Leffler mask = 0x0f << ((h & 0x1) << 2); 100d347a0daSSam Leffler return ((cp[h >> 1] & mask) == mask); 101d347a0daSSam Leffler case 1: 102d347a0daSSam Leffler mask = 0x03 << ((h & 0x3) << 1); 103d347a0daSSam Leffler return ((cp[h >> 2] & mask) == mask); 104d347a0daSSam Leffler case 0: 105d347a0daSSam Leffler mask = 0x01 << (h & 0x7); 106d347a0daSSam Leffler return ((cp[h >> 3] & mask) == mask); 107d347a0daSSam Leffler default: 108d347a0daSSam Leffler panic("ffs_isblock: unknown fs_fragshift %d", 109d347a0daSSam Leffler (int)fs->fs_fragshift); 110d347a0daSSam Leffler } 111d347a0daSSam Leffler } 112d347a0daSSam Leffler 113d347a0daSSam Leffler /* 114d347a0daSSam Leffler * check if a block is completely allocated 115d347a0daSSam Leffler * returns true if all the corresponding bits in the free map are 0 116d347a0daSSam Leffler * returns false if any corresponding bit in the free map is 1 117d347a0daSSam Leffler */ 118d347a0daSSam Leffler int 119d347a0daSSam Leffler ffs_isfreeblock(fs, cp, h) 120d347a0daSSam Leffler struct fs *fs; 121d347a0daSSam Leffler u_char *cp; 122d347a0daSSam Leffler int32_t h; 123d347a0daSSam Leffler { 124d347a0daSSam Leffler 125d347a0daSSam Leffler switch ((int)fs->fs_fragshift) { 126d347a0daSSam Leffler case 3: 127d347a0daSSam Leffler return (cp[h] == 0); 128d347a0daSSam Leffler case 2: 129d347a0daSSam Leffler return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0); 130d347a0daSSam Leffler case 1: 131d347a0daSSam Leffler return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0); 132d347a0daSSam Leffler case 0: 133d347a0daSSam Leffler return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0); 134d347a0daSSam Leffler default: 135d347a0daSSam Leffler panic("ffs_isfreeblock: unknown fs_fragshift %d", 136d347a0daSSam Leffler (int)fs->fs_fragshift); 137d347a0daSSam Leffler } 138d347a0daSSam Leffler } 139d347a0daSSam Leffler 140d347a0daSSam Leffler /* 141d347a0daSSam Leffler * take a block out of the map 142d347a0daSSam Leffler */ 143d347a0daSSam Leffler void 144d347a0daSSam Leffler ffs_clrblock(fs, cp, h) 145d347a0daSSam Leffler struct fs *fs; 146d347a0daSSam Leffler u_char *cp; 147d347a0daSSam Leffler int32_t h; 148d347a0daSSam Leffler { 149d347a0daSSam Leffler 150d347a0daSSam Leffler switch ((int)fs->fs_fragshift) { 151d347a0daSSam Leffler case 3: 152d347a0daSSam Leffler cp[h] = 0; 153d347a0daSSam Leffler return; 154d347a0daSSam Leffler case 2: 155d347a0daSSam Leffler cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 156d347a0daSSam Leffler return; 157d347a0daSSam Leffler case 1: 158d347a0daSSam Leffler cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 159d347a0daSSam Leffler return; 160d347a0daSSam Leffler case 0: 161d347a0daSSam Leffler cp[h >> 3] &= ~(0x01 << (h & 0x7)); 162d347a0daSSam Leffler return; 163d347a0daSSam Leffler default: 164d347a0daSSam Leffler panic("ffs_clrblock: unknown fs_fragshift %d", 165d347a0daSSam Leffler (int)fs->fs_fragshift); 166d347a0daSSam Leffler } 167d347a0daSSam Leffler } 168d347a0daSSam Leffler 169d347a0daSSam Leffler /* 170d347a0daSSam Leffler * put a block into the map 171d347a0daSSam Leffler */ 172d347a0daSSam Leffler void 173d347a0daSSam Leffler ffs_setblock(fs, cp, h) 174d347a0daSSam Leffler struct fs *fs; 175d347a0daSSam Leffler u_char *cp; 176d347a0daSSam Leffler int32_t h; 177d347a0daSSam Leffler { 178d347a0daSSam Leffler 179d347a0daSSam Leffler switch ((int)fs->fs_fragshift) { 180d347a0daSSam Leffler case 3: 181d347a0daSSam Leffler cp[h] = 0xff; 182d347a0daSSam Leffler return; 183d347a0daSSam Leffler case 2: 184d347a0daSSam Leffler cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 185d347a0daSSam Leffler return; 186d347a0daSSam Leffler case 1: 187d347a0daSSam Leffler cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 188d347a0daSSam Leffler return; 189d347a0daSSam Leffler case 0: 190d347a0daSSam Leffler cp[h >> 3] |= (0x01 << (h & 0x7)); 191d347a0daSSam Leffler return; 192d347a0daSSam Leffler default: 193d347a0daSSam Leffler panic("ffs_setblock: unknown fs_fragshift %d", 194d347a0daSSam Leffler (int)fs->fs_fragshift); 195d347a0daSSam Leffler } 196d347a0daSSam Leffler } 197