[BACK]Return to ufs_dirhash.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / ufs / ufs

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/ufs/ufs/ufs_dirhash.c between version 1.1.2.2 and 1.12.2.1

version 1.1.2.2, 2005/01/24 08:36:05 version 1.12.2.1, 2007/03/12 06:01:10
Line 31 
Line 31 
  * This implements a hash-based lookup scheme for UFS directories.   * This implements a hash-based lookup scheme for UFS directories.
  */   */
   
 #ifdef UFS_DIRHASH  
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/kernel.h>  #include <sys/kernel.h>
Line 63  static MALLOC_DEFINE(M_DIRHASH, "UFS dir
Line 61  static MALLOC_DEFINE(M_DIRHASH, "UFS dir
   
 static int ufs_dirhashminblks = 5;  static int ufs_dirhashminblks = 5;
 static int ufs_dirhashmaxmem = 2 * 1024 * 1024;  static int ufs_dirhashmaxmem = 2 * 1024 * 1024;
 static int ufs_dirhashmem;  static int ufs_dirhashmem;
 static int ufs_dirhashcheck = 0;  static int ufs_dirhashcheck = 0;
   
 static int ufsdirhash_hash(struct dirhash *dh, const char *name, int namelen);  static int ufsdirhash_hash(struct dirhash *dh, const char *name, int namelen);
Line 76  static doff_t ufsdirhash_getprev(struct 
Line 74  static doff_t ufsdirhash_getprev(struct 
            int dirblksiz);             int dirblksiz);
 static int ufsdirhash_recycle(int wanted);  static int ufsdirhash_recycle(int wanted);
   
 POOL_INIT(ufsdirhash_pool, DH_NBLKOFF * sizeof(daddr_t), 0, 0, 0, "ufsdirhash",  static POOL_INIT(ufsdirhash_pool, DH_NBLKOFF * sizeof(daddr_t), 0, 0, 0,
     &pool_allocator_nointr);      "ufsdirhash", &pool_allocator_nointr);
   
 #define DIRHASHLIST_LOCK()              do { } while (0)  #define DIRHASHLIST_LOCK()              do { } while (0)
 #define DIRHASHLIST_UNLOCK()            do { } while (0)  #define DIRHASHLIST_UNLOCK()            do { } while (0)
Line 102  ufsdirhash_build(struct inode *ip)
Line 100  ufsdirhash_build(struct inode *ip)
         struct vnode *vp;          struct vnode *vp;
         doff_t bmask, pos;          doff_t bmask, pos;
         int dirblocks, i, j, memreqd, nblocks, narrays, nslots, slot;          int dirblocks, i, j, memreqd, nblocks, narrays, nslots, slot;
         const int needswap = UFS_MPNEEDSWAP(ip->i_ump);          const int needswap = UFS_MPNEEDSWAP(ip->i_ump);
         int dirblksiz = ip->i_ump->um_dirblksiz;          int dirblksiz = ip->i_ump->um_dirblksiz;
   
         /* Check if we can/should use dirhash. */          /* Check if we can/should use dirhash. */
Line 165  ufsdirhash_build(struct inode *ip)
Line 163  ufsdirhash_build(struct inode *ip)
                 DIRHASHLIST_UNLOCK();                  DIRHASHLIST_UNLOCK();
                 return (-1);                  return (-1);
         }          }
         MALLOC(dh->dh_hash, doff_t **, narrays * sizeof(dh->dh_hash[0]),          dh->dh_hash = (doff_t **)malloc(narrays * sizeof(dh->dh_hash[0]),
             M_DIRHASH, M_NOWAIT | M_ZERO);              M_DIRHASH, M_NOWAIT | M_ZERO);
         MALLOC(dh->dh_blkfree, u_int8_t *, nblocks * sizeof(dh->dh_blkfree[0]),          dh->dh_blkfree = (u_int8_t *)malloc(nblocks * sizeof(dh->dh_blkfree[0]),
             M_DIRHASH, M_NOWAIT);              M_DIRHASH, M_NOWAIT);
         if (dh->dh_hash == NULL || dh->dh_blkfree == NULL)          if (dh->dh_hash == NULL || dh->dh_blkfree == NULL)
                 goto fail;                  goto fail;
