[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.27 and 1.36.6.1

version 1.27, 2008/07/03 09:56:15 version 1.36.6.1, 2015/04/06 15:18:33
Line 140  ufsdirhash_build(struct inode *ip)
Line 140  ufsdirhash_build(struct inode *ip)
         }          }
   
         /* Don't hash removed directories. */          /* Don't hash removed directories. */
         if (ip->i_ffs_effnlink == 0)          if (ip->i_nlink == 0)
                 return (-1);                  return (-1);
   
         vp = ip->i_vnode;          vp = ip->i_vnode;
         /* Allocate 50% more entries than this dir size could ever need. */          /* Allocate 50% more entries than this dir size could ever need. */
         KASSERT(ip->i_size >= dirblksiz);          KASSERT(ip->i_size >= dirblksiz);
         nslots = ip->i_size / DIRECTSIZ(1);          nslots = ip->i_size / UFS_DIRECTSIZ(1);
         nslots = (nslots * 3 + 1) / 2;          nslots = (nslots * 3 + 1) / 2;
         narrays = howmany(nslots, DH_NBLKOFF);          narrays = howmany(nslots, DH_NBLKOFF);
         nslots = narrays * DH_NBLKOFF;          nslots = narrays * DH_NBLKOFF;
Line 239  ufsdirhash_build(struct inode *ip)
Line 239  ufsdirhash_build(struct inode *ip)
                                 slot = WRAPINCR(slot, dh->dh_hlen);                                  slot = WRAPINCR(slot, dh->dh_hlen);
                         dh->dh_hused++;                          dh->dh_hused++;
                         DH_ENTRY(dh, slot) = pos;                          DH_ENTRY(dh, slot) = pos;
                         ufsdirhash_adjfree(dh, pos, -DIRSIZ(0, ep, needswap),                          ufsdirhash_adjfree(dh, pos, -UFS_DIRSIZ(0, ep, needswap),
                             dirblksiz);                              dirblksiz);
                 }                  }
                 pos += ep->d_reclen;                  pos += ep->d_reclen;
Line 255  ufsdirhash_build(struct inode *ip)
Line 255  ufsdirhash_build(struct inode *ip)
         return (0);          return (0);
   
 fail:  fail:
           ip->i_dirhash = NULL;
         DIRHASH_UNLOCK(dh);          DIRHASH_UNLOCK(dh);
         if (dh->dh_hash != NULL) {          if (dh->dh_hash != NULL) {
                 for (i = 0; i < narrays; i++)                  for (i = 0; i < narrays; i++)
Line 266  fail:
Line 267  fail:
                 kmem_free(dh->dh_blkfree, dh->dh_blkfreesz);                  kmem_free(dh->dh_blkfree, dh->dh_blkfreesz);
         mutex_destroy(&dh->dh_lock);          mutex_destroy(&dh->dh_lock);
         pool_cache_put(ufsdirhash_cache, dh);          pool_cache_put(ufsdirhash_cache, dh);
         ip->i_dirhash = NULL;  
         atomic_add_int(&ufs_dirhashmem, -memreqd);          atomic_add_int(&ufs_dirhashmem, -memreqd);
         return (-1);          return (-1);
 }  }
Line 283  ufsdirhash_free(struct inode *ip)
Line 283  ufsdirhash_free(struct inode *ip)
         if ((dh = ip->i_dirhash) == NULL)          if ((dh = ip->i_dirhash) == NULL)
                 return;                  return;
   
           ip->i_dirhash = NULL;
   
         if (dh->dh_onlist) {          if (dh->dh_onlist) {
                 DIRHASHLIST_LOCK();                  DIRHASHLIST_LOCK();
                 if (dh->dh_onlist)                  if (dh->dh_onlist)
Line 303  ufsdirhash_free(struct inode *ip)
Line 305  ufsdirhash_free(struct inode *ip)
         }          }
         mutex_destroy(&dh->dh_lock);          mutex_destroy(&dh->dh_lock);
         pool_cache_put(ufsdirhash_cache, dh);          pool_cache_put(ufsdirhash_cache, dh);
         ip->i_dirhash = NULL;  
   
         atomic_add_int(&ufs_dirhashmem, -mem);          atomic_add_int(&ufs_dirhashmem, -mem);
 }  }
Line 316  ufsdirhash_free(struct inode *ip)
Line 317  ufsdirhash_free(struct inode *ip)
  * If successful, the directory offset is stored in *offp, and a   * If successful, the directory offset is stored in *offp, and a
  * pointer to a struct buf containing the entry is stored in *bpp. If   * pointer to a struct buf containing the entry is stored in *bpp. If
  * prevoffp is non-NULL, the offset of the previous entry within   * prevoffp is non-NULL, the offset of the previous entry within
  * the DIRBLKSIZ-sized block is stored in *prevoffp (if the entry   * the UFS_DIRBLKSIZ-sized block is stored in *prevoffp (if the entry
  * is the first in a block, the start of the block is used).   * is the first in a block, the start of the block is used).
  */   */
 int  int
