The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/freevxfs/vxfs_bmap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000-2001 Christoph Hellwig.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions, and the following disclaimer,
   10  *    without modification.
   11  * 2. The name of the author may not be used to endorse or promote products
   12  *    derived from this software without specific prior written permission.
   13  *
   14  * Alternatively, this software may be distributed under the terms of the
   15  * GNU General Public License ("GPL").
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #ident "$Id: vxfs_bmap.c,v 1.25 2002/01/02 23:36:55 hch Exp hch $"
   31 
   32 /*
   33  * Veritas filesystem driver - filesystem to disk block mapping.
   34  */
   35 #include <linux/fs.h>
   36 #include <linux/kernel.h>
   37 
   38 #include "vxfs.h"
   39 #include "vxfs_inode.h"
   40 
   41 
   42 #ifdef DIAGNOSTIC
   43 static void
   44 vxfs_typdump(struct vxfs_typed *typ)
   45 {
   46         printk(KERN_DEBUG "type=%Lu ", typ->vt_hdr >> VXFS_TYPED_TYPESHIFT);
   47         printk("offset=%Lx ", typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
   48         printk("block=%x ", typ->vt_block);
   49         printk("size=%x\n", typ->vt_size);
   50 }
   51 #endif
   52 
   53 /**
   54  * vxfs_bmap_ext4 - do bmap for ext4 extents
   55  * @ip:         pointer to the inode we do bmap for
   56  * @iblock:     logical block.
   57  *
   58  * Description:
   59  *   vxfs_bmap_ext4 performs the bmap operation for inodes with
   60  *   ext4-style extents (which are much like the traditional UNIX
   61  *   inode organisation).
   62  *
   63  * Returns:
   64  *   The physical block number on success, else Zero.
   65  */
   66 static daddr_t
   67 vxfs_bmap_ext4(struct inode *ip, long bn)
   68 {
   69         struct super_block *sb = ip->i_sb;
   70         struct vxfs_inode_info *vip = VXFS_INO(ip);
   71         unsigned long bsize = sb->s_blocksize;
   72         u32 indsize = vip->vii_ext4.ve4_indsize;
   73         int i;
   74 
   75         if (indsize > sb->s_blocksize)
   76                 goto fail_size;
   77 
   78         for (i = 0; i < VXFS_NDADDR; i++) {
   79                 struct direct *d = vip->vii_ext4.ve4_direct + i;
   80                 if (bn >= 0 && bn < d->size)
   81                         return (bn + d->extent);
   82                 bn -= d->size;
   83         }
   84 
   85         if ((bn / (indsize * indsize * bsize / 4)) == 0) {
   86                 struct buffer_head *buf;
   87                 daddr_t bno;
   88                 u32 *indir;
   89 
   90                 buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]);
   91                 if (!buf || !buffer_mapped(buf))
   92                         goto fail_buf;
   93 
   94                 indir = (u32 *)buf->b_data;
   95                 bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize);
   96 
   97                 brelse(buf);
   98                 return bno;
   99         } else
  100                 printk(KERN_WARNING "no matching indir?");
  101 
  102         return 0;
  103 
  104 fail_size:
  105         printk("vxfs: indirect extent to big!\n");
  106 fail_buf:
  107         return 0;
  108 }
  109 
  110 /**
  111  * vxfs_bmap_indir - recursion for vxfs_bmap_typed
  112  * @ip:         pointer to the inode we do bmap for
  113  * @indir:      indirect block we start reading at
  114  * @size:       size of the typed area to search
  115  * @block:      partially result from further searches
  116  *
  117  * Description:
  118  *   vxfs_bmap_indir reads a &struct vxfs_typed at @indir
  119  *   and performs the type-defined action.
  120  *
  121  * Return Value:
  122  *   The physical block number on success, else Zero.
  123  *
  124  * Note:
  125  *   Kernelstack is rare.  Unrecurse?
  126  */
  127 static daddr_t
  128 vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
  129 {
  130         struct buffer_head              *bp = NULL;
  131         daddr_t                         pblock = 0;
  132         int                             i;
  133 
  134         for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
  135                 struct vxfs_typed       *typ;
  136                 int64_t                 off;
  137 
  138                 bp = sb_bread(ip->i_sb,
  139                                 indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
  140                 if (!buffer_mapped(bp))
  141                         return 0;
  142 
  143                 typ = ((struct vxfs_typed *)bp->b_data) +
  144                         (i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
  145                 off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
  146 
  147                 if (block < off) {
  148                         brelse(bp);
  149                         continue;
  150                 }
  151 
  152                 switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
  153                 case VXFS_TYPED_INDIRECT:
  154                         pblock = vxfs_bmap_indir(ip, typ->vt_block,
  155                                         typ->vt_size, block - off);
  156                         if (pblock == -2)
  157                                 break;
  158                         goto out;
  159                 case VXFS_TYPED_DATA:
  160                         if ((block - off) >= typ->vt_size)
  161                                 break;
  162                         pblock = (typ->vt_block + block - off);
  163                         goto out;
  164                 case VXFS_TYPED_INDIRECT_DEV4:
  165                 case VXFS_TYPED_DATA_DEV4: {
  166                         struct vxfs_typed_dev4  *typ4 =
  167                                 (struct vxfs_typed_dev4 *)typ;
  168 
  169                         printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
  170                         printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
  171                                 typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
  172                         goto fail;
  173                 }
  174                 default:
  175                         BUG();
  176                 }
  177                 brelse(bp);
  178         }
  179 
  180 fail:
  181         pblock = 0;
  182 out:
  183         brelse(bp);
  184         return (pblock);
  185 }
  186 
  187 /**
  188  * vxfs_bmap_typed - bmap for typed extents
  189  * @ip:         pointer to the inode we do bmap for
  190  * @iblock:     logical block
  191  *
  192  * Description:
  193  *   Performs the bmap operation for typed extents.
  194  *
  195  * Return Value:
  196  *   The physical block number on success, else Zero.
  197  */
  198 static daddr_t
  199 vxfs_bmap_typed(struct inode *ip, long iblock)
  200 {
  201         struct vxfs_inode_info          *vip = VXFS_INO(ip);
  202         daddr_t                         pblock = 0;
  203         int                             i;
  204 
  205         for (i = 0; i < VXFS_NTYPED; i++) {
  206                 struct vxfs_typed       *typ = vip->vii_org.typed + i;
  207                 int64_t                 off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
  208 
  209 #ifdef DIAGNOSTIC
  210                 vxfs_typdump(typ);
  211 #endif
  212                 if (iblock < off)
  213                         continue;
  214                 switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
  215                 case VXFS_TYPED_INDIRECT:
  216                         pblock = vxfs_bmap_indir(ip, typ->vt_block,
  217                                         typ->vt_size, iblock - off);
  218                         if (pblock == -2)
  219                                 break;
  220                         return (pblock);
  221                 case VXFS_TYPED_DATA:
  222                         if ((iblock - off) < typ->vt_size)
  223                                 return (typ->vt_block + iblock - off);
  224                         break;
  225                 case VXFS_TYPED_INDIRECT_DEV4:
  226                 case VXFS_TYPED_DATA_DEV4: {
  227                         struct vxfs_typed_dev4  *typ4 =
  228                                 (struct vxfs_typed_dev4 *)typ;
  229 
  230                         printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
  231                         printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
  232                                 typ4->vd4_block, typ4->vd4_size, typ4->vd4_dev);
  233                         return 0;
  234                 }
  235                 default:
  236                         BUG();
  237                 }
  238         }
  239 
  240         return 0;
  241 }
  242 
  243 /**
  244  * vxfs_bmap1 - vxfs-internal bmap operation
  245  * @ip:                 pointer to the inode we do bmap for
  246  * @iblock:             logical block
  247  *
  248  * Description:
  249  *   vxfs_bmap1 perfoms a logical to physical block mapping
  250  *   for vxfs-internal purposes.
  251  *
  252  * Return Value:
  253  *   The physical block number on success, else Zero.
  254  */
  255 daddr_t
  256 vxfs_bmap1(struct inode *ip, long iblock)
  257 {
  258         struct vxfs_inode_info          *vip = VXFS_INO(ip);
  259 
  260         if (VXFS_ISEXT4(vip))
  261                 return vxfs_bmap_ext4(ip, iblock);
  262         if (VXFS_ISTYPED(vip))
  263                 return vxfs_bmap_typed(ip, iblock);
  264         if (VXFS_ISNONE(vip))
  265                 goto unsupp;
  266         if (VXFS_ISIMMED(vip))
  267                 goto unsupp;
  268 
  269         printk(KERN_WARNING "vxfs: inode %ld has no valid orgtype (%x)\n",
  270                         ip->i_ino, vip->vii_orgtype);
  271         BUG();
  272 
  273 unsupp:
  274         printk(KERN_WARNING "vxfs: inode %ld has an unsupported orgtype (%x)\n",
  275                         ip->i_ino, vip->vii_orgtype);
  276         return 0;
  277 }

Cache object: ad6bad7169156e4eb6086b17e5b625d4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.