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