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