* 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
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2008, Axel Dörfler, [email protected].
|
* Copyright 2001-2009, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef B_PLUS_TREE_H
|
#ifndef B_PLUS_TREE_H
|
||||||
@@ -308,6 +308,8 @@ public:
|
|||||||
uint16* duplicate = NULL);
|
uint16* duplicate = NULL);
|
||||||
void SkipDuplicates();
|
void SkipDuplicates();
|
||||||
|
|
||||||
|
BPlusTree* Tree() const { return fTree; }
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void Dump();
|
void Dump();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -169,10 +169,10 @@ struct check_cookie {
|
|||||||
check_cookie() {}
|
check_cookie() {}
|
||||||
|
|
||||||
block_run current;
|
block_run current;
|
||||||
Inode *parent;
|
Inode* parent;
|
||||||
mode_t parent_mode;
|
mode_t parent_mode;
|
||||||
Stack<block_run> stack;
|
Stack<block_run> stack;
|
||||||
TreeIterator *iterator;
|
TreeIterator* iterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1427,9 +1427,10 @@ BlockAllocator::CheckNextNode(check_control* control)
|
|||||||
FATAL(("Could not open inode ID %Ld!\n", id));
|
FATAL(("Could not open inode ID %Ld!\n", id));
|
||||||
control->errors |= BFS_COULD_NOT_OPEN;
|
control->errors |= BFS_COULD_NOT_OPEN;
|
||||||
|
|
||||||
if ((control->flags & BFS_REMOVE_INVALID) != 0)
|
if ((control->flags & BFS_REMOVE_INVALID) != 0) {
|
||||||
status = _RemoveInvalidNode(cookie->parent, NULL, name);
|
status = _RemoveInvalidNode(cookie->parent,
|
||||||
else
|
cookie->iterator->Tree(), NULL, name);
|
||||||
|
} else
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
|
|
||||||
control->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 we are allowed to fix errors, we should remove the file
|
||||||
if ((control->flags & BFS_REMOVE_WRONG_TYPES) != 0
|
if ((control->flags & BFS_REMOVE_WRONG_TYPES) != 0
|
||||||
&& (control->flags & BFS_FIX_BITMAP_ERRORS) != 0)
|
&& (control->flags & BFS_FIX_BITMAP_ERRORS) != 0) {
|
||||||
status = _RemoveInvalidNode(cookie->parent, inode, name);
|
status = _RemoveInvalidNode(cookie->parent, NULL, inode,
|
||||||
else
|
name);
|
||||||
|
} else
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
|
|
||||||
control->errors |= BFS_WRONG_TYPE;
|
control->errors |= BFS_WRONG_TYPE;
|
||||||
@@ -1491,7 +1493,7 @@ BlockAllocator::CheckNextNode(check_control* control)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BlockAllocator::_RemoveInvalidNode(Inode* parent, Inode* inode,
|
BlockAllocator::_RemoveInvalidNode(Inode* parent, BPlusTree* tree, Inode* inode,
|
||||||
const char* name)
|
const char* name)
|
||||||
{
|
{
|
||||||
// it's safe to start a transaction, because Inode::Remove()
|
// 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
|
// if we set the INODE_DONT_FREE_SPACE flag - since we fix
|
||||||
// the bitmap anyway
|
// the bitmap anyway
|
||||||
Transaction transaction(fVolume, parent->BlockNumber());
|
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);
|
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)
|
if (status == B_OK)
|
||||||
transaction.Done();
|
transaction.Done();
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
class AllocationGroup;
|
class AllocationGroup;
|
||||||
|
class BPlusTree;
|
||||||
|
class Inode;
|
||||||
class Transaction;
|
class Transaction;
|
||||||
class Volume;
|
class Volume;
|
||||||
class Inode;
|
|
||||||
struct disk_super_block;
|
struct disk_super_block;
|
||||||
struct block_run;
|
struct block_run;
|
||||||
struct check_control;
|
struct check_control;
|
||||||
@@ -64,8 +65,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _RemoveInvalidNode(Inode* parent, Inode* inode,
|
status_t _RemoveInvalidNode(Inode* parent, BPlusTree* tree,
|
||||||
const char* name);
|
Inode* inode, const char* name);
|
||||||
#ifdef DEBUG_ALLOCATION_GROUPS
|
#ifdef DEBUG_ALLOCATION_GROUPS
|
||||||
void _CheckGroup(int32 group) const;
|
void _CheckGroup(int32 group) const;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user