123396Smckusick /* 251494Sbostic * Copyright (c) 1989, 1991 Regents of the University of California. 337736Smckusick * All rights reserved. 423396Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51847Sbostic * @(#)lfs_balloc.c 7.22 (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. 3051846Sbostic * 3151846Sbostic * LFS has a different version of bmap from FFS because of a naming conflict. 3251846Sbostic * In FFS, meta blocks are given real disk addresses at allocation time, and 3351846Sbostic * are linked into the device vnode, using a logical block number which is 3451846Sbostic * the same as the physical block number. This can't be done by LFS because 3551846Sbostic * blocks aren't given disk addresses until they're written, so there's no 3651846Sbostic * way to distinguish the meta-data blocks for one file from any other file. 3751846Sbostic * This means that meta-data blocks have to be on the vnode for the file so 3851846Sbostic * they can be found, and have to have "names" different from the standard 3951846Sbostic * data blocks. To do this, we divide the name space into positive and 4051846Sbostic * negative block numbers, and give the meta-data blocks negative logical 41*51847Sbostic * numbers. Indirect blocks are addressed by the negative address of the 42*51847Sbostic * first data block to which they point. Double indirect blocks are addressed 43*51847Sbostic * by one less than the address of the first indirect block to which they 44*51847Sbostic * point. Triple indirect blocks are addressed by one less than the address 45*51847Sbostic * of the first double indirect block to which they point. 467443Sroot */ 4751348Sroot int 4851561Smckusick lfs_bmap(vp, bn, vpp, bnp) 4951561Smckusick struct vnode *vp; 5037736Smckusick register daddr_t bn; 5151561Smckusick struct vnode **vpp; 5251561Smckusick daddr_t *bnp; 537443Sroot { 5451561Smckusick register struct inode *ip; 5551494Sbostic register struct lfs *fs; 5637736Smckusick register daddr_t nb; 5751846Sbostic struct buf *bp; 5851561Smckusick struct vnode *devvp; 59*51847Sbostic daddr_t *bap, daddr, metalbn; 60*51847Sbostic long realbn; 61*51847Sbostic int error, j, off, sh; 6237736Smckusick 6351561Smckusick /* 6451561Smckusick * Check for underlying vnode requests and ensure that logical 6551561Smckusick * to physical mapping is requested. 6651561Smckusick */ 6751561Smckusick ip = VTOI(vp); 6851561Smckusick if (vpp != NULL) 6951561Smckusick *vpp = ip->i_devvp; 7051561Smckusick if (bnp == NULL) 7151561Smckusick return (0); 7251846Sbostic 7351846Sbostic #ifdef VERBOSE 7451155Sbostic printf("lfs_bmap: block number %d, inode %d\n", bn, ip->i_number); 7551846Sbostic #endif 76*51847Sbostic realbn = bn; 77*51847Sbostic if ((long)bn < 0) 78*51847Sbostic bn = -(long)bn; 79*51847Sbostic 8051486Sbostic /* The first NDADDR blocks are direct blocks. */ 8137736Smckusick if (bn < NDADDR) { 8237736Smckusick nb = ip->i_db[bn]; 83*51847Sbostic if (nb == 0) { 8451348Sroot *bnp = UNASSIGNED; 85*51847Sbostic return (0); 86*51847Sbostic } 87*51847Sbostic *bnp = nb; 8837736Smckusick return (0); 8937736Smckusick } 9051486Sbostic 9151846Sbostic /* 9251846Sbostic * Determine the number of levels of indirection. After this loop 9351846Sbostic * is done, sh indicates the number of data blocks possible at the 94*51847Sbostic * given level of indirection, and NIADDR - j is the number of levels 95*51847Sbostic * of indirection needed to locate the requested block. 9651846Sbostic */ 97*51847Sbostic bn -= NDADDR; 9851846Sbostic fs = ip->i_lfs; 9937736Smckusick sh = 1; 10037736Smckusick for (j = NIADDR; j > 0; j--) { 10137736Smckusick sh *= NINDIR(fs); 10237736Smckusick if (bn < sh) 10337736Smckusick break; 10437736Smckusick bn -= sh; 10537736Smckusick } 10637736Smckusick if (j == 0) 10737736Smckusick return (EFBIG); 10851183Sbostic 109*51847Sbostic /* Calculate the address of the first meta-block. */ 110*51847Sbostic if (realbn >= 0) 111*51847Sbostic metalbn = -(realbn - bn + NIADDR - j); 112*51847Sbostic else 113*51847Sbostic metalbn = -(-realbn - bn + NIADDR - j); 114*51847Sbostic 11551846Sbostic /* 11651846Sbostic * Fetch through the indirect blocks. At each iteration, off is the 11751846Sbostic * offset into the bap array which is an array of disk addresses at 11851846Sbostic * the current level of indirection. 11951846Sbostic */ 12051846Sbostic bp = NULL; 12151183Sbostic devvp = VFSTOUFS(vp->v_mount)->um_devvp; 122*51847Sbostic for (off = NIADDR - j, bap = ip->i_ib; j <= NIADDR; j++) { 12351846Sbostic /* 12451846Sbostic * In LFS, it's possible to have a block appended to a file 12551846Sbostic * for which the meta-blocks have not yet been allocated. 12651846Sbostic * This is a win if the file never gets written or if the 12751846Sbostic * file's growing. 12851846Sbostic */ 12951846Sbostic if ((daddr = bap[off]) == 0) { 13051348Sroot daddr = UNASSIGNED; 13151183Sbostic break; 13251183Sbostic } 133*51847Sbostic 134*51847Sbostic /* If searching for a meta-data block, quit when found. */ 135*51847Sbostic if (metalbn == realbn) 136*51847Sbostic break; 137*51847Sbostic 13851846Sbostic /* 13951846Sbostic * Read in the appropriate indirect block. LFS can't do a 14051846Sbostic * bread because bread knows that FFS will hand it the device 14151846Sbostic * vnode, not the file vnode, so the b_dev and b_blkno would 14251846Sbostic * be wrong. 14351846Sbostic * 14451846Sbostic * XXX 14551846Sbostic * This REALLY needs to be fixed, at the very least it needs 14651846Sbostic * to be rethought when the buffer cache goes away. 14751846Sbostic */ 14851183Sbostic if (bp) 14937736Smckusick brelse(bp); 150*51847Sbostic bp = getblk(vp, metalbn, fs->lfs_bsize); 15151183Sbostic if (bp->b_flags & (B_DONE | B_DELWRI)) { 152*51847Sbostic trace(TR_BREADHIT, pack(vp, size), metalbn); 15351183Sbostic } else { 154*51847Sbostic trace(TR_BREADMISS, pack(vp, size), metalbn); 155*51847Sbostic bp->b_blkno = daddr; 15651846Sbostic bp->b_flags |= B_READ; 15751183Sbostic bp->b_dev = devvp->v_rdev; 15851215Sbostic (devvp->v_op->vop_strategy)(bp); 15951183Sbostic curproc->p_stats->p_ru.ru_inblock++; /* XXX */ 16051183Sbostic if (error = biowait(bp)) { 16151183Sbostic brelse(bp); 16251183Sbostic return (error); 16351183Sbostic } 16437736Smckusick } 165*51847Sbostic 16637736Smckusick bap = bp->b_un.b_daddr; 16737736Smckusick sh /= NINDIR(fs); 16851183Sbostic off = (bn / sh) % NINDIR(fs); 169*51847Sbostic metalbn -= -1 + off * sh; 17051183Sbostic } 17151183Sbostic if (bp) 17239679Smckusick brelse(bp); 17351183Sbostic 17451183Sbostic *bnp = daddr; 17537736Smckusick return (0); 17637736Smckusick } 177