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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user