123402Smckusick /* 237737Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337737Smckusick * All rights reserved. 423402Smckusick * 544539Sbostic * %sccs.include.redist.c% 637737Smckusick * 7*53706Smckusick * @(#)ffs_subr.c 7.21 (Berkeley) 05/27/92 823402Smckusick */ 98719Sroot 108719Sroot #include <sys/param.h> 1151471Sbostic #include <ufs/ffs/fs.h> 1251471Sbostic 1351636Sbostic #ifdef KERNEL 14*53706Smckusick #include <sys/vnode.h> 15*53706Smckusick #include <ufs/ffs/ffs_extern.h> 1651956Smckusick #include <sys/buf.h> 1751956Smckusick #include <ufs/ufs/quota.h> 1851956Smckusick #include <ufs/ufs/inode.h> 1951636Sbostic 208719Sroot /* 2151471Sbostic * Return buffer with the contents of block "offset" from the beginning of 2251471Sbostic * directory "ip". If "res" is non-zero, fill it in with a pointer to the 2351471Sbostic * remaining space in the directory. 2451471Sbostic */ 2551471Sbostic int 2653521Sheideman ffs_blkatoff (ap) 2753521Sheideman struct vop_blkatoff_args *ap; 2851471Sbostic { 2951543Smckusick struct inode *ip; 3051471Sbostic register struct fs *fs; 3151471Sbostic struct buf *bp; 3251471Sbostic daddr_t lbn; 3351471Sbostic int bsize, error; 3451471Sbostic 3553586Sheideman ip = VTOI(ap->a_vp); 3651471Sbostic fs = ip->i_fs; 3753586Sheideman lbn = lblkno(fs, ap->a_offset); 3851471Sbostic bsize = blksize(fs, ip, lbn); 3951471Sbostic 4053586Sheideman *ap->a_bpp = NULL; 4153586Sheideman if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) { 4251471Sbostic brelse(bp); 4351471Sbostic return (error); 4451471Sbostic } 4553586Sheideman if (ap->a_res) 4653586Sheideman *ap->a_res = bp->b_un.b_addr + blkoff(fs, ap->a_offset); 4753586Sheideman *ap->a_bpp = bp; 4851471Sbostic return (0); 4951471Sbostic } 5051636Sbostic #endif 5151471Sbostic 5251471Sbostic /* 538719Sroot * Update the frsum fields to reflect addition or deletion 548719Sroot * of some frags. 558719Sroot */ 5651471Sbostic void 5751471Sbostic ffs_fragacct(fs, fragmap, fraglist, cnt) 588719Sroot struct fs *fs; 598719Sroot int fragmap; 608719Sroot long fraglist[]; 618719Sroot int cnt; 628719Sroot { 638719Sroot int inblk; 648719Sroot register int field, subfield; 658719Sroot register int siz, pos; 668719Sroot 678719Sroot inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1; 688719Sroot fragmap <<= 1; 698719Sroot for (siz = 1; siz < fs->fs_frag; siz++) { 708719Sroot if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 718719Sroot continue; 728719Sroot field = around[siz]; 738719Sroot subfield = inside[siz]; 748719Sroot for (pos = siz; pos <= fs->fs_frag; pos++) { 758719Sroot if ((fragmap & field) == subfield) { 768719Sroot fraglist[siz] += cnt; 778719Sroot pos += siz; 788719Sroot field <<= siz; 798719Sroot subfield <<= siz; 808719Sroot } 818719Sroot field <<= 1; 828719Sroot subfield <<= 1; 838719Sroot } 848719Sroot } 858719Sroot } 868719Sroot 8751636Sbostic #if defined(KERNEL) && defined(DIAGNOSTIC) 8851471Sbostic void 8951471Sbostic ffs_checkoverlap(bp, ip) 9051471Sbostic struct buf *bp; 9151471Sbostic struct inode *ip; 9251471Sbostic { 9353521Sheideman USES_VOP_BMAP; 9451471Sbostic register struct buf *ebp, *ep; 9551471Sbostic register daddr_t start, last; 9651471Sbostic struct vnode *vp; 9751471Sbostic 9851471Sbostic ebp = &buf[nbuf]; 9951471Sbostic start = bp->b_blkno; 10051471Sbostic last = start + btodb(bp->b_bcount) - 1; 10151471Sbostic for (ep = buf; ep < ebp; ep++) { 10251471Sbostic if (ep == bp || (ep->b_flags & B_INVAL) || 10351471Sbostic ep->b_vp == NULLVP) 10451471Sbostic continue; 10551471Sbostic if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0)) 10651471Sbostic continue; 10751471Sbostic if (vp != ip->i_devvp) 10851471Sbostic continue; 10951471Sbostic /* look for overlap */ 11051471Sbostic if (ep->b_bcount == 0 || ep->b_blkno > last || 11151471Sbostic ep->b_blkno + btodb(ep->b_bcount) <= start) 11251471Sbostic continue; 11351471Sbostic vprint("Disk overlap", vp); 11451471Sbostic (void)printf("\tstart %d, end %d overlap start %d, end %d\n", 11551471Sbostic start, last, ep->b_blkno, 11651471Sbostic ep->b_blkno + btodb(ep->b_bcount) - 1); 11751471Sbostic panic("Disk buffer overlap"); 11851471Sbostic } 11951471Sbostic } 12051471Sbostic #endif /* DIAGNOSTIC */ 12151471Sbostic 1228719Sroot /* 1238719Sroot * block operations 1248719Sroot * 1258719Sroot * check if a block is available 1268719Sroot */ 12751471Sbostic int 12851471Sbostic ffs_isblock(fs, cp, h) 1298719Sroot struct fs *fs; 1308719Sroot unsigned char *cp; 1318719Sroot daddr_t h; 1328719Sroot { 1338719Sroot unsigned char mask; 1348719Sroot 13526309Skarels switch ((int)fs->fs_frag) { 1368719Sroot case 8: 1378719Sroot return (cp[h] == 0xff); 1388719Sroot case 4: 1398719Sroot mask = 0x0f << ((h & 0x1) << 2); 1408719Sroot return ((cp[h >> 1] & mask) == mask); 1418719Sroot case 2: 1428719Sroot mask = 0x03 << ((h & 0x3) << 1); 1438719Sroot return ((cp[h >> 2] & mask) == mask); 1448719Sroot case 1: 1458719Sroot mask = 0x01 << (h & 0x7); 1468719Sroot return ((cp[h >> 3] & mask) == mask); 1478719Sroot default: 14851471Sbostic panic("ffs_isblock"); 1498719Sroot } 1508719Sroot } 1518719Sroot 1528719Sroot /* 1538719Sroot * take a block out of the map 1548719Sroot */ 15551471Sbostic void 15651471Sbostic ffs_clrblock(fs, cp, h) 1578719Sroot struct fs *fs; 1588770Sroot u_char *cp; 1598719Sroot daddr_t h; 1608719Sroot { 1618719Sroot 16226309Skarels switch ((int)fs->fs_frag) { 1638719Sroot case 8: 1648719Sroot cp[h] = 0; 1658719Sroot return; 1668719Sroot case 4: 1678719Sroot cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 1688719Sroot return; 1698719Sroot case 2: 1708719Sroot cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 1718719Sroot return; 1728719Sroot case 1: 1738719Sroot cp[h >> 3] &= ~(0x01 << (h & 0x7)); 1748719Sroot return; 1758719Sroot default: 17651471Sbostic panic("ffs_clrblock"); 1778719Sroot } 1788719Sroot } 1798719Sroot 1808719Sroot /* 1818719Sroot * put a block into the map 1828719Sroot */ 18351471Sbostic void 18451471Sbostic ffs_setblock(fs, cp, h) 1858719Sroot struct fs *fs; 1868719Sroot unsigned char *cp; 1878719Sroot daddr_t h; 1888719Sroot { 1898719Sroot 19026309Skarels switch ((int)fs->fs_frag) { 1918719Sroot 1928719Sroot case 8: 1938719Sroot cp[h] = 0xff; 1948719Sroot return; 1958719Sroot case 4: 1968719Sroot cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 1978719Sroot return; 1988719Sroot case 2: 1998719Sroot cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 2008719Sroot return; 2018719Sroot case 1: 2028719Sroot cp[h >> 3] |= (0x01 << (h & 0x7)); 2038719Sroot return; 2048719Sroot default: 20551471Sbostic panic("ffs_setblock"); 2068719Sroot } 2078719Sroot } 2089167Ssam 20941537Smckusick #if (!defined(vax) && !defined(tahoe) && !defined(hp300)) \ 21041537Smckusick || defined(VAX630) || defined(VAX650) 21121090Smckusick /* 21229947Skarels * C definitions of special instructions. 21329947Skarels * Normally expanded with inline. 21421090Smckusick */ 21551471Sbostic int 21621090Smckusick scanc(size, cp, table, mask) 21721090Smckusick u_int size; 21821090Smckusick register u_char *cp, table[]; 21921090Smckusick register u_char mask; 22021090Smckusick { 22121090Smckusick register u_char *end = &cp[size]; 22221090Smckusick 22321090Smckusick while (cp < end && (table[*cp] & mask) == 0) 22421090Smckusick cp++; 22521090Smckusick return (end - cp); 22621090Smckusick } 22727476Skridle #endif 22827476Skridle 22941537Smckusick #if !defined(vax) && !defined(tahoe) && !defined(hp300) 23051471Sbostic int 23121090Smckusick skpc(mask, size, cp) 23221090Smckusick register u_char mask; 23321090Smckusick u_int size; 23421090Smckusick register u_char *cp; 23521090Smckusick { 23621090Smckusick register u_char *end = &cp[size]; 23721090Smckusick 23821090Smckusick while (cp < end && *cp == mask) 23921090Smckusick cp++; 24021090Smckusick return (end - cp); 24121090Smckusick } 24221090Smckusick 24351471Sbostic int 24421090Smckusick locc(mask, size, cp) 24521090Smckusick register u_char mask; 24621090Smckusick u_int size; 24721090Smckusick register u_char *cp; 24821090Smckusick { 24921090Smckusick register u_char *end = &cp[size]; 25021090Smckusick 25121090Smckusick while (cp < end && *cp != mask) 25221090Smckusick cp++; 25321090Smckusick return (end - cp); 25421090Smckusick } 25529947Skarels #endif 256