summaryrefslogtreecommitdiff
path: root/ufs/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ufs/subr.c')
-rw-r--r--ufs/subr.c187
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);
+}