[BACK]Return to msdosfs_denode.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / msdosfs

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

Diff for /src/sys/fs/msdosfs/msdosfs_denode.c between version 1.8.2.6 and 1.8.2.7

version 1.8.2.6, 2007/12/07 17:31:57 version 1.8.2.7, 2008/01/21 09:45:47
Line 76  u_long dehash;   /* size of hash table -
Line 76  u_long dehash;   /* size of hash table -
 #define DEHASH(dev, dcl, doff) \  #define DEHASH(dev, dcl, doff) \
     (((dev) + (dcl) + (doff) / sizeof(struct direntry)) & dehash)      (((dev) + (dcl) + (doff) / sizeof(struct direntry)) & dehash)
   
 struct simplelock msdosfs_ihash_slock;  kmutex_t msdosfs_ihash_lock;
   kmutex_t msdosfs_hashlock;
   
 struct pool msdosfs_denode_pool;  struct pool msdosfs_denode_pool;
   
Line 89  static const struct genfs_ops msdosfs_ge
Line 90  static const struct genfs_ops msdosfs_ge
         .gop_markupdate = msdosfs_gop_markupdate,          .gop_markupdate = msdosfs_gop_markupdate,
 };  };
   
 static struct denode *msdosfs_hashget(dev_t, u_long, u_long);  static struct denode *msdosfs_hashget(dev_t, u_long, u_long, int);
 static void msdosfs_hashins(struct denode *);  static void msdosfs_hashins(struct denode *);
 static void msdosfs_hashrem(struct denode *);  static void msdosfs_hashrem(struct denode *);
   
Line 106  msdosfs_init()
Line 107  msdosfs_init()
             "msdosnopl", &pool_allocator_nointr, IPL_NONE);              "msdosnopl", &pool_allocator_nointr, IPL_NONE);
         dehashtbl = hashinit(desiredvnodes / 2, HASH_LIST, M_MSDOSFSMNT,          dehashtbl = hashinit(desiredvnodes / 2, HASH_LIST, M_MSDOSFSMNT,
             M_WAITOK, &dehash);              M_WAITOK, &dehash);
         simple_lock_init(&msdosfs_ihash_slock);          mutex_init(&msdosfs_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
           mutex_init(&msdosfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
 }  }
   
 /*  /*
Line 124  msdosfs_reinit()
Line 126  msdosfs_reinit()
         hash = hashinit(desiredvnodes / 2, HASH_LIST, M_MSDOSFSMNT, M_WAITOK,          hash = hashinit(desiredvnodes / 2, HASH_LIST, M_MSDOSFSMNT, M_WAITOK,
             &mask);              &mask);
   
         simple_lock(&msdosfs_ihash_slock);          mutex_enter(&msdosfs_ihash_lock);
         oldhash = dehashtbl;          oldhash = dehashtbl;
         oldmask = dehash;          oldmask = dehash;
         dehashtbl = hash;          dehashtbl = hash;
Line 137  msdosfs_reinit()
Line 139  msdosfs_reinit()
                         LIST_INSERT_HEAD(&hash[val], dep, de_hash);                          LIST_INSERT_HEAD(&hash[val], dep, de_hash);
                 }                  }
         }          }
         simple_unlock(&msdosfs_ihash_slock);          mutex_exit(&msdosfs_ihash_lock);
         hashdone(oldhash, M_MSDOSFSMNT);          hashdone(oldhash, M_MSDOSFSMNT);
 }  }
   
Line 146  msdosfs_done()
Line 148  msdosfs_done()
 {  {
         hashdone(dehashtbl, M_MSDOSFSMNT);          hashdone(dehashtbl, M_MSDOSFSMNT);
         pool_destroy(&msdosfs_denode_pool);          pool_destroy(&msdosfs_denode_pool);
           mutex_destroy(&msdosfs_ihash_lock);
           mutex_destroy(&msdosfs_hashlock);
         malloc_type_detach(M_MSDOSFSTMP);          malloc_type_detach(M_MSDOSFSTMP);
         malloc_type_detach(M_MSDOSFSFAT);          malloc_type_detach(M_MSDOSFSFAT);
         malloc_type_detach(M_MSDOSFSMNT);          malloc_type_detach(M_MSDOSFSMNT);
 }  }
   
 static struct denode *  static struct denode *
 msdosfs_hashget(dev, dirclust, diroff)  msdosfs_hashget(dev, dirclust, diroff, flags)
         dev_t dev;          dev_t dev;
         u_long dirclust;          u_long dirclust;
         u_long diroff;          u_long diroff;
           int flags;
 {  {
         struct denode *dep;          struct denode *dep;
         struct vnode *vp;          struct vnode *vp;
   
 loop:  loop:
         simple_lock(&msdosfs_ihash_slock);          mutex_enter(&msdosfs_ihash_lock);
         LIST_FOREACH(dep, &dehashtbl[DEHASH(dev, dirclust, diroff)], de_hash) {          LIST_FOREACH(dep, &dehashtbl[DEHASH(dev, dirclust, diroff)], de_hash) {
                 if (dirclust == dep->de_dirclust &&                  if (dirclust == dep->de_dirclust &&
                     diroff == dep->de_diroffset &&                      diroff == dep->de_diroffset &&
                     dev == dep->de_dev &&                      dev == dep->de_dev &&
                     dep->de_refcnt != 0) {                      dep->de_refcnt != 0) {
                         vp = DETOV(dep);                          vp = DETOV(dep);
                         simple_lock(&vp->v_interlock);                          if (flags == 0) {
                         simple_unlock(&msdosfs_ihash_slock);                                  mutex_exit(&msdosfs_ihash_lock);
                         if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))                          } else {
                                 goto loop;                                  mutex_enter(&vp->v_interlock);
                                   mutex_exit(&msdosfs_ihash_lock);
                                   if (vget(vp, flags | LK_INTERLOCK))
                                           goto loop;
                           }
                         return (dep);                          return (dep);
                 }                  }
         }          }
         simple_unlock(&msdosfs_ihash_slock);          mutex_exit(&msdosfs_ihash_lock);
         return (NULL);          return (NULL);
 }  }
   
Line 186  msdosfs_hashins(dep)
Line 195  msdosfs_hashins(dep)
         struct ihashhead *depp;          struct ihashhead *depp;
         int val;          int val;
   
         simple_lock(&msdosfs_ihash_slock);          KASSERT(mutex_owned(&msdosfs_hashlock));
   
           mutex_enter(&msdosfs_ihash_lock);
         val = DEHASH(dep->de_dev, dep->de_dirclust, dep->de_diroffset);          val = DEHASH(dep->de_dev, dep->de_dirclust, dep->de_diroffset);
         depp = &dehashtbl[val];          depp = &dehashtbl[val];
         LIST_INSERT_HEAD(depp, dep, de_hash);          LIST_INSERT_HEAD(depp, dep, de_hash);
         simple_unlock(&msdosfs_ihash_slock);          mutex_exit(&msdosfs_ihash_lock);
 }  }
   
 static void  static void
 msdosfs_hashrem(dep)  msdosfs_hashrem(dep)
         struct denode *dep;          struct denode *dep;
 {  {
         simple_lock(&msdosfs_ihash_slock);          mutex_enter(&msdosfs_ihash_lock);
         LIST_REMOVE(dep, de_hash);          LIST_REMOVE(dep, de_hash);
         simple_unlock(&msdosfs_ihash_slock);          mutex_exit(&msdosfs_ihash_lock);
 }  }
   
 /*  /*
Line 252  deget(pmp, dirclust, diroffset, depp)
Line 263  deget(pmp, dirclust, diroffset, depp)
          * entry that represented the file happens to be reused while the           * entry that represented the file happens to be reused while the
          * deleted file is still open.           * deleted file is still open.
          */           */
         ldep = msdosfs_hashget(pmp->pm_dev, dirclust, diroffset);   retry:
           ldep = msdosfs_hashget(pmp->pm_dev, dirclust, diroffset, LK_EXCLUSIVE);
         if (ldep) {          if (ldep) {
                 *depp = ldep;                  *depp = ldep;
                 return (0);                  return (0);
Line 270  deget(pmp, dirclust, diroffset, depp)
Line 282  deget(pmp, dirclust, diroffset, depp)
                 return (error);                  return (error);
         }          }
         ldep = pool_get(&msdosfs_denode_pool, PR_WAITOK);          ldep = pool_get(&msdosfs_denode_pool, PR_WAITOK);
   
           /*
            * If someone beat us to it, put back the freshly allocated
            * vnode/inode pair and retry.
            */
           mutex_enter(&msdosfs_hashlock);
           if (msdosfs_hashget(pmp->pm_dev, dirclust, diroffset, 0)) {
                   mutex_exit(&msdosfs_hashlock);
                   ungetnewvnode(nvp);
                   pool_put(&msdosfs_denode_pool, ldep);
                   goto retry;
           }
         memset(ldep, 0, sizeof *ldep);          memset(ldep, 0, sizeof *ldep);
         nvp->v_data = ldep;          nvp->v_data = ldep;
         ldep->de_vnode = nvp;          ldep->de_vnode = nvp;
