123396Smckusick /* 237736Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337736Smckusick * All rights reserved. 423396Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51155Sbostic * @(#)lfs_balloc.c 7.14 (Berkeley) 09/20/91 823396Smckusick */ 97443Sroot 1017099Sbloom #include "param.h" 1117099Sbloom #include "systm.h" 1217099Sbloom #include "buf.h" 1317099Sbloom #include "proc.h" 1437736Smckusick #include "file.h" 1537736Smckusick #include "vnode.h" 167443Sroot 17*51155Sbostic #include "../ufs/quota.h" 18*51155Sbostic #include "../ufs/inode.h" 19*51155Sbostic #include "lfs.h" 20*51155Sbostic #include "lfs_extern.h" 2147571Skarels 227443Sroot /* 2349450Smckusick * Bmap converts a the logical block number of a file 2449450Smckusick * to its physical block number on the disk. The conversion 2549450Smckusick * is done by using the logical block number to index into 2649450Smckusick * the array of block pointers described by the dinode. 277443Sroot */ 28*51155Sbostic lfs_bmap(ip, bn, bnp) 297443Sroot register struct inode *ip; 3037736Smckusick register daddr_t bn; 3137736Smckusick daddr_t *bnp; 327443Sroot { 33*51155Sbostic register LFS *fs; /* LFS */ 3437736Smckusick register daddr_t nb; 3537736Smckusick struct buf *bp; 3637736Smckusick daddr_t *bap; 3737736Smckusick int i, j, sh; 3837736Smckusick int error; 3937736Smckusick 40*51155Sbostic printf("lfs_bmap: block number %d, inode %d\n", bn, ip->i_number); 4137736Smckusick if (bn < 0) 4237736Smckusick return (EFBIG); 43*51155Sbostic fs = ip->i_lfs; /* LFS */ 4437736Smckusick 4537736Smckusick /* 4637736Smckusick * The first NDADDR blocks are direct blocks 4737736Smckusick */ 4837736Smckusick if (bn < NDADDR) { 4937736Smckusick nb = ip->i_db[bn]; 5037736Smckusick if (nb == 0) { 5137736Smckusick *bnp = (daddr_t)-1; 5237736Smckusick return (0); 5337736Smckusick } 54*51155Sbostic *bnp = nb; 5537736Smckusick return (0); 5637736Smckusick } 5737736Smckusick /* 5839679Smckusick * Determine the number of levels of indirection. 5937736Smckusick */ 6037736Smckusick sh = 1; 6137736Smckusick bn -= NDADDR; 6237736Smckusick for (j = NIADDR; j > 0; j--) { 6337736Smckusick sh *= NINDIR(fs); 6437736Smckusick if (bn < sh) 6537736Smckusick break; 6637736Smckusick bn -= sh; 6737736Smckusick } 6837736Smckusick if (j == 0) 6937736Smckusick return (EFBIG); 7037736Smckusick /* 7139679Smckusick * Fetch through the indirect blocks. 7237736Smckusick */ 7337736Smckusick nb = ip->i_ib[NIADDR - j]; 7437736Smckusick if (nb == 0) { 7537736Smckusick *bnp = (daddr_t)-1; 7637736Smckusick return (0); 7737736Smckusick } 7837736Smckusick for (; j <= NIADDR; j++) { 79*51155Sbostic if (error = bread(ip->i_devvp, nb, (int)fs->lfs_bsize, 80*51155Sbostic NOCRED, &bp)) { /* LFS */ 8137736Smckusick brelse(bp); 8237736Smckusick return (error); 8337736Smckusick } 8437736Smckusick bap = bp->b_un.b_daddr; 8537736Smckusick sh /= NINDIR(fs); 8637736Smckusick i = (bn / sh) % NINDIR(fs); 8737736Smckusick nb = bap[i]; 8837736Smckusick if (nb == 0) { 8937736Smckusick *bnp = (daddr_t)-1; 9037736Smckusick brelse(bp); 9137736Smckusick return (0); 9237736Smckusick } 9339679Smckusick brelse(bp); 9437736Smckusick } 95*51155Sbostic *bnp = nb; 9637736Smckusick return (0); 9737736Smckusick } 98