Line 196  ufsdirhash_build(struct inode *ip)
Line 194  ufsdirhash_build(struct inode *ip)
         bmask = VFSTOUFS(vp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;          bmask = VFSTOUFS(vp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
         pos = 0;          pos = 0;
         while (pos < ip->i_size) {          while (pos < ip->i_size) {
                   if ((curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD)
                       != 0) {
                           preempt();
                   }
                 /* If necessary, get the next directory block. */                  /* If necessary, get the next directory block. */
                 if ((pos & bmask) == 0) {                  if ((pos & bmask) == 0) {
                         if (bp != NULL)                          if (bp != NULL)
                                 brelse(bp);                                  brelse(bp);
                         if (VOP_BLKATOFF(vp, (off_t)pos, NULL, &bp) != 0)                          if (ufs_blkatoff(vp, (off_t)pos, NULL, &bp) != 0)
                                 goto fail;                                  goto fail;
                 }                  }
   
Line 309  ufsdirhash_lookup(struct inode *ip, cons
Line 311  ufsdirhash_lookup(struct inode *ip, cons
         struct buf *bp;          struct buf *bp;
         doff_t blkoff, bmask, offset, prevoff;          doff_t blkoff, bmask, offset, prevoff;
         int i, slot;          int i, slot;
         const int needswap = UFS_MPNEEDSWAP(ip->i_ump);          const int needswap = UFS_MPNEEDSWAP(ip->i_ump);
         int dirblksiz = ip->i_ump->um_dirblksiz;          int dirblksiz = ip->i_ump->um_dirblksiz;
   
         if ((dh = ip->i_dirhash) == NULL)          if ((dh = ip->i_dirhash) == NULL)
Line 377  restart:
Line 379  restart:
                          * We found an entry with the expected offset. This                           * We found an entry with the expected offset. This
                          * is probably the entry we want, but if not, the                           * is probably the entry we want, but if not, the
                          * code below will turn off seqoff and retry.                           * code below will turn off seqoff and retry.
                          */                           */
                         slot = i;                          slot = i;
                 } else                  } else
                         dh->dh_seqopt = 0;                          dh->dh_seqopt = 0;
         }          }
   
Line 395  restart:
Line 397  restart:
                         if (bp != NULL)                          if (bp != NULL)
                                 brelse(bp);                                  brelse(bp);
                         blkoff = offset & ~bmask;                          blkoff = offset & ~bmask;
                         if (VOP_BLKATOFF(vp, (off_t)blkoff, NULL, &bp) != 0)                          if (ufs_blkatoff(vp, (off_t)blkoff, NULL, &bp) != 0)
                                 return (EJUSTRETURN);                                  return (EJUSTRETURN);
                 }                  }
                 dp = (struct direct *)(bp->b_data + (offset & bmask));                  dp = (struct direct *)((char *)bp->b_data + (offset & bmask));
                 if (dp->d_reclen == 0 || dp->d_reclen >                  if (dp->d_reclen == 0 || dp->d_reclen >
                     dirblksiz - (offset & (dirblksiz - 1))) {                      dirblksiz - (offset & (dirblksiz - 1))) {
                         /* Corrupted directory. */                          /* Corrupted directory. */
Line 478  ufsdirhash_findfree(struct inode *ip, in
Line 480  ufsdirhash_findfree(struct inode *ip, in
         struct buf *bp;          struct buf *bp;
         doff_t pos, slotstart;          doff_t pos, slotstart;
         int dirblock, error, freebytes, i;          int dirblock, error, freebytes, i;
         const int needswap = UFS_MPNEEDSWAP(ip->i_ump);          const int needswap = UFS_MPNEEDSWAP(ip->i_ump);
         int dirblksiz = ip->i_ump->um_dirblksiz;          int dirblksiz = ip->i_ump->um_dirblksiz;
   
         if ((dh = ip->i_dirhash) == NULL)          if ((dh = ip->i_dirhash) == NULL)
Line 504  ufsdirhash_findfree(struct inode *ip, in
Line 506  ufsdirhash_findfree(struct inode *ip, in
             dh->dh_blkfree[dirblock] >= howmany(slotneeded, DIRALIGN));              dh->dh_blkfree[dirblock] >= howmany(slotneeded, DIRALIGN));
         DIRHASH_UNLOCK(dh);          DIRHASH_UNLOCK(dh);
         pos = dirblock * dirblksiz;          pos = dirblock * dirblksiz;
         error = VOP_BLKATOFF(ip->i_vnode, (off_t)pos, (void *)&dp, &bp);          error = ufs_blkatoff(ip->i_vnode, (off_t)pos, (void *)&dp, &bp);
         if (error)          if (error)
                 return (-1);                  return (-1);
         /* Find the first entry with free space. */          /* Find the first entry with free space. */
Line 780  ufsdirhash_dirtrunc(struct inode *ip, do
Line 782  ufsdirhash_dirtrunc(struct inode *ip, do
  * a directory block matches its actual contents. Panics if a mismatch   * a directory block matches its actual contents. Panics if a mismatch
  * is detected.   * is detected.
  *   *
  * On entry, `buf' should point to the start of an in-core   * On entry, `sbuf' should point to the start of an in-core
  * DIRBLKSIZ-sized directory block, and `offset' should contain the   * DIRBLKSIZ-sized directory block, and `offset' should contain the
  * offset from the start of the directory of that block.   * offset from the start of the directory of that block.
  */   */
 void  void
 ufsdirhash_checkblock(struct inode *ip, char *buf, doff_t offset)  ufsdirhash_checkblock(struct inode *ip, char *sbuf, doff_t offset)
 {  {
         struct dirhash *dh;          struct dirhash *dh;
         struct direct *dp;          struct direct *dp;
Line 810  ufsdirhash_checkblock(struct inode *ip, 
Line 812  ufsdirhash_checkblock(struct inode *ip, 
   
         nfree = 0;          nfree = 0;
         for (i = 0; i < dirblksiz; i += dp->d_reclen) {          for (i = 0; i < dirblksiz; i += dp->d_reclen) {
                 dp = (struct direct *)(buf + i);                  dp = (struct direct *)(sbuf + i);
                 if (dp->d_reclen == 0 || i + dp->d_reclen > dirblksiz)                  if (dp->d_reclen == 0 || i + dp->d_reclen > dirblksiz)
                         panic("ufsdirhash_checkblock: bad dir");                          panic("ufsdirhash_checkblock: bad dir");
   
Line 1057  ufsdirhash_init()
Line 1059  ufsdirhash_init()
 }  }
   
 void  void
 ufsdirhash_done()  ufsdirhash_done(void)
 {  {
         KASSERT(TAILQ_EMPTY(&ufsdirhash_list));          KASSERT(TAILQ_EMPTY(&ufsdirhash_list));
 #ifdef _LKM  #ifdef _LKM
Line 1067  ufsdirhash_done()
Line 1069  ufsdirhash_done()
   
 SYSCTL_SETUP(sysctl_vfs_ufs_setup, "sysctl vfs.ufs.dirhash subtree setup")  SYSCTL_SETUP(sysctl_vfs_ufs_setup, "sysctl vfs.ufs.dirhash subtree setup")
 {  {
         struct sysctlnode *rnode, *cnode;          const struct sysctlnode *rnode, *cnode;
   
         sysctl_createv(clog, 0, NULL, &rnode,          sysctl_createv(clog, 0, NULL, &rnode,
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
Line 1117  SYSCTL_SETUP(sysctl_vfs_ufs_setup, "sysc
Line 1119  SYSCTL_SETUP(sysctl_vfs_ufs_setup, "sysc
                        NULL, 0, &ufs_dirhashcheck, 0,                         NULL, 0, &ufs_dirhashcheck, 0,
                        CTL_CREATE, CTL_EOL);                         CTL_CREATE, CTL_EOL);
 }  }
   
 #endif /* UFS_DIRHASH */  

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.12.2.1

CVSweb <webmaster@jp.NetBSD.org>