Line 289  deget(pmp, dirclust, diroffset, depp)
Line 313  deget(pmp, dirclust, diroffset, depp)
         vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);          vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
         genfs_node_init(nvp, &msdosfs_genfsops);          genfs_node_init(nvp, &msdosfs_genfsops);
         msdosfs_hashins(ldep);          msdosfs_hashins(ldep);
           mutex_exit(&msdosfs_hashlock);
   
         ldep->de_pmp = pmp;          ldep->de_pmp = pmp;
         ldep->de_devvp = pmp->pm_devvp;          ldep->de_devvp = pmp->pm_devvp;
Line 560  deextend(dep, length, cred)
Line 585  deextend(dep, length, cred)
                 }                  }
         }          }
   
           /*
            * Zero extend file range; uvm_vnp_zerorange() uses ubc_alloc() and a
            * memset(); we set the write size so ubc won't read in file data that
            * is zero'd later.
            */
         osize = dep->de_FileSize;          osize = dep->de_FileSize;
         dep->de_FileSize = length;          dep->de_FileSize = length;
         uvm_vnp_setsize(DETOV(dep), (voff_t)dep->de_FileSize);          uvm_vnp_setwritesize(DETOV(dep), (voff_t)dep->de_FileSize);
         dep->de_flag |= DE_UPDATE|DE_MODIFIED;          dep->de_flag |= DE_UPDATE|DE_MODIFIED;
         uvm_vnp_zerorange(DETOV(dep), (off_t)osize,          uvm_vnp_zerorange(DETOV(dep), (off_t)osize,
             (size_t)(dep->de_FileSize - osize));              (size_t)(dep->de_FileSize - osize));
           uvm_vnp_setsize(DETOV(dep), (voff_t)dep->de_FileSize);
         return (deupdat(dep, 1));          return (deupdat(dep, 1));
 }  }
   
