Fixed a major bug in the inode code: Inode::GetTree() was called completely

without any locking, but was not safe to be used this way.
Now, B+tree creation is done when the inode is created, and thus no further
locking is needed.
Although this reduces the speed when doing directory listings with many sub-
directories, any errors are reported upfront, and not only when you access
the tree directly.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7682 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-05-29 21:48:30 +00:00
parent c46a51bb81
commit 5325a3e53d
+18 -15
View File
@@ -220,6 +220,9 @@ Inode::Initialize()
// these two will help to maintain the indices
fOldSize = Size();
fOldLastModified = LastModified();
if (IsContainer())
fTree = new BPlusTree(this);
}
@@ -241,6 +244,18 @@ Inode::InitCheck(bool checkNode)
}
}
if (IsContainer()) {
// inodes that have a
if (fTree == NULL)
RETURN_ERROR(B_NO_MEMORY);
status_t status = fTree->InitCheck();
if (status < B_OK) {
FATAL(("inode tree at block %Ld corrupt!\n", fBlockNumber));
RETURN_ERROR(B_BAD_DATA);
}
}
// it's more important to know that the inode is corrupt
// so we check for the lock not until here
return fLock.InitCheck();
@@ -948,8 +963,9 @@ Inode::CreateAttribute(Transaction *transaction, const char *name, uint32 type,
/** Gives the caller direct access to the b+tree for a given directory.
* The tree is created on demand, but lasts until the inode is
* deleted.
* 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
@@ -960,19 +976,6 @@ Inode::GetTree(BPlusTree **tree)
return B_OK;
}
if (IsContainer()) {
fTree = new BPlusTree(this);
if (!fTree)
RETURN_ERROR(B_NO_MEMORY);
*tree = fTree;
status_t status = fTree->InitCheck();
if (status < B_OK) {
delete fTree;
fTree = NULL;
}
RETURN_ERROR(status);
}
RETURN_ERROR(B_BAD_VALUE);
}