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