149145Sbostic /*- 249145Sbostic * Copyright (c) 1982, 1988 The Regents of the University of California. 349145Sbostic * All rights reserved. 449145Sbostic * 549145Sbostic * %sccs.include.proprietary.c% 649145Sbostic * 7*60328Smckusick * @(#)bmap.c 7.4 (Berkeley) 05/24/93 849145Sbostic */ 949145Sbostic 1049145Sbostic #include <sys/param.h> 11*60328Smckusick #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 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