xref: /csrg-svn/sys/ufs/lfs/lfs_balloc.c (revision 51155)
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