add SCCS header
[unix-history] / usr / src / sys / ufs / lfs / lfs_balloc.c
CommitLineData
da7c5cc6 1/*
9fc995cf 2 * Copyright (c) 1989, 1991 Regents of the University of California.
7188ac27 3 * All rights reserved.
da7c5cc6 4 *
b702c21d 5 * %sccs.include.redist.c%
7188ac27 6 *
8ad16d99 7 * @(#)lfs_balloc.c 7.20 (Berkeley) %G%
da7c5cc6 8 */
52212483 9
f6437c6d
KB
10#include <sys/param.h>
11#include <sys/buf.h>
12#include <sys/proc.h>
13#include <sys/vnode.h>
14#include <sys/mount.h>
15#include <sys/resourcevar.h>
16#include <sys/specdev.h>
17#include <sys/trace.h>
c6f5111d 18
9fc995cf
KB
19#include <ufs/ufs/quota.h>
20#include <ufs/ufs/inode.h>
21#include <ufs/ufs/ufsmount.h>
f6437c6d 22
9fc995cf
KB
23#include <ufs/lfs/lfs.h>
24#include <ufs/lfs/lfs_extern.h>
52212483
BJ
25
26/*
f6437c6d
KB
27 * Bmap converts a the logical block number of a file to its physical block
28 * number on the disk. The conversion is done by using the logical block
29 * number to index into the array of block pointers described by the dinode.
52212483 30 */
e3b6a940 31int
8ad16d99
KM
32lfs_bmap(vp, bn, vpp, bnp)
33 struct vnode *vp;
7188ac27 34 register daddr_t bn;
8ad16d99
KM
35 struct vnode **vpp;
36 daddr_t *bnp;
52212483 37{
8ad16d99 38 register struct inode *ip;
9fc995cf 39 register struct lfs *fs;
7188ac27 40 register daddr_t nb;
8ad16d99 41 struct vnode *devvp;
7188ac27 42 struct buf *bp;
d5075120
KB
43 daddr_t *bap, daddr;
44 daddr_t lbn_ind;
e3b6a940 45 int j, off, sh;
7188ac27
KM
46 int error;
47
8ad16d99
KM
48 /*
49 * Check for underlying vnode requests and ensure that logical
50 * to physical mapping is requested.
51 */
52 ip = VTOI(vp);
53 if (vpp != NULL)
54 *vpp = ip->i_devvp;
55 if (bnp == NULL)
56 return (0);
0b4d6502 57printf("lfs_bmap: block number %d, inode %d\n", bn, ip->i_number);
f6437c6d 58 fs = ip->i_lfs;
7188ac27 59
d5075120 60 /*
f6437c6d
KB
61 * We access all blocks in the cache, even indirect blocks by means
62 * of a logical address. Indirect blocks (single, double, triple) all
63 * have negative block numbers. The first NDADDR blocks are direct
64 * blocks, the first NIADDR negative blocks are the indirect block
65 * pointers. The single, double and triple indirect blocks in the
66 * inode * are addressed: -1, -2 and -3 respectively.
67 *
68 * XXX
69 * We don't handle triple indirect at all.
70 *
71 * XXX
72 * This panic shouldn't be here???
d5075120 73 */
f6437c6d
KB
74 if (bn < 0)
75 panic("lfs_bmap: negative indirect block number %d", bn);
d5075120 76
f6437c6d 77 /* The first NDADDR blocks are direct blocks. */
7188ac27
KM
78 if (bn < NDADDR) {
79 nb = ip->i_db[bn];
80 if (nb == 0) {
e3b6a940 81 *bnp = UNASSIGNED;
7188ac27
KM
82 return (0);
83 }
0b4d6502 84 *bnp = nb;
7188ac27
KM
85 return (0);
86 }
f6437c6d
KB
87
88 /* Determine the number of levels of indirection. */
7188ac27
KM
89 sh = 1;
90 bn -= NDADDR;
d5075120 91 lbn_ind = 0;
7188ac27 92 for (j = NIADDR; j > 0; j--) {
d5075120 93 lbn_ind--;
7188ac27
KM
94 sh *= NINDIR(fs);
95 if (bn < sh)
96 break;
97 bn -= sh;
98 }
99 if (j == 0)
100 return (EFBIG);
d5075120 101
f6437c6d 102 /* Fetch through the indirect blocks. */
d5075120
KB
103 vp = ITOV(ip);
104 devvp = VFSTOUFS(vp->v_mount)->um_devvp;
105 for (off = NIADDR - j, bap = ip->i_ib; j <= NIADDR; j++) {
106 if((daddr = bap[off]) == 0) {
e3b6a940 107 daddr = UNASSIGNED;
d5075120
KB
108 break;
109 }
110 if (bp)
7188ac27 111 brelse(bp);
d5075120
KB
112 bp = getblk(vp, lbn_ind, fs->lfs_bsize);
113 if (bp->b_flags & (B_DONE | B_DELWRI)) {
114 trace(TR_BREADHIT, pack(vp, size), lbn_ind);
115 } else {
116 trace(TR_BREADMISS, pack(vp, size), lbn_ind);
117 bp->b_blkno = daddr;
118 bp->b_flags |= B_READ;
119 bp->b_dev = devvp->v_rdev;
275ca4f0 120 (devvp->v_op->vop_strategy)(bp);
d5075120
KB
121 curproc->p_stats->p_ru.ru_inblock++; /* XXX */
122 if (error = biowait(bp)) {
123 brelse(bp);
124 return (error);
125 }
7188ac27
KM
126 }
127 bap = bp->b_un.b_daddr;
128 sh /= NINDIR(fs);
d5075120
KB
129 off = (bn / sh) % NINDIR(fs);
130 lbn_ind = -(NIADDR + 1 + off);
7188ac27 131 }
d5075120
KB
132 if (bp)
133 brelse(bp);
134
135 *bnp = daddr;
7188ac27 136 return (0);
52212483 137}