* Replaced the Inode::GetTree() method with a simple getter - the tree is

always created for directories since quite some time now.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32158 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-08-06 11:18:26 +00:00
parent 134e1b04d4
commit 1a60fd72cf
7 changed files with 61 additions and 86 deletions
@@ -1369,8 +1369,8 @@ BlockAllocator::CheckNextNode(check_control* control)
// get iterator for the next directory // get iterator for the next directory
BPlusTree* tree; BPlusTree* tree = inode->Tree();
if (inode->GetTree(&tree) != B_OK) { if (tree == NULL) {
FATAL(("check: could not open b+tree from inode at %Ld\n", FATAL(("check: could not open b+tree from inode at %Ld\n",
fVolume->ToBlock(cookie->current))); fVolume->ToBlock(cookie->current)));
continue; continue;
@@ -293,9 +293,7 @@ dump_inode(int argc, char** argv)
kprintf("INODE %p\n", inode); kprintf("INODE %p\n", inode);
kprintf(" rw lock: %p\n", &inode->Lock()); kprintf(" rw lock: %p\n", &inode->Lock());
BPlusTree* tree = NULL; kprintf(" tree: %p\n", inode->Tree());
inode->GetTree(&tree);
kprintf(" tree: %p\n", tree);
kprintf(" file cache: %p\n", inode->FileCache()); kprintf(" file cache: %p\n", inode->FileCache());
kprintf(" file map: %p\n", inode->Map()); kprintf(" file map: %p\n", inode->Map());
kprintf(" old size: %Ld\n", inode->OldSize()); kprintf(" old size: %Ld\n", inode->OldSize());
@@ -76,8 +76,8 @@ Index::SetTo(const char* name)
InodeReadLocker locker(indices); InodeReadLocker locker(indices);
BPlusTree* tree; BPlusTree* tree = indices->Tree();
if (indices->GetTree(&tree) != B_OK) if (tree == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
ino_t id; ino_t id;
@@ -261,15 +261,16 @@ Index::Update(Transaction &transaction, const char* name, int32 type,
newKey, newLength); newKey, newLength);
} }
BPlusTree* tree; BPlusTree* tree = Node()->Tree();
status_t status = Node()->GetTree(&tree); if (tree == NULL)
if (status < B_OK) return B_BAD_VALUE;
return status;
// remove the old key from the tree // remove the old key from the tree
Node()->WriteLockInTransaction(transaction); Node()->WriteLockInTransaction(transaction);
status_t status = B_OK;
if (oldKey != NULL) { if (oldKey != NULL) {
status = tree->Remove(transaction, (const uint8*)oldKey, oldLength, status = tree->Remove(transaction, (const uint8*)oldKey, oldLength,
inode->ID()); inode->ID());
+25 -48
View File
@@ -1206,25 +1206,26 @@ Inode::GetAttribute(const char* name, Inode** _attribute)
return B_ERROR; return B_ERROR;
} }
BPlusTree* tree; BPlusTree* tree = attributes->Tree();
status_t status = attributes->GetTree(&tree); if (tree == NULL)
return B_BAD_VALUE;
InodeReadLocker locker(attributes);
ino_t id;
status_t status = tree->Find((uint8*)name, (uint16)strlen(name), &id);
if (status == B_OK) { if (status == B_OK) {
InodeReadLocker locker(attributes); Vnode vnode(fVolume, id);
Inode* inode;
// Check if the attribute is really an attribute
if (vnode.Get(&inode) != B_OK || !inode->IsAttribute())
return B_ERROR;
ino_t id; *_attribute = inode;
status = tree->Find((uint8*)name, (uint16)strlen(name), &id); vnode.Keep();
if (status == B_OK) { return B_OK;
Vnode vnode(fVolume, id);
Inode* inode;
// Check if the attribute is really an attribute
if (vnode.Get(&inode) < B_OK || !inode->IsAttribute())
return B_ERROR;
*_attribute = inode;
vnode.Keep();
return B_OK;
}
} }
return status; return status;
} }
@@ -1264,32 +1265,10 @@ Inode::CreateAttribute(Transaction& transaction, const char* name, uint32 type,
// #pragma mark - directory tree // #pragma mark - directory tree
/*! Gives the caller direct access to the b+tree for a given directory.
The tree is no longer created on demand, but when the inode is first
created. That will report any potential errors upfront, saves locking,
and should work as good (though a bit slower).
*/
status_t
Inode::GetTree(BPlusTree** tree)
{
if (fTree) {
*tree = fTree;
return B_OK;
}
RETURN_ERROR(B_BAD_VALUE);
}
bool bool
Inode::IsEmpty() Inode::IsEmpty()
{ {
BPlusTree* tree; TreeIterator iterator(fTree);
status_t status = GetTree(&tree);
if (status < B_OK)
return status;
TreeIterator iterator(tree);
// index and attribute directories are really empty when they are // index and attribute directories are really empty when they are
// empty - directories for standard files always contain ".", and // empty - directories for standard files always contain ".", and
@@ -2354,15 +2333,14 @@ status_t
Inode::Remove(Transaction& transaction, const char* name, ino_t* _id, Inode::Remove(Transaction& transaction, const char* name, ino_t* _id,
bool isDirectory, bool force) bool isDirectory, bool force)
{ {
BPlusTree* tree; if (fTree == NULL)
if (GetTree(&tree) != B_OK)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
WriteLockInTransaction(transaction); WriteLockInTransaction(transaction);
// does the file even exist? // does the file even exist?
off_t id; off_t id;
if (tree->Find((uint8*)name, (uint16)strlen(name), &id) < B_OK) if (fTree->Find((uint8*)name, (uint16)strlen(name), &id) < B_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
if (_id) if (_id)
@@ -2398,13 +2376,13 @@ Inode::Remove(Transaction& transaction, const char* name, ino_t* _id,
if (status != B_OK) if (status != B_OK)
return status; return status;
if (tree->Remove(transaction, name, id) != B_OK && !force) { if (fTree->Remove(transaction, name, id) != B_OK && !force) {
unremove_vnode(fVolume->FSVolume(), id); unremove_vnode(fVolume->FSVolume(), id);
RETURN_ERROR(B_ERROR); RETURN_ERROR(B_ERROR);
} }
#ifdef DEBUG #ifdef DEBUG
if (tree->Find((uint8*)name, (uint16)strlen(name), &id) == B_OK) { if (fTree->Find((uint8*)name, (uint16)strlen(name), &id) == B_OK) {
DIE(("deleted entry still there")); DIE(("deleted entry still there"));
} }
#endif #endif
@@ -2463,8 +2441,7 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
if (parent != NULL && (mode & S_ATTR_DIR) == 0 && parent->IsContainer()) { if (parent != NULL && (mode & S_ATTR_DIR) == 0 && parent->IsContainer()) {
// check if the file already exists in the directory // check if the file already exists in the directory
if (parent->GetTree(&tree) != B_OK) tree = parent->Tree();
RETURN_ERROR(B_BAD_VALUE);
} }
if (parent != NULL) { if (parent != NULL) {
@@ -2759,8 +2736,8 @@ AttributeIterator::GetNext(char* name, size_t* _length, uint32* _type,
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
BPlusTree* tree; BPlusTree* tree = fAttributes->Tree();
if (fAttributes->GetTree(&tree) < B_OK if (tree == NULL
|| (fIterator = new TreeIterator(tree)) == NULL) { || (fIterator = new TreeIterator(tree)) == NULL) {
FATAL(("could not get tree in AttributeIterator::GetNext(ino_t" FATAL(("could not get tree in AttributeIterator::GetNext(ino_t"
" = %Ld,name = \"%s\")\n", fInode->ID(), name)); " = %Ld,name = \"%s\")\n", fInode->ID(), name));
+1 -1
View File
@@ -119,7 +119,7 @@ public:
Inode** attribute); Inode** attribute);
// for directories only: // for directories only:
status_t GetTree(BPlusTree** _tree); BPlusTree* Tree() const { return fTree; }
bool IsEmpty(); bool IsEmpty();
status_t ContainerContentsChanged(Transaction& transaction); status_t ContainerContentsChanged(Transaction& transaction);
@@ -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. * This file may be used under the terms of the MIT License.
*/ */
@@ -931,20 +931,20 @@ Equation::PrepareQuery(Volume* /*volume*/, Index& index,
status_t status = index.SetTo(fAttribute); status_t status = index.SetTo(fAttribute);
// if we should query attributes without an index, we can just proceed here // if we should query attributes without an index, we can just proceed here
if (status < B_OK && !queryNonIndexed) if (status != B_OK && !queryNonIndexed)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
type_code type; type_code type;
// Special case for OP_UNEQUAL - it will always operate through the whole // Special case for OP_UNEQUAL - it will always operate through the whole
// index but we need the call to the original index to get the correct type // index but we need the call to the original index to get the correct type
if (status < B_OK || fOp == OP_UNEQUAL) { if (status != B_OK || fOp == OP_UNEQUAL) {
// Try to get an index that holds all files (name) // Try to get an index that holds all files (name)
// Also sets the default type for all attributes without index // Also sets the default type for all attributes without index
// to string. // to string.
type = status < B_OK ? B_STRING_TYPE : index.Type(); type = status < B_OK ? B_STRING_TYPE : index.Type();
if (index.SetTo("name") < B_OK) if (index.SetTo("name") != B_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
fHasIndex = false; fHasIndex = false;
@@ -956,8 +956,8 @@ Equation::PrepareQuery(Volume* /*volume*/, Index& index,
if (ConvertValue(type) < B_OK) if (ConvertValue(type) < B_OK)
return B_BAD_VALUE; return B_BAD_VALUE;
BPlusTree* tree; BPlusTree* tree = index.Node()->Tree();
if (index.Node()->GetTree(&tree) < B_OK) if (tree == NULL)
return B_ERROR; return B_ERROR;
*iterator = new TreeIterator(tree); *iterator = new TreeIterator(tree);
@@ -1033,7 +1033,7 @@ Equation::GetNextMatching(Volume* volume, TreeIterator* iterator,
status_t status = iterator->GetNextEntry(&indexValue, &keyLength, status_t status = iterator->GetNextEntry(&indexValue, &keyLength,
(uint16)sizeof(indexValue), &offset, &duplicate); (uint16)sizeof(indexValue), &offset, &duplicate);
if (status < B_OK) if (status != B_OK)
return status; return status;
// only compare against the index entry when this is the correct // only compare against the index entry when this is the correct
@@ -571,15 +571,15 @@ bfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* file,
// check access permissions // check access permissions
status_t status = directory->CheckPermissions(X_OK); status_t status = directory->CheckPermissions(X_OK);
if (status < B_OK) if (status != B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
BPlusTree* tree; BPlusTree* tree = directory->Tree();
if (directory->GetTree(&tree) != B_OK) if (tree == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
status = tree->Find((uint8*)file, (uint16)strlen(file), _vnodeID); status = tree->Find((uint8*)file, (uint16)strlen(file), _vnodeID);
if (status < B_OK) { if (status != B_OK) {
//PRINT(("bfs_walk() could not find %Ld:\"%s\": %s\n", directory->BlockNumber(), file, strerror(status))); //PRINT(("bfs_walk() could not find %Ld:\"%s\": %s\n", directory->BlockNumber(), file, strerror(status)));
return status; return status;
} }
@@ -1059,24 +1059,23 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
status_t status = oldDirectory->CheckPermissions(W_OK); status_t status = oldDirectory->CheckPermissions(W_OK);
if (status == B_OK) if (status == B_OK)
status = newDirectory->CheckPermissions(W_OK); status = newDirectory->CheckPermissions(W_OK);
if (status < B_OK) if (status != B_OK)
return status; return status;
// Get the directory's tree, and a pointer to the inode which should be // Get the directory's tree, and a pointer to the inode which should be
// changed // changed
BPlusTree* tree; BPlusTree* tree = oldDirectory->Tree();
status = oldDirectory->GetTree(&tree); if (tree == NULL)
if (status < B_OK) RETURN_ERROR(B_BAD_VALUE);
RETURN_ERROR(status);
off_t id; off_t id;
status = tree->Find((const uint8*)oldName, strlen(oldName), &id); status = tree->Find((const uint8*)oldName, strlen(oldName), &id);
if (status < B_OK) if (status != B_OK)
RETURN_ERROR(status); RETURN_ERROR(status);
Vnode vnode(volume, id); Vnode vnode(volume, id);
Inode* inode; Inode* inode;
if (vnode.Get(&inode) < B_OK) if (vnode.Get(&inode) != B_OK)
return B_IO_ERROR; return B_IO_ERROR;
// Don't move a directory into one of its children - we soar up // Don't move a directory into one of its children - we soar up
@@ -1096,7 +1095,7 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
Vnode vnode(volume, parent); Vnode vnode(volume, parent);
Inode* parentNode; Inode* parentNode;
if (vnode.Get(&parentNode) < B_OK) if (vnode.Get(&parentNode) != B_OK)
return B_ERROR; return B_ERROR;
parent = volume->ToVnode(parentNode->Parent()); parent = volume->ToVnode(parentNode->Parent());
@@ -1110,9 +1109,9 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
// failure, we will test this case first // failure, we will test this case first
BPlusTree* newTree = tree; BPlusTree* newTree = tree;
if (newDirectory != oldDirectory) { if (newDirectory != oldDirectory) {
status = newDirectory->GetTree(&newTree); newTree = newDirectory->Tree();
if (status < B_OK) if (newTree == NULL)
RETURN_ERROR(status); RETURN_ERROR(B_BAD_VALUE);
} }
status = newTree->Insert(transaction, (const uint8*)newName, status = newTree->Insert(transaction, (const uint8*)newName,
@@ -1173,10 +1172,10 @@ bfs_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
// if it's a directory, update the parent directory pointer // if it's a directory, update the parent directory pointer
// in its tree if necessary // in its tree if necessary
BPlusTree* movedTree = NULL; BPlusTree* movedTree = inode->Tree();
if (oldDirectory != newDirectory if (oldDirectory != newDirectory
&& inode->IsDirectory() && inode->IsDirectory()
&& (status = inode->GetTree(&movedTree)) == B_OK) { && movedTree != NULL) {
status = movedTree->Replace(transaction, (const uint8*)"..", status = movedTree->Replace(transaction, (const uint8*)"..",
2, newDirectory->ID()); 2, newDirectory->ID());
@@ -1579,8 +1578,8 @@ bfs_open_dir(fs_volume* _volume, fs_vnode* _node, void** _cookie)
if (!inode->IsContainer()) if (!inode->IsContainer())
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
BPlusTree* tree; BPlusTree* tree = inode->Tree();
if (inode->GetTree(&tree) != B_OK) if (tree == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
TreeIterator* iterator = new(std::nothrow) TreeIterator(tree); TreeIterator* iterator = new(std::nothrow) TreeIterator(tree);