[haiku-commits] r34871 - haiku/trunk/src/system/kernel/fs

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 3 Jan 2010 14:54:23 +0100 (CET)

Author: bonefish
Date: 2010-01-03 14:54:22 +0100 (Sun, 03 Jan 2010)
New Revision: 34871
Changeset: http://dev.haiku-os.org/changeset/34871/haiku

Modified:
   haiku/trunk/src/system/kernel/fs/vfs.cpp
Log:
* free_unused_vnodes(): Be a good citizen and use vnode_used() instead of
  playing with the unused list manually. This also clears the vnode's unused
  flag, which wasn't done before and would thus cause corruption of the
  unused list a bit later.
* fs_unmount():
  - Fixed an iteration bug I introduced previously. The iterator would be
    advanced twice per iteration, leading to NULL pointer dereferencing
    when the vnode count was odd and skipping the checks for every other
    vnode.
  - All vnodes are going to be freed, so vnode_to_be_freed() has to invoked
    for every one of them. The code wasn't adjusted correctly when
    introducing the hot vnodes handling.
* Adjusted/improved some comments.


Modified: haiku/trunk/src/system/kernel/fs/vfs.cpp
===================================================================
--- haiku/trunk/src/system/kernel/fs/vfs.cpp    2010-01-03 13:33:20 UTC (rev 
34870)
+++ haiku/trunk/src/system/kernel/fs/vfs.cpp    2010-01-03 13:54:22 UTC (rev 
34871)
@@ -1075,8 +1075,8 @@
 
        In the second case the caller is responsible for dealing with the ref 
count
        0 -> 1 transition. That is 1. this function must not be invoked when the
-       node is busy in the first place and 2. the node must possibly be removed
-       from the unused node list and the unused node counter must be 
incremented.
+       node is busy in the first place and 2. vnode_used() must be called for 
the
+       node.
 
        \param vnode the vnode.
 */
@@ -1295,18 +1295,22 @@
                // lock the node
                AutoLocker<Vnode> nodeLocker(vnode);
 
-               // check whether the node is still unused
+               // Check whether the node is still unused -- since we only 
append to the
+               // the tail of the unused queue, the vnode should still be at 
its head.
+               // Alternatively we could check its ref count for 0 and its 
busy flag,
+               // but if the node is no longer at the head of the queue, it 
means it
+               // has been touched in the meantime, i.e. it is no longer the 
least
+               // recently used unused vnode and we rather don't free it.
                unusedVnodesLocker.Lock();
                if (vnode != list_get_first_item(&sUnusedVnodeList))
                        continue;
-
-               // remove it
-               list_remove_head_item(&sUnusedVnodeList);
-               sUnusedVnodes--;
                unusedVnodesLocker.Unlock();
 
+               ASSERT(!vnode->IsBusy());
+
                // grab a reference
                inc_vnode_ref_count(vnode);
+               vnode_used(vnode);
 
                // write back changes and free the node
                nodeLocker.Unlock();
@@ -7236,8 +7240,6 @@
                // make sure all of them are not busy or have refs on them
                VnodeList::Iterator iterator = mount->vnodes.GetIterator();
                while (struct vnode* vnode = iterator.Next()) {
-                       vnode = iterator.Next();
-
                        AutoLocker<Vnode> nodeLocker(vnode);
 
                        // The root vnode ref_count needs to be 1 here (the 
mount has a
@@ -7290,18 +7292,13 @@
        while (struct vnode* vnode = iterator.Next()) {
                AutoLocker<Vnode> nodeLocker(vnode);
                vnode->SetBusy(true);
-
-               if (vnode->ref_count == 0) {
-                       // this vnode has been unused before
-                       vnode_used(vnode);
-               }
+               vnode_to_be_freed(vnode);
        }
 
        // The ref_count of the root node is 1 at this point, see above why 
this is
        mount->root_vnode->Lock();
-       MutexLocker unusedVnodesLocker(sUnusedVnodesLock);
        mount->root_vnode->ref_count--;
-       unusedVnodesLocker.Unlock();
+       vnode_to_be_freed(mount->root_vnode);
        mount->root_vnode->Unlock();
 
        vnodesReadLocker.Unlock();


Other related posts:

  • » [haiku-commits] r34871 - haiku/trunk/src/system/kernel/fs - ingo_weinhold