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/ufs/ffs/ffs_subr.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 /*      $NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1982, 1986, 1989, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)ffs_subr.c  8.5 (Berkeley) 3/21/95
   32  */
   33 
   34 #if HAVE_NBTOOL_CONFIG_H
   35 #include "nbtool_config.h"
   36 #endif
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: ffs_subr.c,v 1.32 2003/12/30 12:33:24 pk Exp $");
   40 
   41 #include <sys/param.h>
   42 
   43 /* in ffs_tables.c */
   44 extern const int inside[], around[];
   45 extern const u_char * const fragtbl[];
   46 
   47 #ifndef _KERNEL
   48 #include <ufs/ufs/dinode.h>
   49 #include <ufs/ffs/fs.h>
   50 #include <ufs/ffs/ffs_extern.h>
   51 #include <ufs/ufs/ufs_bswap.h>
   52 void    panic __P((const char *, ...))
   53     __attribute__((__noreturn__,__format__(__printf__,1,2)));
   54 
   55 #else   /* _KERNEL */
   56 #include <sys/systm.h>
   57 #include <sys/vnode.h>
   58 #include <sys/mount.h>
   59 #include <sys/buf.h>
   60 #include <sys/inttypes.h>
   61 #include <sys/pool.h>
   62 #include <ufs/ufs/inode.h>
   63 #include <ufs/ufs/ufsmount.h>
   64 #include <ufs/ufs/ufs_extern.h>
   65 #include <ufs/ffs/fs.h>
   66 #include <ufs/ffs/ffs_extern.h>
   67 #include <ufs/ufs/ufs_bswap.h>
   68 
   69 /*
   70  * Return buffer with the contents of block "offset" from the beginning of
   71  * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
   72  * remaining space in the directory.
   73  */
   74 int
   75 ffs_blkatoff(v)
   76         void *v;
   77 {
   78         struct vop_blkatoff_args /* {
   79                 struct vnode *a_vp;
   80                 off_t a_offset;
   81                 char **a_res;
   82                 struct buf **a_bpp;
   83         } */ *ap = v;
   84         struct inode *ip;
   85         struct fs *fs;
   86         struct buf *bp;
   87         daddr_t lbn;
   88         int bsize, error;
   89 
   90         ip = VTOI(ap->a_vp);
   91         fs = ip->i_fs;
   92         lbn = lblkno(fs, ap->a_offset);
   93         bsize = blksize(fs, ip, lbn);
   94 
   95         *ap->a_bpp = NULL;
   96         if ((error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) != 0) {
   97                 brelse(bp);
   98                 return (error);
   99         }
  100         if (ap->a_res)
  101                 *ap->a_res = (char *)bp->b_data + blkoff(fs, ap->a_offset);
  102         *ap->a_bpp = bp;
  103         return (0);
  104 }
  105 
  106 
  107 /*
  108  * Load up the contents of an inode and copy the appropriate pieces
  109  * to the incore copy.
  110  */
  111 void
  112 ffs_load_inode(bp, ip, fs, ino)
  113         struct buf *bp;
  114         struct inode *ip;
  115         struct fs *fs;
  116         ino_t ino;
  117 {
  118         struct ufs1_dinode *dp1;
  119         struct ufs2_dinode *dp2;
  120 
  121         if (ip->i_ump->um_fstype == UFS1) {
  122                 dp1 = (struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino);
  123 #ifdef FFS_EI
  124                 if (UFS_FSNEEDSWAP(fs))
  125                         ffs_dinode1_swap(dp1, ip->i_din.ffs1_din);
  126                 else
  127 #endif
  128                 *ip->i_din.ffs1_din = *dp1;
  129 
  130                 ip->i_mode = ip->i_ffs1_mode;
  131                 ip->i_nlink = ip->i_ffs1_nlink;
  132                 ip->i_size = ip->i_ffs1_size;
  133                 ip->i_flags = ip->i_ffs1_flags;
  134                 ip->i_gen = ip->i_ffs1_gen;
  135                 ip->i_uid = ip->i_ffs1_uid;
  136                 ip->i_gid = ip->i_ffs1_gid;
  137         } else {
  138                 dp2 = (struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino);
  139 #ifdef FFS_EI
  140                 if (UFS_FSNEEDSWAP(fs))
  141                         ffs_dinode2_swap(dp2, ip->i_din.ffs2_din);
  142                 else
  143 #endif
  144                 *ip->i_din.ffs2_din = *dp2;
  145 
  146                 ip->i_mode = ip->i_ffs2_mode;
  147                 ip->i_nlink = ip->i_ffs2_nlink;
  148                 ip->i_size = ip->i_ffs2_size;
  149                 ip->i_flags = ip->i_ffs2_flags;
  150                 ip->i_gen = ip->i_ffs2_gen;
  151                 ip->i_uid = ip->i_ffs2_uid;
  152                 ip->i_gid = ip->i_ffs2_gid;
  153         }
  154 }
  155 
  156 #endif  /* _KERNEL */
  157 
  158 /*
  159  * Update the frsum fields to reflect addition or deletion 
  160  * of some frags.
  161  */
  162 void
  163 ffs_fragacct(fs, fragmap, fraglist, cnt, needswap)
  164         struct fs *fs;
  165         int fragmap;
  166         int32_t fraglist[];
  167         int cnt;
  168         int needswap;
  169 {
  170         int inblk;
  171         int field, subfield;
  172         int siz, pos;
  173 
  174         inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
  175         fragmap <<= 1;
  176         for (siz = 1; siz < fs->fs_frag; siz++) {
  177                 if ((inblk & (1 << (siz + (fs->fs_frag & (NBBY - 1))))) == 0)
  178                         continue;
  179                 field = around[siz];
  180                 subfield = inside[siz];
  181                 for (pos = siz; pos <= fs->fs_frag; pos++) {
  182                         if ((fragmap & field) == subfield) {
  183                                 fraglist[siz] = ufs_rw32(
  184                                     ufs_rw32(fraglist[siz], needswap) + cnt,
  185                                     needswap);
  186                                 pos += siz;
  187                                 field <<= siz;
  188                                 subfield <<= siz;
  189                         }
  190                         field <<= 1;
  191                         subfield <<= 1;
  192                 }
  193         }
  194 }
  195 
  196 #if defined(_KERNEL) && defined(DIAGNOSTIC)
  197 void
  198 ffs_checkoverlap(bp, ip)
  199         struct buf *bp;
  200         struct inode *ip;
  201 {
  202 #if 0
  203         struct buf *ebp, *ep;
  204         daddr_t start, last;
  205         struct vnode *vp;
  206 
  207         ebp = &buf[nbuf];
  208         start = bp->b_blkno;
  209         last = start + btodb(bp->b_bcount) - 1;
  210         for (ep = buf; ep < ebp; ep++) {
  211                 if (ep == bp || (ep->b_flags & B_INVAL) ||
  212                     ep->b_vp == NULLVP)
  213                         continue;
  214                 if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL))
  215                         continue;
  216                 if (vp != ip->i_devvp)
  217                         continue;
  218                 /* look for overlap */
  219                 if (ep->b_bcount == 0 || ep->b_blkno > last ||
  220                     ep->b_blkno + btodb(ep->b_bcount) <= start)
  221                         continue;
  222                 vprint("Disk overlap", vp);
  223                 printf("\tstart %" PRId64 ", end %" PRId64 " overlap start "
  224                     "%" PRId64 ", end %" PRId64 "\n",
  225                     start, last, ep->b_blkno,
  226                     ep->b_blkno + btodb(ep->b_bcount) - 1);
  227                 panic("Disk buffer overlap");
  228         }
  229 #else
  230         printf("ffs_checkoverlap disabled due to buffer cache implementation changes\n");
  231 #endif
  232 }
  233 #endif /* _KERNEL && DIAGNOSTIC */
  234 
  235 /*
  236  * block operations
  237  *
  238  * check if a block is available
  239  *  returns true if all the correponding bits in the free map are 1
  240  *  returns false if any corresponding bit in the free map is 0 
  241  */
  242 int
  243 ffs_isblock(fs, cp, h)
  244         struct fs *fs;
  245         u_char *cp;
  246         int32_t h;
  247 {
  248         u_char mask;
  249 
  250         switch ((int)fs->fs_fragshift) {
  251         case 3:
  252                 return (cp[h] == 0xff);
  253         case 2:
  254                 mask = 0x0f << ((h & 0x1) << 2);
  255                 return ((cp[h >> 1] & mask) == mask);
  256         case 1:
  257                 mask = 0x03 << ((h & 0x3) << 1);
  258                 return ((cp[h >> 2] & mask) == mask);
  259         case 0:
  260                 mask = 0x01 << (h & 0x7);
  261                 return ((cp[h >> 3] & mask) == mask);
  262         default:
  263                 panic("ffs_isblock: unknown fs_fragshift %d",
  264                     (int)fs->fs_fragshift);
  265         }
  266 }
  267 
  268 /*
  269  * check if a block is completely allocated
  270  *  returns true if all the corresponding bits in the free map are 0
  271  *  returns false if any corresponding bit in the free map is 1
  272  */
  273 int
  274 ffs_isfreeblock(fs, cp, h)
  275         struct fs *fs;
  276         u_char *cp;
  277         int32_t h;
  278 {
  279 
  280         switch ((int)fs->fs_fragshift) {
  281         case 3:
  282                 return (cp[h] == 0);
  283         case 2:
  284                 return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
  285         case 1:
  286                 return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
  287         case 0:
  288                 return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
  289         default:
  290                 panic("ffs_isfreeblock: unknown fs_fragshift %d",
  291                     (int)fs->fs_fragshift);
  292         }
  293 }
  294 
  295 /*
  296  * take a block out of the map
  297  */
  298 void
  299 ffs_clrblock(fs, cp, h)
  300         struct fs *fs;
  301         u_char *cp;
  302         int32_t h;
  303 {
  304 
  305         switch ((int)fs->fs_fragshift) {
  306         case 3:
  307                 cp[h] = 0;
  308                 return;
  309         case 2:
  310                 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
  311                 return;
  312         case 1:
  313                 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
  314                 return;
  315         case 0:
  316                 cp[h >> 3] &= ~(0x01 << (h & 0x7));
  317                 return;
  318         default:
  319                 panic("ffs_clrblock: unknown fs_fragshift %d",
  320                     (int)fs->fs_fragshift);
  321         }
  322 }
  323 
  324 /*
  325  * put a block into the map
  326  */
  327 void
  328 ffs_setblock(fs, cp, h)
  329         struct fs *fs;
  330         u_char *cp;
  331         int32_t h;
  332 {
  333 
  334         switch ((int)fs->fs_fragshift) {
  335         case 3:
  336                 cp[h] = 0xff;
  337                 return;
  338         case 2:
  339                 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
  340                 return;
  341         case 1:
  342                 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
  343                 return;
  344         case 0:
  345                 cp[h >> 3] |= (0x01 << (h & 0x7));
  346                 return;
  347         default:
  348                 panic("ffs_setblock: unknown fs_fragshift %d",
  349                     (int)fs->fs_fragshift);
  350         }
  351 }

Cache object: bbaaed51f8450709b2f931ce2d29aa96


[ 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.