1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_balloc.c 7.14 (Berkeley) 09/20/91 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "buf.h" 13 #include "proc.h" 14 #include "file.h" 15 #include "vnode.h" 16 17 #include "../ufs/quota.h" 18 #include "../ufs/inode.h" 19 #include "lfs.h" 20 #include "lfs_extern.h" 21 22 /* 23 * Bmap converts a the logical block number of a file 24 * to its physical block number on the disk. The conversion 25 * is done by using the logical block number to index into 26 * the array of block pointers described by the dinode. 27 */ 28 lfs_bmap(ip, bn, bnp) 29 register struct inode *ip; 30 register daddr_t bn; 31 daddr_t *bnp; 32 { 33 register LFS *fs; /* LFS */ 34 register daddr_t nb; 35 struct buf *bp; 36 daddr_t *bap; 37 int i, j, sh; 38 int error; 39 40 printf("lfs_bmap: block number %d, inode %d\n", bn, ip->i_number); 41 if (bn < 0) 42 return (EFBIG); 43 fs = ip->i_lfs; /* LFS */ 44 45 /* 46 * The first NDADDR blocks are direct blocks 47 */ 48 if (bn < NDADDR) { 49 nb = ip->i_db[bn]; 50 if (nb == 0) { 51 *bnp = (daddr_t)-1; 52 return (0); 53 } 54 *bnp = nb; 55 return (0); 56 } 57 /* 58 * Determine the number of levels of indirection. 59 */ 60 sh = 1; 61 bn -= NDADDR; 62 for (j = NIADDR; j > 0; j--) { 63 sh *= NINDIR(fs); 64 if (bn < sh) 65 break; 66 bn -= sh; 67 } 68 if (j == 0) 69 return (EFBIG); 70 /* 71 * Fetch through the indirect blocks. 72 */ 73 nb = ip->i_ib[NIADDR - j]; 74 if (nb == 0) { 75 *bnp = (daddr_t)-1; 76 return (0); 77 } 78 for (; j <= NIADDR; j++) { 79 if (error = bread(ip->i_devvp, nb, (int)fs->lfs_bsize, 80 NOCRED, &bp)) { /* LFS */ 81 brelse(bp); 82 return (error); 83 } 84 bap = bp->b_un.b_daddr; 85 sh /= NINDIR(fs); 86 i = (bn / sh) % NINDIR(fs); 87 nb = bap[i]; 88 if (nb == 0) { 89 *bnp = (daddr_t)-1; 90 brelse(bp); 91 return (0); 92 } 93 brelse(bp); 94 } 95 *bnp = nb; 96 return (0); 97 } 98