xref: /dflybsd-src/usr.sbin/makefs/ffs/ffs_subr.c (revision c3ba2018f9c7e075ad7429043b57c2fe146306d7)
15978408cSSascha Wildner /*	$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $	*/
25978408cSSascha Wildner 
35978408cSSascha Wildner /*-
45978408cSSascha Wildner  * SPDX-License-Identifier: BSD-3-Clause
55978408cSSascha Wildner  *
65978408cSSascha Wildner  * Copyright (c) 1982, 1986, 1989, 1993
75978408cSSascha Wildner  *	The Regents of the University of California.  All rights reserved.
85978408cSSascha Wildner  *
95978408cSSascha Wildner  * Redistribution and use in source and binary forms, with or without
105978408cSSascha Wildner  * modification, are permitted provided that the following conditions
115978408cSSascha Wildner  * are met:
125978408cSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
135978408cSSascha Wildner  *    notice, this list of conditions and the following disclaimer.
145978408cSSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
155978408cSSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
165978408cSSascha Wildner  *    documentation and/or other materials provided with the distribution.
175978408cSSascha Wildner  * 3. Neither the name of the University nor the names of its contributors
185978408cSSascha Wildner  *    may be used to endorse or promote products derived from this software
195978408cSSascha Wildner  *    without specific prior written permission.
205978408cSSascha Wildner  *
215978408cSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
225978408cSSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
235978408cSSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
245978408cSSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
255978408cSSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
265978408cSSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
275978408cSSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
285978408cSSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
295978408cSSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
305978408cSSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
315978408cSSascha Wildner  * SUCH DAMAGE.
325978408cSSascha Wildner  *
335978408cSSascha Wildner  *	@(#)ffs_subr.c	8.5 (Berkeley) 3/21/95
34811c2036SSascha Wildner  * $FreeBSD: head/usr.sbin/makefs/ffs/ffs_subr.c 333664 2018-05-16 02:58:05Z emaste $
355978408cSSascha Wildner  */
365978408cSSascha Wildner 
375978408cSSascha Wildner #include <sys/param.h>
385978408cSSascha Wildner #include <sys/types.h>
395978408cSSascha Wildner 
40346b9dadSzrj #include <vfs/ufs/dinode.h>
41346b9dadSzrj #include <vfs/ufs/fs.h>
425978408cSSascha Wildner #include "ffs/ffs_extern.h"
435978408cSSascha Wildner #include "ffs/ufs_bswap.h"
445978408cSSascha Wildner 
455978408cSSascha Wildner /*
465978408cSSascha Wildner  * Update the frsum fields to reflect addition or deletion
475978408cSSascha Wildner  * of some frags.
485978408cSSascha Wildner  */
495978408cSSascha Wildner void
ffs_fragacct_swap(struct fs * fs,int fragmap,uint32_t fraglist[],int cnt,int needswap)50*c3ba2018STomohiro Kusumi ffs_fragacct_swap(struct fs *fs, int fragmap, uint32_t fraglist[], int cnt, int needswap)
515978408cSSascha Wildner {
525978408cSSascha Wildner 	int inblk;
535978408cSSascha Wildner 	int field, subfield;
545978408cSSascha Wildner 	int siz, pos;
555978408cSSascha Wildner 
565978408cSSascha Wildner 	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
575978408cSSascha Wildner 	fragmap <<= 1;
585978408cSSascha Wildner 	for (siz = 1; siz < fs->fs_frag; siz++) {
595978408cSSascha Wildner 		if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0)
605978408cSSascha Wildner 			continue;
615978408cSSascha Wildner 		field = around[siz];
625978408cSSascha Wildner 		subfield = inside[siz];
635978408cSSascha Wildner 		for (pos = siz; pos <= fs->fs_frag; pos++) {
645978408cSSascha Wildner 			if ((fragmap & field) == subfield) {
655978408cSSascha Wildner 				fraglist[siz] = ufs_rw32(
665978408cSSascha Wildner 				    ufs_rw32(fraglist[siz], needswap) + cnt,
675978408cSSascha Wildner 				    needswap);
685978408cSSascha Wildner 				pos += siz;
695978408cSSascha Wildner 				field <<= siz;
705978408cSSascha Wildner 				subfield <<= siz;
715978408cSSascha Wildner 			}
725978408cSSascha Wildner 			field <<= 1;
735978408cSSascha Wildner 			subfield <<= 1;
745978408cSSascha Wildner 		}
755978408cSSascha Wildner 	}
765978408cSSascha Wildner }
775978408cSSascha Wildner 
785978408cSSascha Wildner /*
795978408cSSascha Wildner  * block operations
805978408cSSascha Wildner  *
815978408cSSascha Wildner  * check if a block is available
825978408cSSascha Wildner  *  returns true if all the corresponding bits in the free map are 1
835978408cSSascha Wildner  *  returns false if any corresponding bit in the free map is 0
845978408cSSascha Wildner  */
855978408cSSascha Wildner int
ffs_isblock(struct fs * fs,u_char * cp,int32_t h)865978408cSSascha Wildner ffs_isblock(struct fs *fs, u_char *cp, int32_t h)
875978408cSSascha Wildner {
885978408cSSascha Wildner 	u_char mask;
895978408cSSascha Wildner 
905978408cSSascha Wildner 	switch ((int)fs->fs_fragshift) {
915978408cSSascha Wildner 	case 3:
925978408cSSascha Wildner 		return (cp[h] == 0xff);
935978408cSSascha Wildner 	case 2:
945978408cSSascha Wildner 		mask = 0x0f << ((h & 0x1) << 2);
955978408cSSascha Wildner 		return ((cp[h >> 1] & mask) == mask);
965978408cSSascha Wildner 	case 1:
975978408cSSascha Wildner 		mask = 0x03 << ((h & 0x3) << 1);
985978408cSSascha Wildner 		return ((cp[h >> 2] & mask) == mask);
995978408cSSascha Wildner 	case 0:
1005978408cSSascha Wildner 		mask = 0x01 << (h & 0x7);
1015978408cSSascha Wildner 		return ((cp[h >> 3] & mask) == mask);
1025978408cSSascha Wildner 	default:
1035978408cSSascha Wildner 		panic("ffs_isblock: unknown fs_fragshift %d",
1045978408cSSascha Wildner 		    (int)fs->fs_fragshift);
1055978408cSSascha Wildner 	}
1065978408cSSascha Wildner }
1075978408cSSascha Wildner 
1085978408cSSascha Wildner /*
1095978408cSSascha Wildner  * check if a block is completely allocated
1105978408cSSascha Wildner  *  returns true if all the corresponding bits in the free map are 0
1115978408cSSascha Wildner  *  returns false if any corresponding bit in the free map is 1
1125978408cSSascha Wildner  */
1135978408cSSascha Wildner int
ffs_isfreeblock(struct fs * fs,u_char * cp,int32_t h)1145978408cSSascha Wildner ffs_isfreeblock(struct fs *fs, u_char *cp, int32_t h)
1155978408cSSascha Wildner {
1165978408cSSascha Wildner 
1175978408cSSascha Wildner 	switch ((int)fs->fs_fragshift) {
1185978408cSSascha Wildner 	case 3:
1195978408cSSascha Wildner 		return (cp[h] == 0);
1205978408cSSascha Wildner 	case 2:
1215978408cSSascha Wildner 		return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
1225978408cSSascha Wildner 	case 1:
1235978408cSSascha Wildner 		return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
1245978408cSSascha Wildner 	case 0:
1255978408cSSascha Wildner 		return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
1265978408cSSascha Wildner 	default:
1275978408cSSascha Wildner 		panic("ffs_isfreeblock: unknown fs_fragshift %d",
1285978408cSSascha Wildner 		    (int)fs->fs_fragshift);
1295978408cSSascha Wildner 	}
1305978408cSSascha Wildner }
1315978408cSSascha Wildner 
1325978408cSSascha Wildner /*
1335978408cSSascha Wildner  * take a block out of the map
1345978408cSSascha Wildner  */
1355978408cSSascha Wildner void
ffs_clrblock(struct fs * fs,u_char * cp,int32_t h)1365978408cSSascha Wildner ffs_clrblock(struct fs *fs, u_char *cp, int32_t h)
1375978408cSSascha Wildner {
1385978408cSSascha Wildner 
1395978408cSSascha Wildner 	switch ((int)fs->fs_fragshift) {
1405978408cSSascha Wildner 	case 3:
1415978408cSSascha Wildner 		cp[h] = 0;
1425978408cSSascha Wildner 		return;
1435978408cSSascha Wildner 	case 2:
1445978408cSSascha Wildner 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1455978408cSSascha Wildner 		return;
1465978408cSSascha Wildner 	case 1:
1475978408cSSascha Wildner 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1485978408cSSascha Wildner 		return;
1495978408cSSascha Wildner 	case 0:
1505978408cSSascha Wildner 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
1515978408cSSascha Wildner 		return;
1525978408cSSascha Wildner 	default:
1535978408cSSascha Wildner 		panic("ffs_clrblock: unknown fs_fragshift %d",
1545978408cSSascha Wildner 		    (int)fs->fs_fragshift);
1555978408cSSascha Wildner 	}
1565978408cSSascha Wildner }
1575978408cSSascha Wildner 
1585978408cSSascha Wildner /*
1595978408cSSascha Wildner  * put a block into the map
1605978408cSSascha Wildner  */
1615978408cSSascha Wildner void
ffs_setblock(struct fs * fs,u_char * cp,int32_t h)1625978408cSSascha Wildner ffs_setblock(struct fs *fs, u_char *cp, int32_t h)
1635978408cSSascha Wildner {
1645978408cSSascha Wildner 
1655978408cSSascha Wildner 	switch ((int)fs->fs_fragshift) {
1665978408cSSascha Wildner 	case 3:
1675978408cSSascha Wildner 		cp[h] = 0xff;
1685978408cSSascha Wildner 		return;
1695978408cSSascha Wildner 	case 2:
1705978408cSSascha Wildner 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
1715978408cSSascha Wildner 		return;
1725978408cSSascha Wildner 	case 1:
1735978408cSSascha Wildner 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
1745978408cSSascha Wildner 		return;
1755978408cSSascha Wildner 	case 0:
1765978408cSSascha Wildner 		cp[h >> 3] |= (0x01 << (h & 0x7));
1775978408cSSascha Wildner 		return;
1785978408cSSascha Wildner 	default:
1795978408cSSascha Wildner 		panic("ffs_setblock: unknown fs_fragshift %d",
1805978408cSSascha Wildner 		    (int)fs->fs_fragshift);
1815978408cSSascha Wildner 	}
1825978408cSSascha Wildner }
183