123396Smckusick /* 251494Sbostic * Copyright (c) 1989, 1991 Regents of the University of California. 337736Smckusick * All rights reserved. 423396Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51846Sbostic * @(#)lfs_balloc.c 7.21 (Berkeley) 12/06/91 823396Smckusick */ 97443Sroot 1051486Sbostic #include <sys/param.h> 1151486Sbostic #include <sys/buf.h> 1251486Sbostic #include <sys/proc.h> 1351486Sbostic #include <sys/vnode.h> 1451486Sbostic #include <sys/mount.h> 1551486Sbostic #include <sys/resourcevar.h> 1651486Sbostic #include <sys/specdev.h> 1751486Sbostic #include <sys/trace.h> 187443Sroot 1951494Sbostic #include <ufs/ufs/quota.h> 2051494Sbostic #include <ufs/ufs/inode.h> 2151494Sbostic #include <ufs/ufs/ufsmount.h> 2247571Skarels 2351494Sbostic #include <ufs/lfs/lfs.h> 2451494Sbostic #include <ufs/lfs/lfs_extern.h> 2551486Sbostic 267443Sroot /* 2751486Sbostic * Bmap converts a the logical block number of a file to its physical block 2851486Sbostic * number on the disk. The conversion is done by using the logical block 2951486Sbostic * number to index into the array of block pointers described by the dinode. 30*51846Sbostic * 31*51846Sbostic * LFS has a different version of bmap from FFS because of a naming conflict. 32*51846Sbostic * In FFS, meta blocks are given real disk addresses at allocation time, and 33*51846Sbostic * are linked into the device vnode, using a logical block number which is 34*51846Sbostic * the same as the physical block number. This can't be done by LFS because 35*51846Sbostic * blocks aren't given disk addresses until they're written, so there's no 36*51846Sbostic * way to distinguish the meta-data blocks for one file from any other file. 37*51846Sbostic * This means that meta-data blocks have to be on the vnode for the file so 38*51846Sbostic * they can be found, and have to have "names" different from the standard 39*51846Sbostic * data blocks. To do this, we divide the name space into positive and 40*51846Sbostic * negative block numbers, and give the meta-data blocks negative logical 41*51846Sbostic * numbers. 42*51846Sbostic * 43*51846Sbostic * The mapping for meta-data blocks is as follows (assuming a 4K block size): 44*51846Sbostic * 45*51846Sbostic * -1 -- single indirect 46*51846Sbostic * -2 -- double indirect: 47*51846Sbostic * single indirect blocks -4, -1027 48*51846Sbostic * -3 -- triple indirect: 49*51846Sbostic * double indirect blocks -1028, -2051 50*51846Sbostic * single indirect blocks -2052, -(1M + 2052 - 1) 517443Sroot */ 5251348Sroot int 5351561Smckusick lfs_bmap(vp, bn, vpp, bnp) 5451561Smckusick struct vnode *vp; 5537736Smckusick register daddr_t bn; 5651561Smckusick struct vnode **vpp; 5751561Smckusick daddr_t *bnp; 587443Sroot { 5951561Smckusick register struct inode *ip; 6051494Sbostic register struct lfs *fs; 6137736Smckusick register daddr_t nb; 62*51846Sbostic struct buf *bp; 6351561Smckusick struct vnode *devvp; 64*51846Sbostic daddr_t *bap, daddr, lbn_ind, doing_a_triple; 65*51846Sbostic int error, j, off, sh, sh_ind; 6637736Smckusick 6751561Smckusick /* 6851561Smckusick * Check for underlying vnode requests and ensure that logical 6951561Smckusick * to physical mapping is requested. 7051561Smckusick */ 7151561Smckusick ip = VTOI(vp); 7251561Smckusick if (vpp != NULL) 7351561Smckusick *vpp = ip->i_devvp; 7451561Smckusick if (bnp == NULL) 7551561Smckusick return (0); 76*51846Sbostic 77*51846Sbostic #ifdef VERBOSE 7851155Sbostic printf("lfs_bmap: block number %d, inode %d\n", bn, ip->i_number); 79*51846Sbostic #endif 8051486Sbostic /* The first NDADDR blocks are direct blocks. */ 8137736Smckusick if (bn < NDADDR) { 8237736Smckusick nb = ip->i_db[bn]; 83*51846Sbostic if (nb == LFS_UNUSED_DADDR) 8451348Sroot *bnp = UNASSIGNED; 85*51846Sbostic else 86*51846Sbostic *bnp = nb; 8737736Smckusick return (0); 8837736Smckusick } 8951486Sbostic 90*51846Sbostic /* 91*51846Sbostic * The first NIADDR negative blocks are the indirect block pointers. 92*51846Sbostic * Determine the number of levels of indirection. After this loop 93*51846Sbostic * is done, sh indicates the number of data blocks possible at the 94*51846Sbostic * given level of indirection, lbn_ind is the logical block number 95*51846Sbostic * of the next indirect block to retrieve, and NIADDR - j is the 96*51846Sbostic * number of levels of indirection needed to locate the requested 97*51846Sbostic * block. 98*51846Sbostic */ 99*51846Sbostic fs = ip->i_lfs; 10037736Smckusick sh = 1; 10137736Smckusick bn -= NDADDR; 10251183Sbostic lbn_ind = 0; 10337736Smckusick for (j = NIADDR; j > 0; j--) { 104*51846Sbostic --lbn_ind; 10537736Smckusick sh *= NINDIR(fs); 10637736Smckusick if (bn < sh) 10737736Smckusick break; 10837736Smckusick bn -= sh; 10937736Smckusick } 11037736Smckusick if (j == 0) 11137736Smckusick return (EFBIG); 11251183Sbostic 113*51846Sbostic /* 114*51846Sbostic * Fetch through the indirect blocks. At each iteration, off is the 115*51846Sbostic * offset into the bap array which is an array of disk addresses at 116*51846Sbostic * the current level of indirection. 117*51846Sbostic */ 118*51846Sbostic bap = ip->i_ib; 119*51846Sbostic bp = NULL; 12051183Sbostic devvp = VFSTOUFS(vp->v_mount)->um_devvp; 121*51846Sbostic off = NIADDR - j; 122*51846Sbostic doing_a_triple = 0; 123*51846Sbostic for (; j <= NIADDR; j++) { 124*51846Sbostic /* 125*51846Sbostic * In LFS, it's possible to have a block appended to a file 126*51846Sbostic * for which the meta-blocks have not yet been allocated. 127*51846Sbostic * This is a win if the file never gets written or if the 128*51846Sbostic * file's growing. 129*51846Sbostic */ 130*51846Sbostic if ((daddr = bap[off]) == 0) { 13151348Sroot daddr = UNASSIGNED; 13251183Sbostic break; 13351183Sbostic } 134*51846Sbostic /* 135*51846Sbostic * Read in the appropriate indirect block. LFS can't do a 136*51846Sbostic * bread because bread knows that FFS will hand it the device 137*51846Sbostic * vnode, not the file vnode, so the b_dev and b_blkno would 138*51846Sbostic * be wrong. 139*51846Sbostic * 140*51846Sbostic * XXX 141*51846Sbostic * This REALLY needs to be fixed, at the very least it needs 142*51846Sbostic * to be rethought when the buffer cache goes away. 143*51846Sbostic */ 14451183Sbostic if (bp) 14537736Smckusick brelse(bp); 14651183Sbostic bp = getblk(vp, lbn_ind, fs->lfs_bsize); 14751183Sbostic if (bp->b_flags & (B_DONE | B_DELWRI)) { 14851183Sbostic trace(TR_BREADHIT, pack(vp, size), lbn_ind); 14951183Sbostic } else { 150*51846Sbostic bp->b_flags |= B_READ; 15151183Sbostic bp->b_blkno = daddr; 15251183Sbostic bp->b_dev = devvp->v_rdev; 15351215Sbostic (devvp->v_op->vop_strategy)(bp); 154*51846Sbostic trace(TR_BREADMISS, pack(vp, size), lbn_ind); 15551183Sbostic curproc->p_stats->p_ru.ru_inblock++; /* XXX */ 15651183Sbostic if (error = biowait(bp)) { 15751183Sbostic brelse(bp); 15851183Sbostic return (error); 15951183Sbostic } 16037736Smckusick } 16137736Smckusick bap = bp->b_un.b_daddr; 16237736Smckusick sh /= NINDIR(fs); 16351183Sbostic off = (bn / sh) % NINDIR(fs); 164*51846Sbostic 165*51846Sbostic /* 166*51846Sbostic * Ahem. Now the disgusting part. We have to figure out 167*51846Sbostic * the logical block number for the next meta-data block. 168*51846Sbostic * There are really three equations... Note the clever 169*51846Sbostic * use of the doing_a_triple variable to hold the last 170*51846Sbostic * offset into the block of pointers. 171*51846Sbostic */ 172*51846Sbostic switch(j) { 173*51846Sbostic case 1: 174*51846Sbostic /* The triple indirect block found in the inode. */ 175*51846Sbostic doing_a_triple = off; 176*51846Sbostic lbn_ind = -(NIADDR + 1 + off + NINDIR(fs)); 177*51846Sbostic break; 178*51846Sbostic case 2: 179*51846Sbostic /* 180*51846Sbostic * The double indirect block found after indirecting 181*51846Sbostic * through a triple indirect block. 182*51846Sbostic */ 183*51846Sbostic if (doing_a_triple) 184*51846Sbostic lbn_ind = -((doing_a_triple + 2) * NINDIR(fs) + 185*51846Sbostic NIADDR + 1); 186*51846Sbostic 187*51846Sbostic /* The double indirect block found in the inode. */ 188*51846Sbostic else 189*51846Sbostic lbn_ind = -(NIADDR + 1 + off); 190*51846Sbostic break; 191*51846Sbostic case 3: 192*51846Sbostic /* 193*51846Sbostic * A single indirect block; lbn_ind isn't used again, 194*51846Sbostic * so don't do anything. 195*51846Sbostic */ 196*51846Sbostic break; 197*51846Sbostic } 19851183Sbostic } 19951183Sbostic if (bp) 20039679Smckusick brelse(bp); 20151183Sbostic 20251183Sbostic *bnp = daddr; 20337736Smckusick return (0); 20437736Smckusick } 205