1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)ffs_subr.c 7.11 (Berkeley) 12/30/89 18 */ 19 20 #ifdef KERNEL 21 #include "param.h" 22 #include "../ufs/fs.h" 23 #else 24 #include <sys/param.h> 25 #include <ufs/fs.h> 26 #endif 27 28 extern int around[9]; 29 extern int inside[9]; 30 extern u_char *fragtbl[]; 31 32 /* 33 * Update the frsum fields to reflect addition or deletion 34 * of some frags. 35 */ 36 fragacct(fs, fragmap, fraglist, cnt) 37 struct fs *fs; 38 int fragmap; 39 long fraglist[]; 40 int cnt; 41 { 42 int inblk; 43 register int field, subfield; 44 register int siz, pos; 45 46 inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 47 fragmap <<= 1; 48 for (siz = 1; siz < fs->fs_frag; siz++) { 49 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 50 continue; 51 field = around[siz]; 52 subfield = inside[siz]; 53 for (pos = siz; pos <= fs->fs_frag; pos++) { 54 if ((fragmap & field) == subfield) { 55 fraglist[siz] += cnt; 56 pos += siz; 57 field <<= siz; 58 subfield <<= siz; 59 } 60 field <<= 1; 61 subfield <<= 1; 62 } 63 } 64 } 65 66 /* 67 * block operations 68 * 69 * check if a block is available 70 */ 71 isblock(fs, cp, h) 72 struct fs *fs; 73 unsigned char *cp; 74 daddr_t h; 75 { 76 unsigned char mask; 77 78 switch ((int)fs->fs_frag) { 79 case 8: 80 return (cp[h] == 0xff); 81 case 4: 82 mask = 0x0f << ((h & 0x1) << 2); 83 return ((cp[h >> 1] & mask) == mask); 84 case 2: 85 mask = 0x03 << ((h & 0x3) << 1); 86 return ((cp[h >> 2] & mask) == mask); 87 case 1: 88 mask = 0x01 << (h & 0x7); 89 return ((cp[h >> 3] & mask) == mask); 90 default: 91 panic("isblock"); 92 return (NULL); 93 } 94 } 95 96 /* 97 * take a block out of the map 98 */ 99 clrblock(fs, cp, h) 100 struct fs *fs; 101 u_char *cp; 102 daddr_t h; 103 { 104 105 switch ((int)fs->fs_frag) { 106 case 8: 107 cp[h] = 0; 108 return; 109 case 4: 110 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 111 return; 112 case 2: 113 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 114 return; 115 case 1: 116 cp[h >> 3] &= ~(0x01 << (h & 0x7)); 117 return; 118 default: 119 panic("clrblock"); 120 } 121 } 122 123 /* 124 * put a block into the map 125 */ 126 setblock(fs, cp, h) 127 struct fs *fs; 128 unsigned char *cp; 129 daddr_t h; 130 { 131 132 switch ((int)fs->fs_frag) { 133 134 case 8: 135 cp[h] = 0xff; 136 return; 137 case 4: 138 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 139 return; 140 case 2: 141 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 142 return; 143 case 1: 144 cp[h >> 3] |= (0x01 << (h & 0x7)); 145 return; 146 default: 147 panic("setblock"); 148 } 149 } 150 151 #if (!defined(vax) && !defined(tahoe)) || defined(VAX630) || defined(VAX650) 152 /* 153 * C definitions of special instructions. 154 * Normally expanded with inline. 155 */ 156 scanc(size, cp, table, mask) 157 u_int size; 158 register u_char *cp, table[]; 159 register u_char mask; 160 { 161 register u_char *end = &cp[size]; 162 163 while (cp < end && (table[*cp] & mask) == 0) 164 cp++; 165 return (end - cp); 166 } 167 #endif 168 169 #if !defined(vax) && !defined(tahoe) 170 skpc(mask, size, cp) 171 register u_char mask; 172 u_int size; 173 register u_char *cp; 174 { 175 register u_char *end = &cp[size]; 176 177 while (cp < end && *cp == mask) 178 cp++; 179 return (end - cp); 180 } 181 182 locc(mask, size, cp) 183 register u_char mask; 184 u_int size; 185 register u_char *cp; 186 { 187 register u_char *end = &cp[size]; 188 189 while (cp < end && *cp != mask) 190 cp++; 191 return (end - cp); 192 } 193 #endif 194