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