1139825Simp/*- 21541Srgrimes * Copyright (c) 1989, 1991, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * (c) UNIX System Laboratories, Inc. 51541Srgrimes * All or some portions of this file are derived from material licensed 61541Srgrimes * to the University of California by American Telephone and Telegraph 71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with 81541Srgrimes * the permission of UNIX System Laboratories, Inc. 91541Srgrimes * 101541Srgrimes * Redistribution and use in source and binary forms, with or without 111541Srgrimes * modification, are permitted provided that the following conditions 121541Srgrimes * are met: 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161541Srgrimes * notice, this list of conditions and the following disclaimer in the 171541Srgrimes * documentation and/or other materials provided with the distribution. 181541Srgrimes * 4. Neither the name of the University nor the names of its contributors 191541Srgrimes * may be used to endorse or promote products derived from this software 201541Srgrimes * without specific prior written permission. 211541Srgrimes * 221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321541Srgrimes * SUCH DAMAGE. 331541Srgrimes * 3422521Sdyson * @(#)ufs_bmap.c 8.7 (Berkeley) 3/21/95 351541Srgrimes */ 361541Srgrimes 37116192Sobrien#include <sys/cdefs.h> 38116192Sobrien__FBSDID("$FreeBSD$"); 39116192Sobrien 401541Srgrimes#include <sys/param.h> 417430Sbde#include <sys/systm.h> 4260041Sphk#include <sys/bio.h> 431541Srgrimes#include <sys/buf.h> 441541Srgrimes#include <sys/proc.h> 451541Srgrimes#include <sys/vnode.h> 461541Srgrimes#include <sys/mount.h> 471541Srgrimes#include <sys/resourcevar.h> 4862976Smckusick#include <sys/stat.h> 491541Srgrimes 5059241Srwatson#include <ufs/ufs/extattr.h> 511541Srgrimes#include <ufs/ufs/quota.h> 521541Srgrimes#include <ufs/ufs/inode.h> 531541Srgrimes#include <ufs/ufs/ufsmount.h> 541541Srgrimes#include <ufs/ufs/ufs_extern.h> 551541Srgrimes 561541Srgrimes/* 57151657Sdelphij * Bmap converts the logical block number of a file to its physical block 581541Srgrimes * number on the disk. The conversion is done by using the logical block 591541Srgrimes * number to index into the array of block pointers described by the dinode. 601541Srgrimes */ 611541Srgrimesint 621541Srgrimesufs_bmap(ap) 631541Srgrimes struct vop_bmap_args /* { 641541Srgrimes struct vnode *a_vp; 6596572Sphk daddr_t a_bn; 66137726Sphk struct bufobj **a_bop; 6796572Sphk daddr_t *a_bnp; 681541Srgrimes int *a_runp; 6910551Sdyson int *a_runb; 701541Srgrimes } */ *ap; 711541Srgrimes{ 7298542Smckusick ufs2_daddr_t blkno; 7392363Smckusick int error; 7492363Smckusick 751541Srgrimes /* 761541Srgrimes * Check for underlying vnode requests and ensure that logical 771541Srgrimes * to physical mapping is requested. 781541Srgrimes */ 79137726Sphk if (ap->a_bop != NULL) 80137726Sphk *ap->a_bop = &VTOI(ap->a_vp)->i_devvp->v_bufobj; 811541Srgrimes if (ap->a_bnp == NULL) 821541Srgrimes return (0); 831541Srgrimes 84100344Smckusick error = ufs_bmaparray(ap->a_vp, ap->a_bn, &blkno, NULL, 8592363Smckusick ap->a_runp, ap->a_runb); 8692363Smckusick *ap->a_bnp = blkno; 8792363Smckusick return (error); 881541Srgrimes} 891541Srgrimes 901541Srgrimes/* 911541Srgrimes * Indirect blocks are now on the vnode for the file. They are given negative 921541Srgrimes * logical block numbers. Indirect blocks are addressed by the negative 931541Srgrimes * address of the first data block to which they point. Double indirect blocks 941541Srgrimes * are addressed by one less than the address of the first indirect block to 951541Srgrimes * which they point. Triple indirect blocks are addressed by one less than 961541Srgrimes * the address of the first double indirect block to which they point. 971541Srgrimes * 981541Srgrimes * ufs_bmaparray does the bmap conversion, and if requested returns the 991541Srgrimes * array of logical blocks which must be traversed to get to a block. 1001541Srgrimes * Each entry contains the offset into that block that gets you to the 1011541Srgrimes * next block and the disk address of the block (if it is assigned). 1021541Srgrimes */ 1031541Srgrimes 1041541Srgrimesint 105100344Smckusickufs_bmaparray(vp, bn, bnp, nbp, runp, runb) 1061541Srgrimes struct vnode *vp; 10798542Smckusick ufs2_daddr_t bn; 10898542Smckusick ufs2_daddr_t *bnp; 109100344Smckusick struct buf *nbp; 1101541Srgrimes int *runp; 11110551Sdyson int *runb; 1121541Srgrimes{ 11396506Sphk struct inode *ip; 1141541Srgrimes struct buf *bp; 1151541Srgrimes struct ufsmount *ump; 1161541Srgrimes struct mount *mp; 1171541Srgrimes struct vnode *devvp; 11876128Sphk struct indir a[NIADDR+1], *ap; 11998542Smckusick ufs2_daddr_t daddr; 12098542Smckusick ufs_lbn_t metalbn; 12162976Smckusick int error, num, maxrun = 0; 12276128Sphk int *nump; 1231541Srgrimes 12476128Sphk ap = NULL; 1251541Srgrimes ip = VTOI(vp); 1261541Srgrimes mp = vp->v_mount; 1271541Srgrimes ump = VFSTOUFS(mp); 12851483Sphk devvp = ump->um_devvp; 1291541Srgrimes 1301541Srgrimes if (runp) { 13162976Smckusick maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1; 13232724Sdyson *runp = 0; 13332724Sdyson } 13432724Sdyson 13532724Sdyson if (runb) { 13632724Sdyson *runb = 0; 13732724Sdyson } 13832724Sdyson 13932724Sdyson 14076128Sphk ap = a; 14176128Sphk nump = # 14276128Sphk error = ufs_getlbns(vp, bn, ap, nump); 1433427Sphk if (error) 1441541Srgrimes return (error); 1451541Srgrimes 1461541Srgrimes num = *nump; 1471541Srgrimes if (num == 0) { 148100344Smckusick if (bn >= 0 && bn < NDADDR) { 149100344Smckusick *bnp = blkptrtodb(ump, DIP(ip, i_db[bn])); 150100344Smckusick } else if (bn < 0 && bn >= -NXADDR) { 151100344Smckusick *bnp = blkptrtodb(ump, ip->i_din2->di_extb[-1 - bn]); 152100344Smckusick if (*bnp == 0) 153100344Smckusick *bnp = -1; 154100344Smckusick if (nbp == NULL) 155100344Smckusick panic("ufs_bmaparray: mapping ext data"); 156100344Smckusick nbp->b_xflags |= BX_ALTDATA; 157100344Smckusick return (0); 158100344Smckusick } else { 159100344Smckusick panic("ufs_bmaparray: blkno out of range"); 160100344Smckusick } 16163788Smckusick /* 16263788Smckusick * Since this is FFS independent code, we are out of 16363788Smckusick * scope for the definitions of BLK_NOCOPY and 16463788Smckusick * BLK_SNAP, but we do know that they will fall in 16563788Smckusick * the range 1..um_seqinc, so we use that test and 16663788Smckusick * return a request for a zeroed out buffer if attempts 16763788Smckusick * are made to read a BLK_NOCOPY or BLK_SNAP block. 16863788Smckusick */ 16998542Smckusick if ((ip->i_flags & SF_SNAPSHOT) && DIP(ip, i_db[bn]) > 0 && 17098542Smckusick DIP(ip, i_db[bn]) < ump->um_seqinc) { 17163788Smckusick *bnp = -1; 17263788Smckusick } else if (*bnp == 0) { 17362976Smckusick if (ip->i_flags & SF_SNAPSHOT) 17462976Smckusick *bnp = blkptrtodb(ump, bn * ump->um_seqinc); 17562976Smckusick else 17662976Smckusick *bnp = -1; 17762976Smckusick } else if (runp) { 17898542Smckusick ufs2_daddr_t bnb = bn; 1791541Srgrimes for (++bn; bn < NDADDR && *runp < maxrun && 18098542Smckusick is_sequential(ump, DIP(ip, i_db[bn - 1]), 18198542Smckusick DIP(ip, i_db[bn])); 1821541Srgrimes ++bn, ++*runp); 18310551Sdyson bn = bnb; 18410551Sdyson if (runb && (bn > 0)) { 18510551Sdyson for (--bn; (bn >= 0) && (*runb < maxrun) && 18698542Smckusick is_sequential(ump, DIP(ip, i_db[bn]), 18798542Smckusick DIP(ip, i_db[bn+1])); 18810551Sdyson --bn, ++*runb); 18910551Sdyson } 19010551Sdyson } 1911541Srgrimes return (0); 1921541Srgrimes } 1931541Srgrimes 1941541Srgrimes 1951541Srgrimes /* Get disk address out of indirect block array */ 19698542Smckusick daddr = DIP(ip, i_ib[ap->in_off]); 1971541Srgrimes 19876128Sphk for (bp = NULL, ++ap; --num; ++ap) { 1998876Srgrimes /* 2001541Srgrimes * Exit the loop if there is no disk address assigned yet and 2011541Srgrimes * the indirect block isn't in the cache, or if we were 2021541Srgrimes * looking for an indirect block and we've found it. 2031541Srgrimes */ 2041541Srgrimes 20576128Sphk metalbn = ap->in_lbn; 206136767Sphk if ((daddr == 0 && !incore(&vp->v_bufobj, metalbn)) || metalbn == bn) 2071541Srgrimes break; 2081541Srgrimes /* 2091541Srgrimes * If we get here, we've either got the block in the cache 2101541Srgrimes * or we have a disk address for it, go fetch it. 2111541Srgrimes */ 2121541Srgrimes if (bp) 21313490Sdyson bqrelse(bp); 2141541Srgrimes 215111856Sjeff bp = getblk(vp, metalbn, mp->mnt_stat.f_iosize, 0, 0, 0); 2166875Sdg if ((bp->b_flags & B_CACHE) == 0) { 217173464Sobrien#ifdef INVARIANTS 2186875Sdg if (!daddr) 21923562Smpp panic("ufs_bmaparray: indirect block not in cache"); 2201541Srgrimes#endif 2211541Srgrimes bp->b_blkno = blkptrtodb(ump, daddr); 22258345Sphk bp->b_iocmd = BIO_READ; 22358934Sphk bp->b_flags &= ~B_INVAL; 22458934Sphk bp->b_ioflags &= ~BIO_ERROR; 2255455Sdg vfs_busy_pages(bp, 0); 226121205Sphk bp->b_iooffset = dbtob(bp->b_blkno); 227136927Sphk bstrategy(bp); 228170174Sjeff curthread->td_ru.ru_inblock++; 22959762Sphk error = bufwait(bp); 2303427Sphk if (error) { 2311541Srgrimes brelse(bp); 2321541Srgrimes return (error); 2331541Srgrimes } 2341541Srgrimes } 2351541Srgrimes 23698542Smckusick if (ip->i_ump->um_fstype == UFS1) { 23798542Smckusick daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off]; 23898542Smckusick if (num == 1 && daddr && runp) { 23998542Smckusick for (bn = ap->in_off + 1; 24098542Smckusick bn < MNINDIR(ump) && *runp < maxrun && 24198542Smckusick is_sequential(ump, 24298542Smckusick ((ufs1_daddr_t *)bp->b_data)[bn - 1], 24398542Smckusick ((ufs1_daddr_t *)bp->b_data)[bn]); 24498542Smckusick ++bn, ++*runp); 24598542Smckusick bn = ap->in_off; 24698542Smckusick if (runb && bn) { 24798542Smckusick for (--bn; bn >= 0 && *runb < maxrun && 24898542Smckusick is_sequential(ump, 24998542Smckusick ((ufs1_daddr_t *)bp->b_data)[bn], 25098542Smckusick ((ufs1_daddr_t *)bp->b_data)[bn+1]); 25198542Smckusick --bn, ++*runb); 25298542Smckusick } 25398542Smckusick } 25498542Smckusick continue; 25598542Smckusick } 25698542Smckusick daddr = ((ufs2_daddr_t *)bp->b_data)[ap->in_off]; 25710551Sdyson if (num == 1 && daddr && runp) { 25876128Sphk for (bn = ap->in_off + 1; 2591541Srgrimes bn < MNINDIR(ump) && *runp < maxrun && 26022521Sdyson is_sequential(ump, 26198542Smckusick ((ufs2_daddr_t *)bp->b_data)[bn - 1], 26298542Smckusick ((ufs2_daddr_t *)bp->b_data)[bn]); 2631541Srgrimes ++bn, ++*runp); 26476128Sphk bn = ap->in_off; 26510551Sdyson if (runb && bn) { 26698542Smckusick for (--bn; bn >= 0 && *runb < maxrun && 26798542Smckusick is_sequential(ump, 26898542Smckusick ((ufs2_daddr_t *)bp->b_data)[bn], 26998542Smckusick ((ufs2_daddr_t *)bp->b_data)[bn + 1]); 27098542Smckusick --bn, ++*runb); 27110551Sdyson } 27210551Sdyson } 2731541Srgrimes } 2741541Srgrimes if (bp) 27513490Sdyson bqrelse(bp); 2761541Srgrimes 27763788Smckusick /* 27863788Smckusick * Since this is FFS independent code, we are out of scope for the 27963788Smckusick * definitions of BLK_NOCOPY and BLK_SNAP, but we do know that they 28063788Smckusick * will fall in the range 1..um_seqinc, so we use that test and 28163788Smckusick * return a request for a zeroed out buffer if attempts are made 28263788Smckusick * to read a BLK_NOCOPY or BLK_SNAP block. 28363788Smckusick */ 28463788Smckusick if ((ip->i_flags & SF_SNAPSHOT) && daddr > 0 && daddr < ump->um_seqinc){ 28563788Smckusick *bnp = -1; 28663788Smckusick return (0); 28763788Smckusick } 28862976Smckusick *bnp = blkptrtodb(ump, daddr); 28962976Smckusick if (*bnp == 0) { 29062976Smckusick if (ip->i_flags & SF_SNAPSHOT) 29162976Smckusick *bnp = blkptrtodb(ump, bn * ump->um_seqinc); 29262976Smckusick else 29362976Smckusick *bnp = -1; 29462976Smckusick } 2951541Srgrimes return (0); 2961541Srgrimes} 2971541Srgrimes 2981541Srgrimes/* 2991541Srgrimes * Create an array of logical block number/offset pairs which represent the 3001541Srgrimes * path of indirect blocks required to access a data block. The first "pair" 3011541Srgrimes * contains the logical block number of the appropriate single, double or 3021541Srgrimes * triple indirect block and the offset into the inode indirect block array. 3031541Srgrimes * Note, the logical block number of the inode single/double/triple indirect 3041541Srgrimes * block appears twice in the array, once with the offset into the i_ib and 3051541Srgrimes * once with the offset into the page itself. 3061541Srgrimes */ 3071541Srgrimesint 3081541Srgrimesufs_getlbns(vp, bn, ap, nump) 3091541Srgrimes struct vnode *vp; 31098542Smckusick ufs2_daddr_t bn; 3111541Srgrimes struct indir *ap; 3121541Srgrimes int *nump; 3131541Srgrimes{ 31498542Smckusick ufs2_daddr_t blockcnt; 31598542Smckusick ufs_lbn_t metalbn, realbn; 3161541Srgrimes struct ufsmount *ump; 31731394Sbde int i, numlevels, off; 3181541Srgrimes 3191541Srgrimes ump = VFSTOUFS(vp->v_mount); 3201541Srgrimes if (nump) 3211541Srgrimes *nump = 0; 3221541Srgrimes numlevels = 0; 3231541Srgrimes realbn = bn; 32498542Smckusick if (bn < 0) 32598542Smckusick bn = -bn; 3261541Srgrimes 3271541Srgrimes /* The first NDADDR blocks are direct blocks. */ 3281541Srgrimes if (bn < NDADDR) 3291541Srgrimes return (0); 3301541Srgrimes 3318876Srgrimes /* 3321541Srgrimes * Determine the number of levels of indirection. After this loop 3331541Srgrimes * is done, blockcnt indicates the number of data blocks possible 33431394Sbde * at the previous level of indirection, and NIADDR - i is the number 3351541Srgrimes * of levels of indirection needed to locate the requested block. 3361541Srgrimes */ 3371541Srgrimes for (blockcnt = 1, i = NIADDR, bn -= NDADDR;; i--, bn -= blockcnt) { 3381541Srgrimes if (i == 0) 3391541Srgrimes return (EFBIG); 34098542Smckusick blockcnt *= MNINDIR(ump); 34198542Smckusick if (bn < blockcnt) 3421541Srgrimes break; 3431541Srgrimes } 3441541Srgrimes 3451541Srgrimes /* Calculate the address of the first meta-block. */ 3461541Srgrimes if (realbn >= 0) 3471541Srgrimes metalbn = -(realbn - bn + NIADDR - i); 3481541Srgrimes else 3491541Srgrimes metalbn = -(-realbn - bn + NIADDR - i); 3501541Srgrimes 3518876Srgrimes /* 3521541Srgrimes * At each iteration, off is the offset into the bap array which is 3531541Srgrimes * an array of disk addresses at the current level of indirection. 3541541Srgrimes * The logical block number and the offset in that block are stored 3551541Srgrimes * into the argument array. 3561541Srgrimes */ 3571541Srgrimes ap->in_lbn = metalbn; 3581541Srgrimes ap->in_off = off = NIADDR - i; 3591541Srgrimes ap++; 3601541Srgrimes for (++numlevels; i <= NIADDR; i++) { 3611541Srgrimes /* If searching for a meta-data block, quit when found. */ 3621541Srgrimes if (metalbn == realbn) 3631541Srgrimes break; 3641541Srgrimes 36598542Smckusick blockcnt /= MNINDIR(ump); 3661541Srgrimes off = (bn / blockcnt) % MNINDIR(ump); 3671541Srgrimes 3681541Srgrimes ++numlevels; 3691541Srgrimes ap->in_lbn = metalbn; 3701541Srgrimes ap->in_off = off; 3711541Srgrimes ++ap; 3721541Srgrimes 3731541Srgrimes metalbn -= -1 + off * blockcnt; 3741541Srgrimes } 3751541Srgrimes if (nump) 3761541Srgrimes *nump = numlevels; 3771541Srgrimes return (0); 3781541Srgrimes} 379