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