From e66295e5e578267d488a98387f2f29f38d7242e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 26 Jul 2009 14:01:27 +0000 Subject: [PATCH] * The inode may actually not be known when calling _RemoveInvalidNode(), this could cause a KDL. * Added a "force" argument to Inode::Remove() which should make it remove inodes more reliably for checkfs. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31773 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp | 9 +++++---- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 6 +++--- src/add-ons/kernel/file_systems/bfs/Inode.h | 3 ++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index d152fe7c67..4e5637c5e2 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -1428,7 +1428,7 @@ BlockAllocator::CheckNextNode(check_control* control) control->errors |= BFS_COULD_NOT_OPEN; if ((control->flags & BFS_REMOVE_INVALID) != 0) - status = _RemoveInvalidNode(cookie->parent, inode, name); + status = _RemoveInvalidNode(cookie->parent, NULL, name); else status = B_ERROR; @@ -1500,9 +1500,10 @@ BlockAllocator::_RemoveInvalidNode(Inode* parent, Inode* inode, // the bitmap anyway Transaction transaction(fVolume, parent->BlockNumber()); - inode->Node().flags |= HOST_ENDIAN_TO_BFS_INT32(INODE_DONT_FREE_SPACE); - status_t status - = parent->Remove(transaction, name, NULL, inode->IsContainer()); + 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); if (status == B_OK) transaction.Done(); diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 3ae8b57e44..7da6173b0b 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -2333,7 +2333,7 @@ Inode::Sync() status_t Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, - bool isDirectory) + bool isDirectory, bool force) { BPlusTree* tree; if (GetTree(&tree) != B_OK) @@ -2364,7 +2364,7 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, // bit is set for indices in BFS, not for attribute directories) - but you // should really be able to do whatever you want with your indices // without having to remove all files first :) - if (!inode->IsIndex()) { + if (!inode->IsIndex() && !force) { // if it's not of the correct type, don't delete it! if (inode->IsContainer() != isDirectory) return isDirectory ? B_NOT_A_DIRECTORY : B_IS_A_DIRECTORY; @@ -2379,7 +2379,7 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, if (status != B_OK) return status; - if (tree->Remove(transaction, name, id) < B_OK) { + if (tree->Remove(transaction, name, id) != B_OK && !force) { unremove_vnode(fVolume->FSVolume(), id); RETURN_ERROR(B_ERROR); } diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index cfdfa3c214..3e7ee41316 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -142,7 +142,8 @@ public: // create/remove inodes status_t Remove(Transaction& transaction, const char* name, - ino_t* _id = NULL, bool isDirectory = false); + ino_t* _id = NULL, bool isDirectory = false, + bool force = false); static status_t Create(Transaction& transaction, Inode* parent, const char* name, int32 mode, int openMode, uint32 type, bool* _created = NULL,