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