Line 416  restart:
Line 417  restart:
                                 brelse(bp, 0);                                  brelse(bp, 0);
                         blkoff = offset & ~bmask;                          blkoff = offset & ~bmask;
                         if (ufs_blkatoff(vp, (off_t)blkoff,                          if (ufs_blkatoff(vp, (off_t)blkoff,
                             NULL, &bp, true) != 0) {                              NULL, &bp, false) != 0) {
                                 DIRHASH_UNLOCK(dh);                                  DIRHASH_UNLOCK(dh);
                                 return (EJUSTRETURN);                                  return (EJUSTRETURN);
                         }                          }
Line 430  restart:
Line 431  restart:
                         return (EJUSTRETURN);                          return (EJUSTRETURN);
                 }                  }
                 if (dp->d_namlen == namelen &&                  if (dp->d_namlen == namelen &&
                     bcmp(dp->d_name, name, namelen) == 0) {                      memcmp(dp->d_name, name, namelen) == 0) {
                         /* Found. Get the prev offset if needed. */                          /* Found. Get the prev offset if needed. */
                         if (prevoffp != NULL) {                          if (prevoffp != NULL) {
                                 if (offset & (dirblksiz - 1)) {                                  if (offset & (dirblksiz - 1)) {
Line 448  restart:
Line 449  restart:
                         /* Check for sequential access, and update offset. */                          /* Check for sequential access, and update offset. */
                         if (dh->dh_seqopt == 0 && dh->dh_seqoff == offset)                          if (dh->dh_seqopt == 0 && dh->dh_seqoff == offset)
                                 dh->dh_seqopt = 1;                                  dh->dh_seqopt = 1;
                         dh->dh_seqoff = offset + DIRSIZ(0, dp, needswap);                          dh->dh_seqoff = offset + UFS_DIRSIZ(0, dp, needswap);
                         DIRHASH_UNLOCK(dh);                          DIRHASH_UNLOCK(dh);
   
                         *bpp = bp;                          *bpp = bp;
Line 483  restart:
Line 484  restart:
  * the offset of the directory entry that begins the free space.   * the offset of the directory entry that begins the free space.
  * This will either be the offset of an existing entry that has free   * This will either be the offset of an existing entry that has free
  * space at the end, or the offset of an entry with d_ino == 0 at   * space at the end, or the offset of an entry with d_ino == 0 at
  * the start of a DIRBLKSIZ block.   * the start of a UFS_DIRBLKSIZ block.
  *   *
  * To use the space, the caller may need to compact existing entries in   * To use the space, the caller may need to compact existing entries in
  * the directory. The total number of bytes in all of the entries involved   * the directory. The total number of bytes in all of the entries involved
Line 540  ufsdirhash_findfree(struct inode *ip, in
Line 541  ufsdirhash_findfree(struct inode *ip, in
                         brelse(bp, 0);                          brelse(bp, 0);
                         return (-1);                          return (-1);
                 }                  }
                 if (dp->d_ino == 0 || dp->d_reclen > DIRSIZ(0, dp, needswap))                  if (dp->d_ino == 0 || dp->d_reclen > UFS_DIRSIZ(0, dp, needswap))
                         break;                          break;
                 i += dp->d_reclen;                  i += dp->d_reclen;
                 dp = (struct direct *)((char *)dp + dp->d_reclen);                  dp = (struct direct *)((char *)dp + dp->d_reclen);
Line 557  ufsdirhash_findfree(struct inode *ip, in
Line 558  ufsdirhash_findfree(struct inode *ip, in
         while (i < dirblksiz && freebytes < slotneeded) {          while (i < dirblksiz && freebytes < slotneeded) {
                 freebytes += dp->d_reclen;                  freebytes += dp->d_reclen;
                 if (dp->d_ino != 0)                  if (dp->d_ino != 0)
                         freebytes -= DIRSIZ(0, dp, needswap);                          freebytes -= UFS_DIRSIZ(0, dp, needswap);
                 if (dp->d_reclen == 0) {                  if (dp->d_reclen == 0) {
                         DIRHASH_UNLOCK(dh);                          DIRHASH_UNLOCK(dh);
                         brelse(bp, 0);                          brelse(bp, 0);
Line 655  ufsdirhash_add(struct inode *ip, struct 
Line 656  ufsdirhash_add(struct inode *ip, struct 
         DH_ENTRY(dh, slot) = offset;          DH_ENTRY(dh, slot) = offset;
   
         /* Update the per-block summary info. */          /* Update the per-block summary info. */
         ufsdirhash_adjfree(dh, offset, -DIRSIZ(0, dirp, needswap), dirblksiz);          ufsdirhash_adjfree(dh, offset, -UFS_DIRSIZ(0, dirp, needswap), dirblksiz);
         DIRHASH_UNLOCK(dh);          DIRHASH_UNLOCK(dh);
 }  }
   
Line 690  ufsdirhash_remove(struct inode *ip, stru
Line 691  ufsdirhash_remove(struct inode *ip, stru
         ufsdirhash_delslot(dh, slot);          ufsdirhash_delslot(dh, slot);
   
         /* Update the per-block summary info. */          /* Update the per-block summary info. */
         ufsdirhash_adjfree(dh, offset, DIRSIZ(0, dirp, needswap), dirblksiz);          ufsdirhash_adjfree(dh, offset, UFS_DIRSIZ(0, dirp, needswap), dirblksiz);
         DIRHASH_UNLOCK(dh);          DIRHASH_UNLOCK(dh);
 }  }
   
Line 724  ufsdirhash_move(struct inode *ip, struct
Line 725  ufsdirhash_move(struct inode *ip, struct
   
 /*  /*
  * Inform dirhash that the directory has grown by one block that   * Inform dirhash that the directory has grown by one block that
  * begins at offset (i.e. the new length is offset + DIRBLKSIZ).   * begins at offset (i.e. the new length is offset + UFS_DIRBLKSIZ).
  */   */
 void  void
 ufsdirhash_newblk(struct inode *ip, doff_t offset)  ufsdirhash_newblk(struct inode *ip, doff_t offset)
Line 868  ufsdirhash_checkblock(struct inode *ip, 
Line 869  ufsdirhash_checkblock(struct inode *ip, 
                 /* Check that the entry exists (will panic if it doesn't). */                  /* Check that the entry exists (will panic if it doesn't). */
                 ufsdirhash_findslot(dh, dp->d_name, dp->d_namlen, offset + i);                  ufsdirhash_findslot(dh, dp->d_name, dp->d_namlen, offset + i);
   
                 nfree += dp->d_reclen - DIRSIZ(0, dp, needswap);                  nfree += dp->d_reclen - UFS_DIRSIZ(0, dp, needswap);
         }          }
         if (i != dirblksiz)          if (i != dirblksiz)
                 panic("ufsdirhash_checkblock: bad dir end");                  panic("ufsdirhash_checkblock: bad dir end");
Line 1000  ufsdirhash_delslot(struct dirhash *dh, i
Line 1001  ufsdirhash_delslot(struct dirhash *dh, i
   
 /*  /*
  * Given a directory entry and its offset, find the offset of the   * Given a directory entry and its offset, find the offset of the
  * previous entry in the same DIRBLKSIZ-sized block. Returns an   * previous entry in the same UFS_DIRBLKSIZ-sized block. Returns an
  * offset, or -1 if there is no previous entry in the block or some   * offset, or -1 if there is no previous entry in the block or some
  * other problem occurred.   * other problem occurred.
  */   */
Line 1086  ufsdirhash_recycle(int wanted)
Line 1087  ufsdirhash_recycle(int wanted)
   
                 /* Account for the returned memory, and repeat if necessary. */                  /* Account for the returned memory, and repeat if necessary. */
                 DIRHASHLIST_LOCK();                  DIRHASHLIST_LOCK();
                 ufs_dirhashmem -= mem;                  atomic_add_int(&ufs_dirhashmem, -mem);
         }          }
         /* Success. */          /* Success. */
         return (0);          return (0);
Line 1099  ufsdirhash_sysctl_init(void)
Line 1100  ufsdirhash_sysctl_init(void)
   
         sysctl_createv(&ufsdirhash_sysctl_log, 0, NULL, &rnode,          sysctl_createv(&ufsdirhash_sysctl_log, 0, NULL, &rnode,
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
                        CTLTYPE_NODE, "vfs", NULL,  
                        NULL, 0, NULL, 0,  
                        CTL_VFS, CTL_EOL);  
   
         sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &rnode,  
                        CTLFLAG_PERMANENT,  
                        CTLTYPE_NODE, "ufs",                         CTLTYPE_NODE, "ufs",
                        SYSCTL_DESCR("ufs"),                         SYSCTL_DESCR("ufs"),
                        NULL, 0, NULL, 0,                         NULL, 0, NULL, 0,
                        CTL_CREATE, CTL_EOL);                         CTL_VFS, CTL_CREATE, CTL_EOL);
   
         sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &rnode,          sysctl_createv(&ufsdirhash_sysctl_log, 0, &rnode, &rnode,
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
Line 1147  ufsdirhash_sysctl_init(void)
Line 1142  ufsdirhash_sysctl_init(void)
 }  }
   
 void  void
 ufsdirhash_init()  ufsdirhash_init(void)
 {  {
   
         mutex_init(&ufsdirhash_lock, MUTEX_DEFAULT, IPL_NONE);          mutex_init(&ufsdirhash_lock, MUTEX_DEFAULT, IPL_NONE);

Legend:
Removed from v.1.27  
changed lines
  Added in v.1.36.6.1

CVSweb <webmaster@jp.NetBSD.org>