From 64e0d0841b2276f67a953dd09e900743b7cb5a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 2 Jan 2009 10:59:47 +0000 Subject: [PATCH] * Inodes are no longer trimmed from the checking thread. This should fix bug #3190. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28845 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../file_systems/bfs/BlockAllocator.cpp | 3 +++ .../kernel/file_systems/bfs/Volume.cpp | 3 ++- src/add-ons/kernel/file_systems/bfs/Volume.h | 5 +++++ src/add-ons/kernel/file_systems/bfs/bfs.h | 5 +++-- .../file_systems/bfs/kernel_interface.cpp | 19 ++++++++++++------- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index bc1dbf1c6a..979d2d775b 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -1242,6 +1242,8 @@ BlockAllocator::StopChecking(check_control* control) } else FATAL(("BlockAllocator::CheckNextNode() didn't run through\n")); + fVolume->SetCheckingThread(-1); + free(fCheckBitmap); fCheckBitmap = NULL; fCheckCookie = NULL; @@ -1260,6 +1262,7 @@ BlockAllocator::CheckNextNode(check_control* control) return B_BAD_VALUE; check_cookie* cookie = (check_cookie*)control->cookie; + fVolume->SetCheckingThread(find_thread(NULL)); while (true) { if (cookie->iterator == NULL) { diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 23ad69c016..6307b8e12d 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -280,7 +280,8 @@ Volume::Volume(fs_volume* volume) fIndicesNode(NULL), fDirtyCachedBlocks(0), fUniqueID(0), - fFlags(0) + fFlags(0), + fCheckingThread(-1) { mutex_init(&fLock, "bfs volume"); mutex_init(&fQueryLock, "bfs queries"); diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index 2ee013e006..7a803277b7 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -98,6 +98,10 @@ public: off_t numBlocks, block_run& run, uint16 minimum = 1); status_t Free(Transaction& transaction, block_run run); + void SetCheckingThread(thread_id thread) + { fCheckingThread = thread; } + bool IsCheckingThread() const + { return find_thread(NULL) == fCheckingThread; } // cache access status_t WriteSuperBlock(); @@ -150,6 +154,7 @@ public: uint32 fFlags; void* fBlockCache; + thread_id fCheckingThread; }; diff --git a/src/add-ons/kernel/file_systems/bfs/bfs.h b/src/add-ons/kernel/file_systems/bfs/bfs.h index c8c3135436..aaa84e1f47 100644 --- a/src/add-ons/kernel/file_systems/bfs/bfs.h +++ b/src/add-ons/kernel/file_systems/bfs/bfs.h @@ -222,8 +222,9 @@ enum inode_flags { INODE_PERMANENT_FLAGS = 0x0000ffff, INODE_WAS_WRITTEN = 0x00020000, - INODE_DONT_FREE_SPACE = 0x00080000, // only used by the "chkbfs" functionality - INODE_CHKBFS_RUNNING = 0x00200000, + // The rest is only used by the file system check functionality + INODE_DONT_FREE_SPACE = 0x00080000, + INODE_CHECK_RUNNING = 0x00200000 }; //************************************** diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 6b491eb32e..3d04461289 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -303,7 +303,8 @@ bfs_put_vnode(fs_volume* _volume, fs_vnode* _node, bool reenter) // since a directory's size can be changed without having it opened, // we need to take care about their preallocated blocks here - if (!volume->IsReadOnly() && inode->NeedsTrimming()) { + if (!volume->IsReadOnly() && !volume->IsCheckingThread() + && inode->NeedsTrimming()) { Transaction transaction(volume, inode->BlockNumber()); if (inode->TrimPreallocation(transaction) == B_OK) @@ -600,8 +601,10 @@ bfs_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, ulong cmd, check_control* control = (check_control*)buffer; status_t status = allocator.StartChecking(control); - if (status == B_OK) - inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_CHKBFS_RUNNING); + if (status == B_OK) { + inode->Node().flags + |= HOST_ENDIAN_TO_BFS_INT32(INODE_CHECK_RUNNING); + } return status; } @@ -612,8 +615,10 @@ bfs_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, ulong cmd, check_control* control = (check_control*)buffer; status_t status = allocator.StopChecking(control); - if (status == B_OK) - inode->Node().flags &= HOST_ENDIAN_TO_BFS_INT32(~INODE_CHKBFS_RUNNING); + if (status == B_OK) { + inode->Node().flags + &= HOST_ENDIAN_TO_BFS_INT32(~INODE_CHECK_RUNNING); + } return status; } @@ -1314,7 +1319,7 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) Transaction transaction; bool needsTrimming = false; - if (!volume->IsReadOnly()) { + if (!volume->IsReadOnly() && !volume->IsCheckingThread()) { InodeReadLocker locker(inode); needsTrimming = inode->NeedsTrimming(); @@ -1376,7 +1381,7 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie) if (status == B_OK) transaction.Done(); - if (inode->Flags() & INODE_CHKBFS_RUNNING) { + if ((inode->Flags() & INODE_CHECK_RUNNING) != 0) { // "chkbfs" exited abnormally, so we have to stop it here... FATAL(("check process was aborted!\n")); volume->Allocator().StopChecking(NULL);