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
|
// these two will help to maintain the indices
|
||||||
fOldSize = Size();
|
fOldSize = Size();
|
||||||
fOldLastModified = LastModified();
|
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
|
// it's more important to know that the inode is corrupt
|
||||||
// so we check for the lock not until here
|
// so we check for the lock not until here
|
||||||
return fLock.InitCheck();
|
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.
|
/** 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
|
* The tree is no longer created on demand, but when the inode is first
|
||||||
* deleted.
|
* created. That will report any potential errors upfront, saves locking,
|
||||||
|
* and should work as good (though a bit slower).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
@@ -960,19 +976,6 @@ Inode::GetTree(BPlusTree **tree)
|
|||||||
return B_OK;
|
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);
|
RETURN_ERROR(B_BAD_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user