xref: /csrg-svn/sys/stand.att/bmap.c (revision 63370)
149145Sbostic /*-
2*63370Sbostic  * Copyright (c) 1982, 1988, 1993
3*63370Sbostic  *	The Regents of the University of California.  All rights reserved.
449145Sbostic  *
549145Sbostic  * %sccs.include.proprietary.c%
649145Sbostic  *
7*63370Sbostic  *	@(#)bmap.c	8.1 (Berkeley) 06/11/93
849145Sbostic  */
949145Sbostic 
1049145Sbostic #include <sys/param.h>
1160328Smckusick #include <stand.att/saio.h>
1249145Sbostic 
1349145Sbostic #define	NBUFS	4
1449145Sbostic static char	b[NBUFS][MAXBSIZE];
1549145Sbostic static daddr_t	blknos[NBUFS];
1649145Sbostic 
1749145Sbostic daddr_t
bmap(io,bn)1849145Sbostic bmap(io, bn)
1949145Sbostic 	register struct iob *io;
2049145Sbostic 	daddr_t bn;
2149145Sbostic {
2249145Sbostic 	register struct dinode *ip;
2349145Sbostic 	int i, j, sh;
2449145Sbostic 	daddr_t nb, *bap;
2549145Sbostic 
2649145Sbostic 	ip = &io->i_ino;
2749145Sbostic 	if (bn < 0) {
2849145Sbostic 		printf("bn negative\n");
2949145Sbostic 		return ((daddr_t)0);
3049145Sbostic 	}
3149145Sbostic 
3249145Sbostic 	/* The first NDADDR blocks are direct blocks. */
3349145Sbostic 	if(bn < NDADDR) {
3449145Sbostic 		nb = ip->di_db[bn];
3549145Sbostic 		return (nb);
3649145Sbostic 	}
3749145Sbostic 
3849145Sbostic 	/* Determine the number of levels of indirection. */
3949145Sbostic 	sh = 1;
4049145Sbostic 	bn -= NDADDR;
4149145Sbostic 	for (j = NIADDR; j > 0; j--) {
4249145Sbostic 		sh *= NINDIR(&io->i_fs);
4349145Sbostic 		if (bn < sh)
4449145Sbostic 			break;
4549145Sbostic 		bn -= sh;
4649145Sbostic 	}
4749145Sbostic 	if (j == 0) {
4849883Sbostic 		printf("bn ovf %ld\n", bn);
4949145Sbostic 		return ((daddr_t)0);
5049145Sbostic 	}
5149145Sbostic 
5249145Sbostic 	/* Get the first indirect block address. */
5349145Sbostic 	nb = ip->di_ib[NIADDR - j];
5449145Sbostic 	if (nb == 0) {
5549883Sbostic 		printf("bn void %ld\n",bn);
5649145Sbostic 		return ((daddr_t)0);
5749145Sbostic 	}
5849145Sbostic 
5949145Sbostic 	/* Get the indirect blocks. */
6049145Sbostic 	for (; j <= NIADDR; j++) {
6149145Sbostic 		if (blknos[j] != nb) {
6249145Sbostic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
6349145Sbostic 			io->i_ma = b[j];
6449145Sbostic 			io->i_cc = io->i_fs.fs_bsize;
6549145Sbostic 			if (devread(io) != io->i_fs.fs_bsize) {
6649145Sbostic 				if (io->i_error)
6749145Sbostic 					errno = io->i_error;
6849883Sbostic 				printf("bn %ld: read error\n", io->i_bn);
6949145Sbostic 				return ((daddr_t)0);
7049145Sbostic 			}
7149145Sbostic 			blknos[j] = nb;
7249145Sbostic 		}
7349145Sbostic 		bap = (daddr_t *)b[j];
7449145Sbostic 		sh /= NINDIR(&io->i_fs);
7549145Sbostic 		i = (bn / sh) % NINDIR(&io->i_fs);
7649145Sbostic 		nb = bap[i];
7749145Sbostic 		if(nb == 0) {
7849883Sbostic 			printf("bn void %ld\n",bn);
7949145Sbostic 			return ((daddr_t)0);
8049145Sbostic 		}
8149145Sbostic 	}
8249145Sbostic 	return (nb);
8349145Sbostic }
84