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