Line 587  reinsert(dep)
Line 618  reinsert(dep)
          */           */
         if (dep->de_Attributes & ATTR_DIRECTORY)          if (dep->de_Attributes & ATTR_DIRECTORY)
                 return;                  return;
           mutex_enter(&msdosfs_hashlock);
         msdosfs_hashrem(dep);          msdosfs_hashrem(dep);
         msdosfs_hashins(dep);          msdosfs_hashins(dep);
           mutex_exit(&msdosfs_hashlock);
 }  }
   
 int  int
Line 606  msdosfs_reclaim(v)
Line 639  msdosfs_reclaim(v)
             dep, dep->de_Name, dep->de_refcnt);              dep, dep->de_Name, dep->de_refcnt);
 #endif  #endif
   
         if (prtactive && vp->v_usecount != 0)          if (prtactive && vp->v_usecount > 1)
                 vprint("msdosfs_reclaim(): pushing active", vp);                  vprint("msdosfs_reclaim(): pushing active", vp);
         /*          /*
          * Remove the denode from its hash chain.           * Remove the denode from its hash chain.
Line 635  msdosfs_inactive(v)
Line 668  msdosfs_inactive(v)
 {  {
         struct vop_inactive_args /* {          struct vop_inactive_args /* {
                 struct vnode *a_vp;                  struct vnode *a_vp;
                   bool *a_recycle;
         } */ *ap = v;          } */ *ap = v;
         struct vnode *vp = ap->a_vp;          struct vnode *vp = ap->a_vp;
         struct denode *dep = VTODE(vp);          struct denode *dep = VTODE(vp);
Line 644  msdosfs_inactive(v)
Line 678  msdosfs_inactive(v)
         printf("msdosfs_inactive(): dep %p, de_Name[0] %x\n", dep, dep->de_Name[0]);          printf("msdosfs_inactive(): dep %p, de_Name[0] %x\n", dep, dep->de_Name[0]);
 #endif  #endif
   
         if (prtactive && vp->v_usecount != 0)  
                 vprint("msdosfs_inactive(): pushing active", vp);  
   
         /*          /*
          * Get rid of denodes related to stale file handles.           * Get rid of denodes related to stale file handles.
          */           */
Line 671  msdosfs_inactive(v)
Line 702  msdosfs_inactive(v)
         }          }
         deupdat(dep, 0);          deupdat(dep, 0);
 out:  out:
         VOP_UNLOCK(vp, 0);  
         /*          /*
          * If we are done with the denode, reclaim it           * If we are done with the denode, reclaim it
          * so that it can be reused immediately.           * so that it can be reused immediately.
Line 680  out:
Line 710  out:
         printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n",          printf("msdosfs_inactive(): v_usecount %d, de_Name[0] %x\n",
                 vp->v_usecount, dep->de_Name[0]);                  vp->v_usecount, dep->de_Name[0]);
 #endif  #endif
         if (dep->de_Name[0] == SLOT_DELETED)          *ap->a_recycle = (dep->de_Name[0] == SLOT_DELETED);
                 vrecycle(vp, (struct simplelock *)0, curlwp);          VOP_UNLOCK(vp, 0);
         return (error);          return (error);
 }  }
   

Legend:
Removed from v.1.8.2.6  
changed lines
  Added in v.1.8.2.7

CVSweb <webmaster@jp.NetBSD.org>