xref: /csrg-svn/sys/stand.att/bmap.c (revision 49145)
1*49145Sbostic /*-
2*49145Sbostic  * Copyright (c) 1982, 1988 The Regents of the University of California.
3*49145Sbostic  * All rights reserved.
4*49145Sbostic  *
5*49145Sbostic  * %sccs.include.proprietary.c%
6*49145Sbostic  *
7*49145Sbostic  *	@(#)bmap.c	7.1 (Berkeley) 05/05/91
8*49145Sbostic  */
9*49145Sbostic 
10*49145Sbostic #include <sys/param.h>
11*49145Sbostic #include "saio.h"
12*49145Sbostic 
13*49145Sbostic #define	NBUFS	4
14*49145Sbostic static char	b[NBUFS][MAXBSIZE];
15*49145Sbostic static daddr_t	blknos[NBUFS];
16*49145Sbostic 
17*49145Sbostic daddr_t
18*49145Sbostic bmap(io, bn)
19*49145Sbostic 	register struct iob *io;
20*49145Sbostic 	daddr_t bn;
21*49145Sbostic {
22*49145Sbostic 	register struct dinode *ip;
23*49145Sbostic 	int i, j, sh;
24*49145Sbostic 	daddr_t nb, *bap;
25*49145Sbostic 
26*49145Sbostic 	ip = &io->i_ino;
27*49145Sbostic 	if (bn < 0) {
28*49145Sbostic 		printf("bn negative\n");
29*49145Sbostic 		return ((daddr_t)0);
30*49145Sbostic 	}
31*49145Sbostic 
32*49145Sbostic 	/* The first NDADDR blocks are direct blocks. */
33*49145Sbostic 	if(bn < NDADDR) {
34*49145Sbostic 		nb = ip->di_db[bn];
35*49145Sbostic 		return (nb);
36*49145Sbostic 	}
37*49145Sbostic 
38*49145Sbostic 	/* Determine the number of levels of indirection. */
39*49145Sbostic 	sh = 1;
40*49145Sbostic 	bn -= NDADDR;
41*49145Sbostic 	for (j = NIADDR; j > 0; j--) {
42*49145Sbostic 		sh *= NINDIR(&io->i_fs);
43*49145Sbostic 		if (bn < sh)
44*49145Sbostic 			break;
45*49145Sbostic 		bn -= sh;
46*49145Sbostic 	}
47*49145Sbostic 	if (j == 0) {
48*49145Sbostic 		printf("bn ovf %D\n", bn);
49*49145Sbostic 		return ((daddr_t)0);
50*49145Sbostic 	}
51*49145Sbostic 
52*49145Sbostic 	/* Get the first indirect block address. */
53*49145Sbostic 	nb = ip->di_ib[NIADDR - j];
54*49145Sbostic 	if (nb == 0) {
55*49145Sbostic 		printf("bn void %D\n",bn);
56*49145Sbostic 		return ((daddr_t)0);
57*49145Sbostic 	}
58*49145Sbostic 
59*49145Sbostic 	/* Get the indirect blocks. */
60*49145Sbostic 	for (; j <= NIADDR; j++) {
61*49145Sbostic 		if (blknos[j] != nb) {
62*49145Sbostic 			io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
63*49145Sbostic 			io->i_ma = b[j];
64*49145Sbostic 			io->i_cc = io->i_fs.fs_bsize;
65*49145Sbostic 			if (devread(io) != io->i_fs.fs_bsize) {
66*49145Sbostic 				if (io->i_error)
67*49145Sbostic 					errno = io->i_error;
68*49145Sbostic 				printf("bn %D: read error\n", io->i_bn);
69*49145Sbostic 				return ((daddr_t)0);
70*49145Sbostic 			}
71*49145Sbostic 			blknos[j] = nb;
72*49145Sbostic 		}
73*49145Sbostic 		bap = (daddr_t *)b[j];
74*49145Sbostic 		sh /= NINDIR(&io->i_fs);
75*49145Sbostic 		i = (bn / sh) % NINDIR(&io->i_fs);
76*49145Sbostic 		nb = bap[i];
77*49145Sbostic 		if(nb == 0) {
78*49145Sbostic 			printf("bn void %D\n",bn);
79*49145Sbostic 			return ((daddr_t)0);
80*49145Sbostic 		}
81*49145Sbostic 	}
82*49145Sbostic 	return (nb);
83*49145Sbostic }
84