LCOV - code coverage report
Current view: top level - ufs/ffs - ffs_subr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 113 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ffs_subr.c,v 1.32 2016/08/10 11:33:01 natano 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           0 : ffs_bufatoff(struct inode *ip, off_t offset, char **res, struct buf **bpp)
      58             : {
      59             :         struct fs *fs;
      60             :         struct vnode *vp;
      61           0 :         struct buf *bp;
      62             :         daddr_t lbn;
      63             :         int bsize, error;
      64             : 
      65           0 :         vp = ITOV(ip);
      66           0 :         fs = ip->i_fs;
      67           0 :         lbn = lblkno(fs, offset);
      68           0 :         bsize = blksize(fs, ip, lbn);
      69             : 
      70           0 :         *bpp = NULL;
      71           0 :         if ((error = bread(vp, lbn, fs->fs_bsize, &bp)) != 0) {
      72           0 :                 brelse(bp);
      73           0 :                 return (error);
      74             :         }
      75           0 :         buf_adjcnt(bp, bsize);
      76           0 :         if (res)
      77           0 :                 *res = (char *)bp->b_data + blkoff(fs, offset);
      78           0 :         *bpp = bp;
      79           0 :         return (0);
      80           0 : }
      81             : #else
      82             : /* Prototypes for userland */
      83             : void    ffs_fragacct(struct fs *, int, int32_t[], int);
      84             : int     ffs_isfreeblock(struct fs *, u_char *, daddr_t);
      85             : int     ffs_isblock(struct fs *, u_char *, daddr_t);
      86             : void    ffs_clrblock(struct fs *, u_char *, daddr_t);
      87             : void    ffs_setblock(struct fs *, u_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           0 : 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           0 :         inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
     103           0 :         fragmap <<= 1;
     104           0 :         for (siz = 1; siz < fs->fs_frag; siz++) {
     105           0 :                 if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
     106             :                         continue;
     107           0 :                 field = around[siz];
     108           0 :                 subfield = inside[siz];
     109           0 :                 for (pos = siz; pos <= fs->fs_frag; pos++) {
     110           0 :                         if ((fragmap & field) == subfield) {
     111           0 :                                 fraglist[siz] += cnt;
     112           0 :                                 pos += siz;
     113           0 :                                 field <<= siz;
     114           0 :                                 subfield <<= siz;
     115           0 :                         }
     116           0 :                         field <<= 1;
     117           0 :                         subfield <<= 1;
     118             :                 }
     119             :         }
     120           0 : }
     121             : 
     122             : #if defined(_KERNEL) && defined(DIAGNOSTIC)
     123             : void
     124           0 : ffs_checkoverlap(struct buf *bp, struct inode *ip)
     125             : {
     126             :         daddr_t start, last;
     127           0 :         struct vnode *vp;
     128             :         struct buf *ep;
     129             : 
     130           0 :         start = bp->b_blkno;
     131           0 :         last = start + btodb(bp->b_bcount) - 1;
     132           0 :         LIST_FOREACH(ep, &bufhead, b_list) {
     133           0 :                 if (ep == bp || (ep->b_flags & B_INVAL) ||
     134           0 :                     ep->b_vp == NULLVP)
     135             :                         continue;
     136           0 :                 if (VOP_BMAP(ep->b_vp, 0, &vp, NULL, NULL))
     137             :                         continue;
     138           0 :                 if (vp != ip->i_devvp)
     139             :                         continue;
     140             :                 /* look for overlap */
     141           0 :                 if (ep->b_bcount == 0 || ep->b_blkno > last ||
     142           0 :                     ep->b_blkno + btodb(ep->b_bcount) <= start)
     143             :                         continue;
     144           0 :                 vprint("Disk overlap", vp);
     145           0 :                 (void)printf("\tstart %lld, end %lld overlap start %llu, "
     146             :                     "end %llu\n", (long long)start, (long long)last,
     147           0 :                     (long long)ep->b_blkno,
     148           0 :                     (long long)(ep->b_blkno + btodb(ep->b_bcount) - 1));
     149           0 :                 panic("Disk buffer overlap");
     150             :         }
     151           0 : }
     152             : #endif /* DIAGNOSTIC */
     153             : 
     154             : /*
     155             :  * block operations
     156             :  *
     157             :  * check if a block is available
     158             :  */
     159             : int
     160           0 : ffs_isblock(struct fs *fs, u_char *cp, daddr_t h)
     161             : {
     162             :         u_char mask;
     163             : 
     164           0 :         switch (fs->fs_frag) {
     165             :         default:
     166             :         case 8:
     167           0 :                 return (cp[h] == 0xff);
     168             :         case 4:
     169           0 :                 mask = 0x0f << ((h & 0x1) << 2);
     170           0 :                 return ((cp[h >> 1] & mask) == mask);
     171             :         case 2:
     172           0 :                 mask = 0x03 << ((h & 0x3) << 1);
     173           0 :                 return ((cp[h >> 2] & mask) == mask);
     174             :         case 1:
     175           0 :                 mask = 0x01 << (h & 0x7);
     176           0 :                 return ((cp[h >> 3] & mask) == mask);
     177             :         }
     178           0 : }
     179             : 
     180             : /*
     181             :  * take a block out of the map
     182             :  */
     183             : void
     184           0 : ffs_clrblock(struct fs *fs, u_char *cp, daddr_t h)
     185             : {
     186             : 
     187           0 :         switch (fs->fs_frag) {
     188             :         default:
     189             :         case 8:
     190           0 :                 cp[h] = 0;
     191           0 :                 return;
     192             :         case 4:
     193           0 :                 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
     194           0 :                 return;
     195             :         case 2:
     196           0 :                 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
     197           0 :                 return;
     198             :         case 1:
     199           0 :                 cp[h >> 3] &= ~(0x01 << (h & 0x7));
     200           0 :                 return;
     201             :         }
     202           0 : }
     203             : 
     204             : /*
     205             :  * put a block into the map
     206             :  */
     207             : void
     208           0 : ffs_setblock(struct fs *fs, u_char *cp, daddr_t h)
     209             : {
     210             : 
     211           0 :         switch (fs->fs_frag) {
     212             :         default:
     213             :         case 8:
     214           0 :                 cp[h] = 0xff;
     215           0 :                 return;
     216             :         case 4:
     217           0 :                 cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
     218           0 :                 return;
     219             :         case 2:
     220           0 :                 cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
     221           0 :                 return;
     222             :         case 1:
     223           0 :                 cp[h >> 3] |= (0x01 << (h & 0x7));
     224           0 :                 return;
     225             :         }
     226           0 : }
     227             : 
     228             : /*
     229             :  * check if a block is free
     230             :  */
     231             : int
     232           0 : ffs_isfreeblock(struct fs *fs, u_char *cp, daddr_t h)
     233             : {
     234             : 
     235           0 :         switch (fs->fs_frag) {
     236             :         default:
     237             :         case 8:
     238           0 :                 return (cp[h] == 0);
     239             :         case 4:
     240           0 :                 return ((cp[h >> 1] & (0x0f << ((h & 0x1) << 2))) == 0);
     241             :         case 2:
     242           0 :                 return ((cp[h >> 2] & (0x03 << ((h & 0x3) << 1))) == 0);
     243             :         case 1:
     244           0 :                 return ((cp[h >> 3] & (0x01 << (h & 0x7))) == 0);
     245             :         }
     246           0 : }
     247             : 
     248             : #ifdef _KERNEL
     249             : /*
     250             :  * Initialize the vnode associated with a new inode, handle aliased
     251             :  * vnodes.
     252             :  */
     253             : int
     254           0 : ffs_vinit(struct mount *mntp, struct vnode **vpp)
     255             : {
     256             :         struct inode *ip;
     257             :         struct vnode *vp, *nvp;
     258           0 :         struct timeval mtv;
     259             : 
     260           0 :         vp = *vpp;
     261           0 :         ip = VTOI(vp);
     262           0 :         switch(vp->v_type = IFTOVT(DIP(ip, mode))) {
     263             :         case VCHR:
     264             :         case VBLK:
     265           0 :                 vp->v_op = &ffs_specvops;
     266           0 :                 if ((nvp = checkalias(vp, DIP(ip, rdev), mntp)) != NULL) {
     267             :                         /*
     268             :                          * Discard unneeded vnode, but save its inode.
     269             :                          * Note that the lock is carried over in the inode
     270             :                          * to the replacement vnode.
     271             :                          */
     272           0 :                         nvp->v_data = vp->v_data;
     273           0 :                         vp->v_data = NULL;
     274           0 :                         vp->v_op = &spec_vops;
     275             : #ifdef VFSLCKDEBUG
     276             :                         vp->v_flag &= ~VLOCKSWORK;
     277             : #endif
     278           0 :                         vrele(vp);
     279           0 :                         vgone(vp);
     280             :                         /*
     281             :                          * Reinitialize aliased inode.
     282             :                          */
     283             :                         vp = nvp;
     284           0 :                         ip->i_vnode = vp;
     285           0 :                 }
     286             :                 break;
     287             :         case VFIFO:
     288             : #ifdef FIFO
     289           0 :                 vp->v_op = &ffs_fifovops;
     290           0 :                 break;
     291             : #else
     292             :                 return (EOPNOTSUPP);
     293             : #endif
     294             :         case VNON:
     295             :         case VBAD:
     296             :         case VSOCK:
     297             :         case VLNK:
     298             :         case VDIR:
     299             :         case VREG:
     300             :                 break;
     301             :         }
     302           0 :         if (ip->i_number == ROOTINO)
     303           0 :                 vp->v_flag |= VROOT;
     304             :         /*
     305             :          * Initialize modrev times
     306             :          */
     307           0 :         getmicrouptime(&mtv);
     308           0 :         ip->i_modrev = (u_quad_t)mtv.tv_sec << 32;
     309           0 :         ip->i_modrev |= (u_quad_t)mtv.tv_usec * 4294;
     310           0 :         *vpp = vp;
     311           0 :         return (0);
     312           0 : }
     313             : #endif /* _KERNEL */

Generated by: LCOV version 1.13