xref: /original-bsd/sys/ufs/ffs/ffs_subr.c (revision 5363fd5e)
1c8bc2536Smckusick /*
22b768bd7Sbostic  * Copyright (c) 1982, 1986, 1989, 1993
32b768bd7Sbostic  *	The Regents of the University of California.  All rights reserved.
4c8bc2536Smckusick  *
58eb14236Sbostic  * %sccs.include.redist.c%
6065083aeSmckusick  *
7*5363fd5eSmckusick  *	@(#)ffs_subr.c	8.5 (Berkeley) 03/21/95
8c8bc2536Smckusick  */
92fd425aeSroot 
102fd425aeSroot #include <sys/param.h>
112c9a935dSmckusick #ifndef KERNEL
12*5363fd5eSmckusick #include <ufs/ufs/dinode.h>
13507878abSbostic #include <ufs/ffs/fs.h>
142c9a935dSmckusick #else
15507878abSbostic 
16c470cd31Smckusick #include <sys/systm.h>
1748d0f8e9Smckusick #include <sys/vnode.h>
18e8e9bf15Smckusick #include <sys/buf.h>
19e8e9bf15Smckusick #include <ufs/ufs/quota.h>
20e8e9bf15Smckusick #include <ufs/ufs/inode.h>
212c9a935dSmckusick #include <ufs/ffs/fs.h>
222c9a935dSmckusick #include <ufs/ffs/ffs_extern.h>
23898d8e57Sbostic 
24507878abSbostic /*
25507878abSbostic  * Return buffer with the contents of block "offset" from the beginning of
26507878abSbostic  * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
27507878abSbostic  * remaining space in the directory.
28507878abSbostic  */
29507878abSbostic int
ffs_blkatoff(ap)3042026a80Sheideman ffs_blkatoff(ap)
3177f5479aSmckusick 	struct vop_blkatoff_args /* {
3277f5479aSmckusick 		struct vnode *a_vp;
3377f5479aSmckusick 		off_t a_offset;
3477f5479aSmckusick 		char **a_res;
3577f5479aSmckusick 		struct buf **a_bpp;
3677f5479aSmckusick 	} */ *ap;
37507878abSbostic {
38297a81e4Smckusick 	struct inode *ip;
39507878abSbostic 	register struct fs *fs;
40507878abSbostic 	struct buf *bp;
412c9a935dSmckusick 	ufs_daddr_t lbn;
42507878abSbostic 	int bsize, error;
43507878abSbostic 
44ffd50346Sheideman 	ip = VTOI(ap->a_vp);
45507878abSbostic 	fs = ip->i_fs;
46ffd50346Sheideman 	lbn = lblkno(fs, ap->a_offset);
47507878abSbostic 	bsize = blksize(fs, ip, lbn);
48507878abSbostic 
49ffd50346Sheideman 	*ap->a_bpp = NULL;
50ffd50346Sheideman 	if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
51507878abSbostic 		brelse(bp);
52507878abSbostic 		return (error);
53507878abSbostic 	}
54ffd50346Sheideman 	if (ap->a_res)
558821b0ebSbostic 		*ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset);
56ffd50346Sheideman 	*ap->a_bpp = bp;
57507878abSbostic 	return (0);
58507878abSbostic }
59898d8e57Sbostic #endif
602fd425aeSroot 
612fd425aeSroot /*
622fd425aeSroot  * Update the frsum fields to reflect addition or deletion
632fd425aeSroot  * of some frags.
642fd425aeSroot  */
65507878abSbostic void
ffs_fragacct(fs,fragmap,fraglist,cnt)66507878abSbostic ffs_fragacct(fs, fragmap, fraglist, cnt)
672fd425aeSroot 	struct fs *fs;
682fd425aeSroot 	int fragmap;
69c7e57180Smckusick 	int32_t fraglist[];
702fd425aeSroot 	int cnt;
712fd425aeSroot {
722fd425aeSroot 	int inblk;
732fd425aeSroot 	register int field, subfield;
742fd425aeSroot 	register int siz, pos;
752fd425aeSroot 
762fd425aeSroot 	inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
772fd425aeSroot 	fragmap <<= 1;
782fd425aeSroot 	for (siz = 1; siz < fs->fs_frag; siz++) {
792fd425aeSroot 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
802fd425aeSroot 			continue;
812fd425aeSroot 		field = around[siz];
822fd425aeSroot 		subfield = inside[siz];
832fd425aeSroot 		for (pos = siz; pos <= fs->fs_frag; pos++) {
842fd425aeSroot 			if ((fragmap & field) == subfield) {
852fd425aeSroot 				fraglist[siz] += cnt;
862fd425aeSroot 				pos += siz;
872fd425aeSroot 				field <<= siz;
882fd425aeSroot 				subfield <<= siz;
892fd425aeSroot 			}
902fd425aeSroot 			field <<= 1;
912fd425aeSroot 			subfield <<= 1;
922fd425aeSroot 		}
932fd425aeSroot 	}
942fd425aeSroot }
952fd425aeSroot 
96898d8e57Sbostic #if defined(KERNEL) && defined(DIAGNOSTIC)
97507878abSbostic void
ffs_checkoverlap(bp,ip)98507878abSbostic ffs_checkoverlap(bp, ip)
99507878abSbostic 	struct buf *bp;
100507878abSbostic 	struct inode *ip;
101507878abSbostic {
102507878abSbostic 	register struct buf *ebp, *ep;
1032c9a935dSmckusick 	register ufs_daddr_t start, last;
104507878abSbostic 	struct vnode *vp;
105507878abSbostic 
106507878abSbostic 	ebp = &buf[nbuf];
107507878abSbostic 	start = bp->b_blkno;
108507878abSbostic 	last = start + btodb(bp->b_bcount) - 1;
109507878abSbostic 	for (ep = buf; ep < ebp; ep++) {
110507878abSbostic 		if (ep == bp || (ep->b_flags & B_INVAL) ||
111507878abSbostic 		    ep->b_vp == NULLVP)
112507878abSbostic 			continue;
1132c9a935dSmckusick 		if (VOP_BMAP(ep->b_vp, (ufs_daddr_t)0, &vp, (ufs_daddr_t)0,
1142c9a935dSmckusick 		    NULL))
115507878abSbostic 			continue;
116507878abSbostic 		if (vp != ip->i_devvp)
117507878abSbostic 			continue;
118507878abSbostic 		/* look for overlap */
119507878abSbostic 		if (ep->b_bcount == 0 || ep->b_blkno > last ||
120507878abSbostic 		    ep->b_blkno + btodb(ep->b_bcount) <= start)
121507878abSbostic 			continue;
122507878abSbostic 		vprint("Disk overlap", vp);
123507878abSbostic 		(void)printf("\tstart %d, end %d overlap start %d, end %d\n",
124507878abSbostic 			start, last, ep->b_blkno,
125507878abSbostic 			ep->b_blkno + btodb(ep->b_bcount) - 1);
126507878abSbostic 		panic("Disk buffer overlap");
127507878abSbostic 	}
128507878abSbostic }
129507878abSbostic #endif /* DIAGNOSTIC */
130507878abSbostic 
1312fd425aeSroot /*
1322fd425aeSroot  * block operations
1332fd425aeSroot  *
1342fd425aeSroot  * check if a block is available
1352fd425aeSroot  */
136507878abSbostic int
ffs_isblock(fs,cp,h)137507878abSbostic ffs_isblock(fs, cp, h)
1382fd425aeSroot 	struct fs *fs;
1392fd425aeSroot 	unsigned char *cp;
1402c9a935dSmckusick 	ufs_daddr_t h;
1412fd425aeSroot {
1422fd425aeSroot 	unsigned char mask;
1432fd425aeSroot 
144c6f9bf5fSkarels 	switch ((int)fs->fs_frag) {
1452fd425aeSroot 	case 8:
1462fd425aeSroot 		return (cp[h] == 0xff);
1472fd425aeSroot 	case 4:
1482fd425aeSroot 		mask = 0x0f << ((h & 0x1) << 2);
1492fd425aeSroot 		return ((cp[h >> 1] & mask) == mask);
1502fd425aeSroot 	case 2:
1512fd425aeSroot 		mask = 0x03 << ((h & 0x3) << 1);
1522fd425aeSroot 		return ((cp[h >> 2] & mask) == mask);
1532fd425aeSroot 	case 1:
1542fd425aeSroot 		mask = 0x01 << (h & 0x7);
1552fd425aeSroot 		return ((cp[h >> 3] & mask) == mask);
1562fd425aeSroot 	default:
157507878abSbostic 		panic("ffs_isblock");
1582fd425aeSroot 	}
1592fd425aeSroot }
1602fd425aeSroot 
1612fd425aeSroot /*
1622fd425aeSroot  * take a block out of the map
1632fd425aeSroot  */
164507878abSbostic void
ffs_clrblock(fs,cp,h)165507878abSbostic ffs_clrblock(fs, cp, h)
1662fd425aeSroot 	struct fs *fs;
16791257f00Sroot 	u_char *cp;
1682c9a935dSmckusick 	ufs_daddr_t h;
1692fd425aeSroot {
1702fd425aeSroot 
171c6f9bf5fSkarels 	switch ((int)fs->fs_frag) {
1722fd425aeSroot 	case 8:
1732fd425aeSroot 		cp[h] = 0;
1742fd425aeSroot 		return;
1752fd425aeSroot 	case 4:
1762fd425aeSroot 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
1772fd425aeSroot 		return;
1782fd425aeSroot 	case 2:
1792fd425aeSroot 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
1802fd425aeSroot 		return;
1812fd425aeSroot 	case 1:
1822fd425aeSroot 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
1832fd425aeSroot 		return;
1842fd425aeSroot 	default:
185507878abSbostic 		panic("ffs_clrblock");
1862fd425aeSroot 	}
1872fd425aeSroot }
1882fd425aeSroot 
1892fd425aeSroot /*
1902fd425aeSroot  * put a block into the map
1912fd425aeSroot  */
192507878abSbostic void
ffs_setblock(fs,cp,h)193507878abSbostic ffs_setblock(fs, cp, h)
1942fd425aeSroot 	struct fs *fs;
1952fd425aeSroot 	unsigned char *cp;
1962c9a935dSmckusick 	ufs_daddr_t h;
1972fd425aeSroot {
1982fd425aeSroot 
199c6f9bf5fSkarels 	switch ((int)fs->fs_frag) {
2002fd425aeSroot 
2012fd425aeSroot 	case 8:
2022fd425aeSroot 		cp[h] = 0xff;
2032fd425aeSroot 		return;
2042fd425aeSroot 	case 4:
2052fd425aeSroot 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
2062fd425aeSroot 		return;
2072fd425aeSroot 	case 2:
2082fd425aeSroot 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
2092fd425aeSroot 		return;
2102fd425aeSroot 	case 1:
2112fd425aeSroot 		cp[h >> 3] |= (0x01 << (h & 0x7));
2122fd425aeSroot 		return;
2132fd425aeSroot 	default:
214507878abSbostic 		panic("ffs_setblock");
2152fd425aeSroot 	}
2162fd425aeSroot }
217