From b5a51254dc88420043623914ada12e2ab778611b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 26 Jul 2009 14:29:05 +0000 Subject: [PATCH] * Don't use Inode::Remove() when the inode could not be opened, because it actually relies on that. * Instead, _RemoveInvalidNode() now manipulates the parent tree manually. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31774 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/bfs/BPlusTree.h | 4 ++- .../file_systems/bfs/BlockAllocator.cpp | 35 +++++++++++++------ .../kernel/file_systems/bfs/BlockAllocator.h | 7 ++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.h b/src/add-ons/kernel/file_systems/bfs/BPlusTree.h index d6e12d718f..e3c36d8130 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.h +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ #ifndef B_PLUS_TREE_H @@ -308,6 +308,8 @@ public: uint16* duplicate = NULL); void SkipDuplicates(); + BPlusTree* Tree() const { return fTree; } + #ifdef DEBUG void Dump(); #endif diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 4e5637c5e2..d295a2e187 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -169,10 +169,10 @@ struct check_cookie { check_cookie() {} block_run current; - Inode *parent; + Inode* parent; mode_t parent_mode; Stack stack; - TreeIterator *iterator; + TreeIterator* iterator; }; @@ -1427,9 +1427,10 @@ BlockAllocator::CheckNextNode(check_control* control) FATAL(("Could not open inode ID %Ld!\n", id)); control->errors |= BFS_COULD_NOT_OPEN; - if ((control->flags & BFS_REMOVE_INVALID) != 0) - status = _RemoveInvalidNode(cookie->parent, NULL, name); - else + if ((control->flags & BFS_REMOVE_INVALID) != 0) { + status = _RemoveInvalidNode(cookie->parent, + cookie->iterator->Tree(), NULL, name); + } else status = B_ERROR; control->status = B_ERROR; @@ -1465,9 +1466,10 @@ BlockAllocator::CheckNextNode(check_control* control) // if we are allowed to fix errors, we should remove the file if ((control->flags & BFS_REMOVE_WRONG_TYPES) != 0 - && (control->flags & BFS_FIX_BITMAP_ERRORS) != 0) - status = _RemoveInvalidNode(cookie->parent, inode, name); - else + && (control->flags & BFS_FIX_BITMAP_ERRORS) != 0) { + status = _RemoveInvalidNode(cookie->parent, NULL, inode, + name); + } else status = B_ERROR; control->errors |= BFS_WRONG_TYPE; @@ -1491,7 +1493,7 @@ BlockAllocator::CheckNextNode(check_control* control) status_t -BlockAllocator::_RemoveInvalidNode(Inode* parent, Inode* inode, +BlockAllocator::_RemoveInvalidNode(Inode* parent, BPlusTree* tree, Inode* inode, const char* name) { // it's safe to start a transaction, because Inode::Remove() @@ -1499,11 +1501,22 @@ BlockAllocator::_RemoveInvalidNode(Inode* parent, Inode* inode, // if we set the INODE_DONT_FREE_SPACE flag - since we fix // the bitmap anyway Transaction transaction(fVolume, parent->BlockNumber()); + status_t status; - if (inode != NULL) + if (inode != NULL) { inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_DONT_FREE_SPACE); - status_t status = parent->Remove(transaction, name, NULL, false, true); + status = parent->Remove(transaction, name, NULL, false, true); + } else { + parent->WriteLockInTransaction(transaction); + + // does the file even exist? + off_t id; + status = tree->Find((uint8*)name, (uint16)strlen(name), &id); + if (status == B_OK) + status = tree->Remove(transaction, name, id); + } + if (status == B_OK) transaction.Done(); diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h index 93fae1b2b1..383df9e068 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h @@ -10,9 +10,10 @@ class AllocationGroup; +class BPlusTree; +class Inode; class Transaction; class Volume; -class Inode; struct disk_super_block; struct block_run; struct check_control; @@ -64,8 +65,8 @@ public: #endif private: - status_t _RemoveInvalidNode(Inode* parent, Inode* inode, - const char* name); + status_t _RemoveInvalidNode(Inode* parent, BPlusTree* tree, + Inode* inode, const char* name); #ifdef DEBUG_ALLOCATION_GROUPS void _CheckGroup(int32 group) const; #endif