123402Smckusick /* 237737Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337737Smckusick * All rights reserved. 423402Smckusick * 537737Smckusick * Redistribution and use in source and binary forms are permitted 637737Smckusick * provided that the above copyright notice and this paragraph are 737737Smckusick * duplicated in all such forms and that any documentation, 837737Smckusick * advertising materials, and other materials related to such 937737Smckusick * distribution and use acknowledge that the software was developed 1037737Smckusick * by the University of California, Berkeley. The name of the 1137737Smckusick * University may not be used to endorse or promote products derived 1237737Smckusick * from this software without specific prior written permission. 1337737Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1437737Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1537737Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1637737Smckusick * 17*41537Smckusick * @(#)ffs_subr.c 7.12 (Berkeley) 05/10/90 1823402Smckusick */ 198719Sroot 208719Sroot #ifdef KERNEL 2117101Sbloom #include "param.h" 2237737Smckusick #include "../ufs/fs.h" 238719Sroot #else 248719Sroot #include <sys/param.h> 2537737Smckusick #include <ufs/fs.h> 268719Sroot #endif 278719Sroot 288719Sroot extern int around[9]; 298719Sroot extern int inside[9]; 308719Sroot extern u_char *fragtbl[]; 318719Sroot 328719Sroot /* 338719Sroot * Update the frsum fields to reflect addition or deletion 348719Sroot * of some frags. 358719Sroot */ 368719Sroot fragacct(fs, fragmap, fraglist, cnt) 378719Sroot struct fs *fs; 388719Sroot int fragmap; 398719Sroot long fraglist[]; 408719Sroot int cnt; 418719Sroot { 428719Sroot int inblk; 438719Sroot register int field, subfield; 448719Sroot register int siz, pos; 458719Sroot 468719Sroot inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 478719Sroot fragmap <<= 1; 488719Sroot for (siz = 1; siz < fs->fs_frag; siz++) { 498719Sroot if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 508719Sroot continue; 518719Sroot field = around[siz]; 528719Sroot subfield = inside[siz]; 538719Sroot for (pos = siz; pos <= fs->fs_frag; pos++) { 548719Sroot if ((fragmap & field) == subfield) { 558719Sroot fraglist[siz] += cnt; 568719Sroot pos += siz; 578719Sroot field <<= siz; 588719Sroot subfield <<= siz; 598719Sroot } 608719Sroot field <<= 1; 618719Sroot subfield <<= 1; 628719Sroot } 638719Sroot } 648719Sroot } 658719Sroot 668719Sroot /* 678719Sroot * block operations 688719Sroot * 698719Sroot * check if a block is available 708719Sroot */ 718719Sroot isblock(fs, cp, h) 728719Sroot struct fs *fs; 738719Sroot unsigned char *cp; 748719Sroot daddr_t h; 758719Sroot { 768719Sroot unsigned char mask; 778719Sroot 7826309Skarels switch ((int)fs->fs_frag) { 798719Sroot case 8: 808719Sroot return (cp[h] == 0xff); 818719Sroot case 4: 828719Sroot mask = 0x0f << ((h & 0x1) << 2); 838719Sroot return ((cp[h >> 1] & mask) == mask); 848719Sroot case 2: 858719Sroot mask = 0x03 << ((h & 0x3) << 1); 868719Sroot return ((cp[h >> 2] & mask) == mask); 878719Sroot case 1: 888719Sroot mask = 0x01 << (h & 0x7); 898719Sroot return ((cp[h >> 3] & mask) == mask); 908719Sroot default: 918719Sroot panic("isblock"); 928719Sroot return (NULL); 938719Sroot } 948719Sroot } 958719Sroot 968719Sroot /* 978719Sroot * take a block out of the map 988719Sroot */ 998719Sroot clrblock(fs, cp, h) 1008719Sroot struct fs *fs; 1018770Sroot u_char *cp; 1028719Sroot daddr_t h; 1038719Sroot { 1048719Sroot 10526309Skarels switch ((int)fs->fs_frag) { 1068719Sroot case 8: 1078719Sroot cp[h] = 0; 1088719Sroot return; 1098719Sroot case 4: 1108719Sroot cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1118719Sroot return; 1128719Sroot case 2: 1138719Sroot cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1148719Sroot return; 1158719Sroot case 1: 1168719Sroot cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1178719Sroot return; 1188719Sroot default: 1198719Sroot panic("clrblock"); 1208719Sroot } 1218719Sroot } 1228719Sroot 1238719Sroot /* 1248719Sroot * put a block into the map 1258719Sroot */ 1268719Sroot setblock(fs, cp, h) 1278719Sroot struct fs *fs; 1288719Sroot unsigned char *cp; 1298719Sroot daddr_t h; 1308719Sroot { 1318719Sroot 13226309Skarels switch ((int)fs->fs_frag) { 1338719Sroot 1348719Sroot case 8: 1358719Sroot cp[h] = 0xff; 1368719Sroot return; 1378719Sroot case 4: 1388719Sroot cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1398719Sroot return; 1408719Sroot case 2: 1418719Sroot cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 1428719Sroot return; 1438719Sroot case 1: 1448719Sroot cp[h >> 3] |= (0x01 << (h & 0x7)); 1458719Sroot return; 1468719Sroot default: 1478719Sroot panic("setblock"); 1488719Sroot } 1498719Sroot } 1509167Ssam 151*41537Smckusick #if (!defined(vax) && !defined(tahoe) && !defined(hp300)) \ 152*41537Smckusick || defined(VAX630) || defined(VAX650) 15321090Smckusick /* 15429947Skarels * C definitions of special instructions. 15529947Skarels * Normally expanded with inline. 15621090Smckusick */ 15721090Smckusick scanc(size, cp, table, mask) 15821090Smckusick u_int size; 15921090Smckusick register u_char *cp, table[]; 16021090Smckusick register u_char mask; 16121090Smckusick { 16221090Smckusick register u_char *end = &cp[size]; 16321090Smckusick 16421090Smckusick while (cp < end && (table[*cp] & mask) == 0) 16521090Smckusick cp++; 16621090Smckusick return (end - cp); 16721090Smckusick } 16827476Skridle #endif 16927476Skridle 170*41537Smckusick #if !defined(vax) && !defined(tahoe) && !defined(hp300) 17121090Smckusick skpc(mask, size, cp) 17221090Smckusick register u_char mask; 17321090Smckusick u_int size; 17421090Smckusick register u_char *cp; 17521090Smckusick { 17621090Smckusick register u_char *end = &cp[size]; 17721090Smckusick 17821090Smckusick while (cp < end && *cp == mask) 17921090Smckusick cp++; 18021090Smckusick return (end - cp); 18121090Smckusick } 18221090Smckusick 18321090Smckusick locc(mask, size, cp) 18421090Smckusick register u_char mask; 18521090Smckusick u_int size; 18621090Smckusick register u_char *cp; 18721090Smckusick { 18821090Smckusick register u_char *end = &cp[size]; 18921090Smckusick 19021090Smckusick while (cp < end && *cp != mask) 19121090Smckusick cp++; 19221090Smckusick return (end - cp); 19321090Smckusick } 19429947Skarels #endif 195