root/ufs/ffs/ffs_subr.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ffs_bufatoff
  2. ffs_fragacct
  3. ffs_checkoverlap
  4. ffs_isblock
  5. ffs_clrblock
  6. ffs_setblock
  7. ffs_isfreeblock

    1 /*      $OpenBSD: ffs_subr.c,v 1.20 2007/05/26 20:26:51 pedro Exp $     */
    2 /*      $NetBSD: ffs_subr.c,v 1.6 1996/03/17 02:16:23 christos Exp $    */
    3 
    4 /*
    5  * Copyright (c) 1982, 1986, 1989, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)ffs_subr.c  8.2 (Berkeley) 9/21/93
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <ufs/ffs/fs.h>
   37 
   38 #ifdef _KERNEL
   39 #include <sys/systm.h>
   40 #include <sys/vnode.h>
   41 #include <sys/mount.h>
   42 #include <sys/buf.h>
   43 
   44 #include <ufs/ufs/quota.h>
   45 #include <ufs/ufs/inode.h>
   46 #include <ufs/ufs/ufsmount.h>
   47 #include <ufs/ufs/ufs_extern.h>
   48 
   49 #include <ufs/ffs/ffs_extern.h>
   50 
   51 /*
   52  * Return buffer with the contents of block "offset" from the beginning of
   53  * directory "ip".  If "res" is non-zero, fill it in with a pointer to the
   54  * remaining space in the directory.
   55  */
   56 int
   57 ffs_bufatoff(struct inode *ip, off_t offset, char **res, struct buf **bpp)
   58 {
   59         struct fs *fs;
   60         struct vnode *vp;
   61         struct buf *bp;
   62         daddr_t lbn;
   63         int bsize, error;
   64 
   65         vp = ITOV(ip);
   66         fs = ip->i_fs;
   67         lbn = lblkno(fs, offset);
   68         bsize = blksize(fs, ip, lbn);
   69 
   70         *bpp = NULL;
   71         if ((error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp)) != 0) {
   72                 brelse(bp);
   73                 return (error);
   74         }
   75         bp->b_bcount = bsize;
   76         if (res)
   77                 *res = (char *)bp->b_data + blkoff(fs, offset);
   78         *bpp = bp;
   79         return (0);
   80 }
   81 #else
   82 /* Prototypes for userland */
   83 void    ffs_fragacct(struct fs *, int, int32_t[], int);
   84 int     ffs_isfreeblock(struct fs *, unsigned char *, daddr_t);
   85 int     ffs_isblock(struct fs *, unsigned char *, daddr_t);
   86 void    ffs_clrblock(struct fs *, u_char *, daddr_t);
   87 void    ffs_setblock(struct fs *, unsigned char *, daddr_t);
   88 __dead void panic(const char *, ...);
   89 #endif
   90 
   91 /*
   92  * Update the frsum fields to reflect addition or deletion
   93  * of some frags.
   94  */
   95 void
   96 ffs_fragacct(struct fs *fs, int fragmap, int32_t fraglist[], int cnt)
   97 {
   98         int inblk;
   99         int field, subfield;
  100         int siz, pos;
  101 
  102         inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
  103         fragmap <<= 1;
  104         for (siz = 1; siz < fs->fs_frag; siz++) {
  105                 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
  106                         continue;
  107                 field = around[siz];
  108                 subfield = inside[siz];
  109                 for (pos = siz; pos <= fs->fs_frag; pos++) {
  110                         if ((fragmap & field) == subfield) {
  111                                 fraglist[siz] += cnt;
  112                                 pos += siz;
  113                                 field <<= siz;
  114                                 subfield <<= siz;
  115                         }
  116                         field <<= 1;
  117                         subfield <<= 1;
  118                 }
  119         }
  120 }
  121 
  122 #if defined(_KERNEL) && defined(DIAGNOSTIC)
  123 void
  124 ffs_checkoverlap(struct buf *bp, struct inode *ip)
  125 {
  126         daddr_t start, last;
  127         struct vnode *vp;
  128         struct buf *ep;
  129 
  130         start = bp->b_blkno;
  131         last = start + btodb(bp->b_bcount) - 1;
  132         LIST_FOREACH(ep, &bufhead, b_list) {
  133                 if (ep == bp || (ep->b_flags & B_INVAL) ||
  134                     ep->b_vp == NULLVP)
  135                         continue;
  136                 if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL))
  137                         continue;
  138                 if (vp != ip->i_devvp)
  139                         continue;
  140                 /* look for overlap */
  141                 if (ep->b_bcount == 0 || ep->b_blkno > last ||
  142                     ep->b_blkno + btodb(ep->b_bcount) <= start)
  143                         continue;
  144                 vprint("Disk overlap", vp);
  145                 (void)printf("\tstart %d, end %d overlap start %d, end %ld\n",
  146                         start, last, ep->b_blkno,
  147                         ep->b_blkno + btodb(ep->b_bcount) - 1);
  148                 panic("Disk buffer overlap");
  149         }
  150 }
  151 #endif /* DIAGNOSTIC */
  152 
  153 /*
  154  * block operations
  155  *
  156  * check if a block is available
  157  */
  158 int
  159 ffs_isblock(struct fs *fs, unsigned char *cp, daddr_t h)
  160 {
  161         unsigned char mask;
  162 
  163         switch (fs->fs_frag) {
  164         default:
  165         case 8:
  166                 return (cp[h] == 0xff);
  167         case 4:
  168                 mask = 0x0f << ((h & 0x1) << 2);
  169                 return ((cp[h >> 1] & mask) == mask);
  170         case 2:
  171                 mask = 0x03 << ((h & 0x3) << 1);
  172                 return ((cp[h >> 2] & mask) == mask);
  173         case 1:
  174                 mask = 0x01 << (h & 0x7);
  175                 return ((cp[h >> 3] & mask) == mask);
  176         }
  177 }
  178 
  179 /*
  180  * take a block out of the map
  181  */
  182 void
  183 ffs_clrblock(struct fs *fs, u_char *cp, daddr_t h)
  184 {
  185 
  186         switch (fs->fs_frag) {
  187         default:
  188         case 8:
  189                 cp[h] = 0;
  190                 return;
  191         case 4:
  192                 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
  193                 return;
  194         case 2:
  195                 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
  196                 return;
  197         case 1:
  198                 cp[h >> 3] &= ~(0x01 << (h & 0x7));
  199                 return;
  200         }
  201 }
  202 
  203 /*
  204  * put a block into the map
  205  */
  206 void
  207 ffs_setblock(struct fs *fs, unsigned char *cp, daddr_t h)
  208 {
  209 
  210         switch (fs->fs_frag) {
  211         default:
  212         case 8:
  213                 cp[h] = 0xff;
  214                 return;
  215         case 4:
  216                 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
  217                 return;
  218         case 2:
  219                 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
  220                 return;
  221         case 1:
  222                 cp[h >> 3] |= (0x01 << (h & 0x7));
  223                 return;
  224         }
  225 }
  226 
  227 /*
  228  * check if a block is free
  229  */
  230 int
  231 ffs_isfreeblock(struct fs *fs, unsigned char *cp, daddr_t h)
  232 {
  233 
  234         switch (fs->fs_frag) {
  235         default:
  236         case 8:
  237                 return (cp[h] == 0);
  238         case 4:
  239                 return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
  240         case 2:
  241                 return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
  242         case 1:
  243                 return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
  244         }
  245 }

/* [<][>][^][v][top][bottom][index][help] */