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