diff options
Diffstat (limited to 'ufs/subr.c')
-rw-r--r-- | ufs/subr.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/ufs/subr.c b/ufs/subr.c new file mode 100644 index 00000000..b61b09d6 --- /dev/null +++ b/ufs/subr.c @@ -0,0 +1,187 @@ +/* Miscellaneous map manipulation routines + Copyright (C) 1991, 1992, 1994 Free Software Foundation + +This file is part of the GNU Hurd. + +The GNU Hurd is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +The GNU Hurd is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU Hurd; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Slightly modified from UCB by Michael I. Bushnell. */ + +/* + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution is only permitted until one year after the first shipment + * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and + * binary forms are permitted provided that: (1) source distributions retain + * this entire copyright notice and comment, and (2) distributions including + * binaries display the following acknowledgement: This product includes + * software developed by the University of California, Berkeley and its + * contributors'' in the documentation or other materials provided with the + * distribution and in all advertising materials mentioning features or use + * of this software. Neither the name of the University nor the names of + * its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ufs_subr.c 7.13 (Berkeley) 6/28/90 + */ + + +#include <assert.h> + +extern int around[9]; +extern int inside[9]; +extern u_char *fragtbl[]; + +/* + * Update the frsum fields to reflect addition or deletion + * of some frags. + */ +void +fragacct(int fragmap, + long fraglist[], + int cnt) +{ + int inblk; + int field, subfield; + int siz, pos; + + inblk = (int)(fragtbl[sblock->fs_frag][fragmap]) << 1; + fragmap <<= 1; + for (siz = 1; siz < sblock->fs_frag; siz++) { + if ((inblk & (1 << (siz + (sblock->fs_frag % NBBY)))) == 0) + continue; + field = around[siz]; + subfield = inside[siz]; + for (pos = siz; pos <= sblock->fs_frag; pos++) { + if ((fragmap & field) == subfield) { + fraglist[siz] += cnt; + pos += siz; + field <<= siz; + subfield <<= siz; + } + field <<= 1; + subfield <<= 1; + } + } +} + +/* + * block operations + * + * check if a block is available + */ +int +isblock(u_char *cp, + daddr_t h) +{ + u_char mask; + + switch ((int)sblock->fs_frag) { + case 8: + return (cp[h] == 0xff); + case 4: + mask = 0x0f << ((h & 0x1) << 2); + return ((cp[h >> 1] & mask) == mask); + case 2: + mask = 0x03 << ((h & 0x3) << 1); + return ((cp[h >> 2] & mask) == mask); + case 1: + mask = 0x01 << (h & 0x7); + return ((cp[h >> 3] & mask) == mask); + default: + assert (0); + } +} + +/* + * take a block out of the map + */ +void +clrblock(u_char *cp, + daddr_t h) +{ + + switch ((int)sblock->fs_frag) { + case 8: + cp[h] = 0; + return; + case 4: + cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); + return; + case 2: + cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); + return; + case 1: + cp[h >> 3] &= ~(0x01 << (h & 0x7)); + return; + default: + assert (0); + } +} + +/* + * put a block into the map + */ +void +setblock(u_char *cp, + daddr_t h) +{ + switch ((int)sblock->fs_frag) { + + case 8: + cp[h] = 0xff; + return; + case 4: + cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); + return; + case 2: + cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); + return; + case 1: + cp[h >> 3] |= (0x01 << (h & 0x7)); + return; + default: + assert (0); + } +} + +int +skpc(u_char mask, + u_int size, + u_char *cp) +{ + u_char *end = &cp[size]; + + while (cp < end && *cp == mask) + cp++; + return (end - cp); +} + +int +scanc(u_int size, + u_char *cp, + u_char table[], + u_char mask) +{ + register u_char *end = &cp[size]; + + while (cp < end && (table[*cp] & mask) == 0) + cp++; + return (end - cp); +} |