* Coding style cleanups, no functional changes.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26728 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-08-02 14:06:38 +00:00
parent 51daeb7147
commit 02c8f6c89d
13 changed files with 1333 additions and 1259 deletions
@@ -10,7 +10,8 @@
// TODO: clean this up, find a better separation between Inode and this class
// TODO: even after Create(), the attribute cannot be stat() for until the first write
// TODO: even after Create(), the attribute cannot be stat() for until the
// first write
extern void fill_stat_buffer(Inode* inode, struct stat& stat);
@@ -203,8 +204,8 @@ Attribute::Read(attr_cookie *cookie, off_t pos, uint8 *buffer, size_t *_length)
status_t
Attribute::Write(Transaction &transaction, attr_cookie *cookie,
off_t pos, const uint8 *buffer, size_t *_length)
Attribute::Write(Transaction& transaction, attr_cookie* cookie, off_t pos,
const uint8* buffer, size_t* _length)
{
if (!cookie->create && fSmall == NULL && fAttribute == NULL)
return B_NO_INIT;
@@ -1,6 +1,5 @@
/* Attribute - connection between pure inode and kernel_interface attributes
*
* Copyright 2004, Axel Dörfler, [email protected].
/*
* Copyright 2004-2008, Axel Dörfler, [email protected].
* This file may be used under the terms of the MIT License.
*/
#ifndef ATTRIBUTE_H
@@ -30,15 +29,18 @@ class Attribute {
status_t Get(const char* name);
void Put();
status_t Create(const char *name, type_code type, int openMode,
status_t Create(const char* name, type_code type,
int openMode, attr_cookie** _cookie);
status_t Open(const char* name, int openMode,
attr_cookie** _cookie);
status_t Open(const char *name, int openMode, attr_cookie **_cookie);
status_t Stat(struct stat& stat);
status_t Read(attr_cookie *cookie, off_t pos, uint8 *buffer, size_t *_length);
status_t Read(attr_cookie* cookie, off_t pos, uint8* buffer,
size_t* _length);
status_t Write(Transaction& transaction, attr_cookie* cookie,
off_t pos, const uint8 *buffer, size_t *_length);
off_t pos, const uint8* buffer,
size_t* _length);
private:
status_t _Truncate();
@@ -50,4 +52,4 @@ class Attribute {
const char* fName;
};
#endif /* ATTRIBUTE_H */
#endif // ATTRIBUTE_H
+142 -97
View File
@@ -82,7 +82,8 @@ CachedNode::Unset()
return;
if (fNode != NULL) {
block_cache_put(fTree->fStream->GetVolume()->BlockCache(), fBlockNumber);
block_cache_put(fTree->fStream->GetVolume()->BlockCache(),
fBlockNumber);
fNode = NULL;
}
}
@@ -225,9 +226,10 @@ CachedNode::InternalSetTo(Transaction *transaction, off_t offset)
}
if (block) {
// the node is somewhere in that block... (confusing offset calculation)
fNode = (bplustree_node *)(block + offset -
(fileOffset + (blockOffset << volume->BlockShift())));
// The node is somewhere in that block...
// (confusing offset calculation)
fNode = (bplustree_node*)(block + offset
- (fileOffset + (blockOffset << volume->BlockShift())));
} else
REPORT_ERROR(B_IO_ERROR);
}
@@ -246,7 +248,8 @@ CachedNode::Free(Transaction &transaction, off_t offset)
// function is called, perhaps it should be done when the directory
// inode is closed or based on some calculation or whatever...
bplustree_header *header = fTree->fCachedHeader.MakeWritableHeader(transaction);
bplustree_header* header
= fTree->fCachedHeader.MakeWritableHeader(transaction);
if (header == NULL)
return B_IO_ERROR;
@@ -419,7 +422,8 @@ BPlusTree::SetTo(Transaction &transaction, Inode *stream, int32 nodeSize)
header->max_number_of_levels = HOST_ENDIAN_TO_BFS_INT32(1);
header->data_type = HOST_ENDIAN_TO_BFS_INT32(ModeToKeyType(stream->Mode()));
header->root_node_pointer = HOST_ENDIAN_TO_BFS_INT64(nodeSize);
header->free_node_pointer = HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
header->free_node_pointer
= HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
header->maximum_size = HOST_ENDIAN_TO_BFS_INT64(nodeSize * 2);
// initialize b+tree root node
@@ -684,8 +688,7 @@ BPlusTree::_FindKey(const bplustree_node *node, const uint8 *key,
}
/*!
Prepares the stack to contain all nodes that were passed while
/*! Prepares the stack to contain all nodes that were passed while
following the key, from the root node to the leaf node that could
or should contain that key.
*/
@@ -733,8 +736,7 @@ BPlusTree::_SeekDown(Stack<node_and_key> &stack, const uint8 *key,
}
/*!
This will find a free duplicate fragment in the given bplustree_node.
/*! This will find a free duplicate fragment in the given bplustree_node.
The CachedNode will be set to the writable fragment on success.
*/
status_t
@@ -792,8 +794,10 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
// If it's a duplicate fragment, try to insert it into that, or if it
// doesn't fit anymore, create a new duplicate node
if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) {
bplustree_node *duplicate = cachedDuplicate.SetToWritable(transaction,
if (bplustree_node::LinkType(oldValue)
== BPLUSTREE_DUPLICATE_FRAGMENT) {
bplustree_node* duplicate
= cachedDuplicate.SetToWritable(transaction,
bplustree_node::FragmentOffset(oldValue), false);
if (duplicate == NULL)
return B_IO_ERROR;
@@ -802,19 +806,20 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
bplustree_node::FragmentIndex(oldValue));
if (array->count > NUM_FRAGMENT_VALUES
|| array->count < 1) {
FATAL(("insertDuplicate: Invalid array[%d] size in fragment %Ld == %Ld!\n",
FATAL(("insertDuplicate: Invalid array[%d] size in fragment "
"%Ld == %Ld!\n",
(int)bplustree_node::FragmentIndex(oldValue),
bplustree_node::FragmentOffset(oldValue),
array->count));
bplustree_node::FragmentOffset(oldValue), array->count));
return B_BAD_DATA;
}
if (array->count < NUM_FRAGMENT_VALUES) {
array->Insert(value);
} else {
// test if the fragment will be empty if we remove this key's values
// Test if the fragment will be empty if we remove this key's
// values
if (duplicate->FragmentsUsed(fNodeSize) < 2) {
// the node will be empty without our values, so let us
// The node will be empty without our values, so let us
// reuse it as a duplicate node
offset = bplustree_node::FragmentOffset(oldValue);
@@ -826,10 +831,11 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
array = duplicate->DuplicateArray();
array->Insert(value);
} else {
// create a new duplicate node
// Create a new duplicate node
cachedDuplicate.UnsetUnchanged(transaction);
// the old duplicate has not been touched, so we can reuse it
// The old duplicate has not been touched, so we can
// reuse it
bplustree_node* newDuplicate;
status = cachedDuplicate.Allocate(transaction,
@@ -837,8 +843,8 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
if (status < B_OK)
RETURN_ERROR(status);
// copy the array from the fragment node to the duplicate node
// and free the old entry (by zero'ing all values)
// Copy the array from the fragment node to the duplicate
// node and free the old entry (by zero'ing all values)
newDuplicate->overflow_link = HOST_ENDIAN_TO_BFS_INT64(
array->count);
memcpy(&newDuplicate->all_key_count, &array->values[0],
@@ -849,11 +855,12 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
array->Insert(value);
}
// update the main pointer to link to a duplicate node
// Update the main pointer to link to a duplicate node
if (cached.MakeWritable(transaction) == NULL)
return B_IO_ERROR;
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
values[index]
= HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
BPLUSTREE_DUPLICATE_NODE, offset));
}
@@ -874,14 +881,15 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
array = duplicate->DuplicateArray();
if (array->count > NUM_DUPLICATE_VALUES || array->count < 0) {
FATAL(("removeDuplicate: Invalid array size in duplicate %Ld == %Ld!\n",
duplicateOffset, array->count));
FATAL(("removeDuplicate: Invalid array size in duplicate %Ld "
"== %Ld!\n", duplicateOffset, array->count));
return B_BAD_DATA;
}
} while (array->count >= NUM_DUPLICATE_VALUES
&& (oldValue = duplicate->RightLink()) != BPLUSTREE_NULL);
bplustree_node *writableDuplicate = cachedDuplicate.MakeWritable(transaction);
bplustree_node* writableDuplicate
= cachedDuplicate.MakeWritable(transaction);
if (writableDuplicate == NULL)
return B_IO_ERROR;
@@ -892,7 +900,8 @@ BPlusTree::_InsertDuplicate(Transaction &transaction, CachedNode &cached,
// no space left - add a new duplicate node
bplustree_node* newDuplicate;
status = cachedDuplicate.Allocate(transaction, &newDuplicate, &offset);
status = cachedDuplicate.Allocate(transaction, &newDuplicate,
&offset);
if (status < B_OK)
RETURN_ERROR(status);
@@ -984,10 +993,9 @@ BPlusTree::_InsertKey(bplustree_node *node, uint16 index, uint8 *key,
}
/*!
Splits the \a node into two halves - the other half will be put into \a other.
It also takes care to create a new overflow link if the node to split is an
index node.
/*! Splits the \a node into two halves - the other half will be put into
\a other. It also takes care to create a new overflow link if the node
to split is an index node.
*/
status_t
BPlusTree::_SplitNode(bplustree_node* node, off_t nodeOffset,
@@ -1082,7 +1090,8 @@ BPlusTree::_SplitNode(bplustree_node *node, off_t nodeOffset,
keys = out - keyIndex - 1;
for (int32 i = 0;i < keys;i++) {
outKeyLengths[keyIndex + i + 1] = HOST_ENDIAN_TO_BFS_INT16(
BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[keyIndex + i]) + bytes);
BFS_ENDIAN_TO_HOST_INT16(inKeyLengths[keyIndex + i])
+ bytes);
}
memcpy(outKeyValues + keyIndex + 1, inKeyValues + keyIndex,
keys * sizeof(off_t));
@@ -1421,8 +1430,9 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
if (array->count > NUM_FRAGMENT_VALUES
|| array->count < 1) {
FATAL(("removeDuplicate: Invalid array[%d] size in fragment %Ld == %Ld!\n",
(int)bplustree_node::FragmentIndex(oldValue), duplicateOffset, array->count));
FATAL(("removeDuplicate: Invalid array[%d] size in fragment %Ld "
"== %Ld!\n", (int)bplustree_node::FragmentIndex(oldValue),
duplicateOffset, array->count));
return B_BAD_DATA;
}
if (!array->Remove(value)) {
@@ -1442,7 +1452,8 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
// Remove the whole fragment node, if this was the only array,
// otherwise free just the array
if (duplicate->FragmentsUsed(fNodeSize) == 1) {
status_t status = cachedDuplicate.Free(transaction, duplicateOffset);
status_t status = cachedDuplicate.Free(transaction,
duplicateOffset);
if (status < B_OK)
return status;
} else
@@ -1466,8 +1477,8 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
array = duplicate->DuplicateArray();
if (array->count > NUM_DUPLICATE_VALUES
|| array->count < 0) {
FATAL(("removeDuplicate: Invalid array size in duplicate %Ld == %Ld!\n",
duplicateOffset, array->count));
FATAL(("removeDuplicate: Invalid array size in duplicate %Ld == "
"%Ld!\n", duplicateOffset, array->count));
return B_BAD_DATA;
}
@@ -1478,7 +1489,8 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
RETURN_ERROR(B_ENTRY_NOT_FOUND);
cachedDuplicate.UnsetUnchanged(transaction);
duplicate = cachedDuplicate.SetToWritable(transaction, duplicateOffset, false);
duplicate = cachedDuplicate.SetToWritable(transaction, duplicateOffset,
false);
}
if (duplicate == NULL)
RETURN_ERROR(B_IO_ERROR);
@@ -1502,41 +1514,48 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
return B_IO_ERROR;
if (array->count == 1) {
// this is the last node, and there is only one value left;
// replace the duplicate link with that value, it's no duplicate
// anymore
// This is the last node, and there is only one value left;
// replace the duplicate link with that value, it's no
// duplicate anymore
values[index] = array->values[0];
} else {
// move the duplicate link to the next node
values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink(
// Move the duplicate link to the next node
values[index] = HOST_ENDIAN_TO_BFS_INT64(
bplustree_node::MakeLink(
BPLUSTREE_DUPLICATE_NODE, right));
}
}
status_t status;
if ((status = cachedDuplicate.Free(transaction, duplicateOffset)) < B_OK)
status_t status = cachedDuplicate.Free(transaction,
duplicateOffset);
if (status < B_OK)
return status;
if (left != BPLUSTREE_NULL
&& (duplicate = cachedDuplicate.SetToWritable(transaction, left, false)) != NULL) {
&& (duplicate = cachedDuplicate.SetToWritable(transaction, left,
false)) != NULL) {
duplicate->right_link = HOST_ENDIAN_TO_BFS_INT64(right);
// If the next node is the last node, we need to free that node
// and convert the duplicate entry back into a normal entry
array = duplicate->DuplicateArray();
if (right == BPLUSTREE_NULL && duplicate->LeftLink() == BPLUSTREE_NULL
if (right == BPLUSTREE_NULL
&& duplicate->LeftLink() == BPLUSTREE_NULL
&& array->count <= NUM_FRAGMENT_VALUES) {
duplicateOffset = left;
continue;
}
}
if (right != BPLUSTREE_NULL
&& (duplicate = cachedDuplicate.SetToWritable(transaction, right, false)) != NULL) {
&& (duplicate = cachedDuplicate.SetToWritable(transaction,
right, false)) != NULL) {
duplicate->left_link = HOST_ENDIAN_TO_BFS_INT64(left);
// Again, we may need to turn the duplicate entry back into a normal entry
// Again, we may need to turn the duplicate entry back into a
// normal entry
array = duplicate->DuplicateArray();
if (left == BPLUSTREE_NULL && duplicate->RightLink() == BPLUSTREE_NULL
if (left == BPLUSTREE_NULL
&& duplicate->RightLink() == BPLUSTREE_NULL
&& array->count <= NUM_FRAGMENT_VALUES) {
duplicateOffset = right;
continue;
@@ -1556,13 +1575,15 @@ BPlusTree::_RemoveDuplicate(Transaction &transaction,
&offset, &fragment, &fragmentIndex) == B_OK) {
// move to other node
duplicate_array* target = fragment->FragmentAt(fragmentIndex);
memcpy(target, array, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
memcpy(target, array,
(NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
cachedDuplicate.Free(transaction, duplicateOffset);
duplicateOffset = offset;
} else {
// convert node
memmove(duplicate, array, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
memmove(duplicate, array,
(NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
memset((off_t*)duplicate + NUM_FRAGMENT_VALUES + 1, 0,
fNodeSize - (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t));
}
@@ -1605,7 +1626,8 @@ BPlusTree::_RemoveKey(bplustree_node *node, uint16 index)
if (key + length + sizeof(off_t) + sizeof(uint16) > (uint8*)node + fNodeSize
|| length > BPLUSTREE_MAX_KEY_LENGTH) {
FATAL(("Key length to long: %s, %u (inode at %d,%u)\n", key, length,
(int)fStream->BlockRun().allocation_group, fStream->BlockRun().start));
(int)fStream->BlockRun().allocation_group,
fStream->BlockRun().start));
fStream->GetVolume()->Panic();
return;
}
@@ -1614,7 +1636,8 @@ BPlusTree::_RemoveKey(bplustree_node *node, uint16 index)
uint8* keys = node->Keys();
node->all_key_count = HOST_ENDIAN_TO_BFS_INT16(node->NumKeys() - 1);
node->all_key_length = HOST_ENDIAN_TO_BFS_INT64(node->AllKeyLength() - length);
node->all_key_length = HOST_ENDIAN_TO_BFS_INT64(
node->AllKeyLength() - length);
off_t* newValues = node->Values();
uint16* newKeyLengths = node->KeyLengths();
@@ -1633,8 +1656,10 @@ BPlusTree::_RemoveKey(bplustree_node *node, uint16 index)
// move values
if (index > 0)
memmove(newValues, values, index * sizeof(off_t));
if (node->NumKeys() > index)
memmove(newValues + index, values + index + 1, (node->NumKeys() - index) * sizeof(off_t));
if (node->NumKeys() > index) {
memmove(newValues + index, values + index + 1,
(node->NumKeys() - index) * sizeof(off_t));
}
}
@@ -1689,7 +1714,8 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
return _RemoveDuplicate(transaction, node, cached,
nodeAndKey.keyIndex, value);
} else {
FATAL(("dupliate node found where no duplicates are allowed!\n"));
FATAL(("dupliate node found where no duplicates are "
"allowed!\n"));
RETURN_ERROR(B_ERROR);
}
}
@@ -1703,15 +1729,18 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
// to a leaf node by dropping the overflow link, or,
// if it's already a leaf node, just empty it
if (nodeAndKey.nodeOffset == fHeader->RootNode()
&& (node->NumKeys() == 0 || (node->NumKeys() == 1 && node->IsLeaf()))) {
writableNode->overflow_link = HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
&& (node->NumKeys() == 0
|| (node->NumKeys() == 1 && node->IsLeaf()))) {
writableNode->overflow_link
= HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
writableNode->all_key_count = 0;
writableNode->all_key_length = 0;
// if we've made a leaf node out of the root node, we need
// to reset the maximum number of levels in the header
if (fHeader->MaxNumberOfLevels() != 1) {
bplustree_header *header = fCachedHeader.MakeWritableHeader(transaction);
bplustree_header* header
= fCachedHeader.MakeWritableHeader(transaction);
if (header == NULL)
return B_IO_ERROR;
@@ -1738,8 +1767,10 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
if (other != NULL)
other->right_link = writableNode->right_link;
if ((other = otherCached.SetToWritable(transaction, node->RightLink())) != NULL)
if ((other = otherCached.SetToWritable(transaction, node->RightLink()))
!= NULL) {
other->left_link = writableNode->left_link;
}
cached.Free(transaction, nodeAndKey.nodeOffset);
}
@@ -1757,8 +1788,8 @@ BPlusTree::Remove(Transaction &transaction, const uint8 *key, uint16 keyLength,
You need to have the inode write locked.
*/
status_t
BPlusTree::Replace(Transaction &transaction, const uint8 *key,
uint16 keyLength, off_t value)
BPlusTree::Replace(Transaction& transaction, const uint8* key, uint16 keyLength,
off_t value)
{
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH
@@ -1777,14 +1808,16 @@ BPlusTree::Replace(Transaction &transaction, const uint8 *key,
while ((node = cached.SetTo(nodeOffset)) != NULL) {
uint16 keyIndex = 0;
off_t nextOffset;
status_t status = _FindKey(node, key, keyLength, &keyIndex, &nextOffset);
status_t status = _FindKey(node, key, keyLength, &keyIndex,
&nextOffset);
if (node->OverflowLink() == BPLUSTREE_NULL) {
if (status == B_OK) {
bplustree_node* writableNode = cached.MakeWritable(transaction);
if (writableNode != NULL)
writableNode->Values()[keyIndex] = HOST_ENDIAN_TO_BFS_INT64(value);
else
if (writableNode != NULL) {
writableNode->Values()[keyIndex]
= HOST_ENDIAN_TO_BFS_INT64(value);
} else
status = B_IO_ERROR;
}
@@ -1798,16 +1831,15 @@ BPlusTree::Replace(Transaction &transaction, const uint8 *key,
}
/*! Searches the key in the tree, and stores the offset found in
_value, if successful.
It's very similar to BPlusTree::SeekDown(), but doesn't fill
a stack while it descends the tree.
Returns B_OK when the key could be found, B_ENTRY_NOT_FOUND
if not. It can also return other errors to indicate that
something went wrong.
Note that this doesn't work with duplicates - it will just
return B_BAD_TYPE if you call this function on a tree where
duplicates are allowed.
/*! Searches the key in the tree, and stores the offset found in _value,
if successful.
It's very similar to BPlusTree::SeekDown(), but doesn't fill a stack
while it descends the tree.
Returns B_OK when the key could be found, B_ENTRY_NOT_FOUND if not.
It can also return other errors to indicate that something went wrong.
Note that this doesn't work with duplicates - it will just return
B_BAD_TYPE if you call this function on a tree where duplicates are
allowed.
You need to have the inode read or write locked.
*/
status_t
@@ -1834,7 +1866,8 @@ BPlusTree::Find(const uint8 *key, uint16 keyLength, off_t *_value)
while ((node = cached.SetTo(nodeOffset)) != NULL) {
uint16 keyIndex = 0;
off_t nextOffset;
status_t status = _FindKey(node, key, keyLength, &keyIndex, &nextOffset);
status_t status = _FindKey(node, key, keyLength, &keyIndex,
&nextOffset);
#ifdef DEBUG
levels++;
@@ -1924,8 +1957,7 @@ TreeIterator::Goto(int8 to)
}
/*!
Iterates through the tree in the specified direction.
/*! Iterates through the tree in the specified direction.
When it iterates through duplicates, the "key" is only updated for the
first entry - if you need to know when this happens, use the "duplicate"
parameter which is 0 for no duplicate, 1 for the first, and 2 for all
@@ -1960,27 +1992,31 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
const bplustree_node* node;
if (fDuplicateNode != BPLUSTREE_NULL) {
// regardless of traverse direction the duplicates are always presented in
// the same order; since they are all considered as equal, this shouldn't
// cause any problems
// regardless of traverse direction the duplicates are always presented
// in the same order; since they are all considered as equal, this
// shouldn't cause any problems
if (!fIsFragment || fDuplicate < fNumDuplicates)
node = cached.SetTo(bplustree_node::FragmentOffset(fDuplicateNode), false);
else
if (!fIsFragment || fDuplicate < fNumDuplicates) {
node = cached.SetTo(bplustree_node::FragmentOffset(fDuplicateNode),
false);
} else
node = NULL;
if (node != NULL) {
if (!fIsFragment && fDuplicate >= fNumDuplicates) {
// if the node is out of duplicates, we go directly to the next one
// If the node is out of duplicates, we go directly to the next
// one
fDuplicateNode = node->RightLink();
if (fDuplicateNode != BPLUSTREE_NULL
&& (node = cached.SetTo(fDuplicateNode, false)) != NULL) {
fNumDuplicates = node->CountDuplicates(fDuplicateNode, false);
fNumDuplicates = node->CountDuplicates(fDuplicateNode,
false);
fDuplicate = 0;
}
}
if (fDuplicate < fNumDuplicates) {
*value = node->DuplicateAt(fDuplicateNode, fIsFragment, fDuplicate++);
*value = node->DuplicateAt(fDuplicateNode, fIsFragment,
fDuplicate++);
if (duplicate)
*duplicate = 2;
return B_OK;
@@ -2027,7 +2063,8 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
uint16 length;
uint8* keyStart = node->KeyAt(fCurrentKey, &length);
if (keyStart + length + sizeof(off_t) + sizeof(uint16) > (uint8 *)node + fTree->fNodeSize
if (keyStart + length + sizeof(off_t) + sizeof(uint16)
> (uint8*)node + fTree->fNodeSize
|| length > BPLUSTREE_MAX_KEY_LENGTH) {
fTree->fStream->GetVolume()->Panic();
RETURN_ERROR(B_BAD_DATA);
@@ -2048,10 +2085,12 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
// duplicate fragments?
uint8 type = bplustree_node::LinkType(offset);
if (type == BPLUSTREE_DUPLICATE_FRAGMENT || type == BPLUSTREE_DUPLICATE_NODE) {
if (type == BPLUSTREE_DUPLICATE_FRAGMENT
|| type == BPLUSTREE_DUPLICATE_NODE) {
fDuplicateNode = offset;
node = cached.SetTo(bplustree_node::FragmentOffset(fDuplicateNode), false);
node = cached.SetTo(bplustree_node::FragmentOffset(fDuplicateNode),
false);
if (node == NULL)
RETURN_ERROR(B_ERROR);
@@ -2064,7 +2103,8 @@ TreeIterator::Traverse(int8 direction, void *key, uint16 *keyLength,
if (duplicate)
*duplicate = 1;
} else {
// shouldn't happen, but we're dealing here with potentially corrupt disks...
// Shouldn't happen, but we're dealing here with potentially
// corrupt disks...
fDuplicateNode = BPLUSTREE_NULL;
offset = 0;
}
@@ -2084,7 +2124,8 @@ TreeIterator::Find(const uint8 *key, uint16 keyLength)
{
if (fTree == NULL)
return B_INTERRUPTED;
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH || keyLength > BPLUSTREE_MAX_KEY_LENGTH
if (keyLength < BPLUSTREE_MIN_KEY_LENGTH
|| keyLength > BPLUSTREE_MAX_KEY_LENGTH
|| key == NULL)
RETURN_ERROR(B_BAD_VALUE);
@@ -2163,7 +2204,9 @@ TreeIterator::Dump()
__out("\tfTree = %p\n", fTree);
__out("\tfCurrentNodeOffset = %Ld\n", fCurrentNodeOffset);
__out("\tfCurrentKey = %ld\n", fCurrentKey);
__out("\tfDuplicateNode = %Ld (%Ld, 0x%Lx)\n", bplustree_node::FragmentOffset(fDuplicateNode), fDuplicateNode, fDuplicateNode);
__out("\tfDuplicateNode = %Ld (%Ld, 0x%Lx)\n",
bplustree_node::FragmentOffset(fDuplicateNode), fDuplicateNode,
fDuplicateNode);
__out("\tfDuplicate = %u\n", fDuplicate);
__out("\tfNumDuplicates = %u\n", fNumDuplicates);
__out("\tfIsFragment = %s\n", fIsFragment ? "true" : "false");
@@ -2177,7 +2220,8 @@ TreeIterator::Dump()
void
bplustree_node::Initialize()
{
left_link = right_link = overflow_link = HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
left_link = right_link = overflow_link
= HOST_ENDIAN_TO_BFS_INT64((uint64)BPLUSTREE_NULL);
all_key_count = 0;
all_key_length = 0;
}
@@ -2257,7 +2301,8 @@ bplustree_node::CheckIntegrity(uint32 nodeSize) const
for (int32 i = 0; i < NumKeys(); i++) {
uint16 length;
uint8* key = KeyAt(i, &length);
if (key + length + sizeof(off_t) + sizeof(uint16) > (uint8 *)this + nodeSize
if (key + length + sizeof(off_t) + sizeof(uint16)
> (uint8*)this + nodeSize
|| length > BPLUSTREE_MAX_KEY_LENGTH) {
dprintf("node %p, key %ld\n", this, i);
DEBUGGER(("invalid node: keys corrupted"));
@@ -29,21 +29,28 @@ class BlockAllocator {
void Uninitialize();
status_t AllocateForInode(Transaction &transaction, const block_run *parent,
mode_t type, block_run &run);
status_t Allocate(Transaction &transaction, Inode *inode, off_t numBlocks,
block_run &run, uint16 minimum = 1);
status_t AllocateForInode(Transaction& transaction,
const block_run* parent, mode_t type,
block_run& run);
status_t Allocate(Transaction& transaction, Inode* inode,
off_t numBlocks, block_run& run,
uint16 minimum = 1);
status_t Free(Transaction& transaction, block_run run);
status_t AllocateBlocks(Transaction &transaction, int32 group, uint16 start,
uint16 numBlocks, uint16 minimum, block_run &run);
status_t AllocateBlocks(Transaction& transaction,
int32 group, uint16 start, uint16 numBlocks,
uint16 minimum, block_run& run);
status_t StartChecking(check_control* control);
status_t StopChecking(check_control* control);
status_t CheckNextNode(check_control* control);
status_t CheckBlockRun(block_run run, const char *type = NULL, check_control *control = NULL, bool allocated = true);
status_t CheckInode(Inode *inode, check_control *control = NULL);
status_t CheckBlockRun(block_run run,
const char* type = NULL,
check_control* control = NULL,
bool allocated = true);
status_t CheckInode(Inode* inode,
check_control* control = NULL);
size_t BitmapSize() const;
@@ -56,7 +63,7 @@ class BlockAllocator {
bool _CheckBitmapIsUsedAt(off_t block) const;
void _SetCheckBitmapAt(off_t block);
static status_t _Initialize(BlockAllocator *);
static status_t _Initialize(BlockAllocator* self);
Volume* fVolume;
mutex fLock;
@@ -72,4 +79,4 @@ class BlockAllocator {
int dump_block_allocator(int argc, char** argv);
#endif
#endif /* BLOCK_ALLOCATOR_H */
#endif // BLOCK_ALLOCATOR_H
@@ -51,8 +51,7 @@ Index::Unset()
}
/*!
Sets the index to specified one. Returns an error if the index could
/*! Sets the index to specified one. Returns an error if the index could
not be found or initialized.
Note, Index::Update() may be called on the object even if this method
failed previously. In this case, it will only update live queries for
+24 -15
View File
@@ -1,6 +1,5 @@
/* Index - index access functions
*
* Copyright 2001-2004, Axel Dörfler, axeld@pinc-software.de.
/*
* Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
#ifndef INDEX_H
@@ -9,6 +8,7 @@
#include "system_dependencies.h"
class Transaction;
class Volume;
class Inode;
@@ -26,27 +26,36 @@ class Index {
uint32 Type();
size_t KeySize();
status_t Create(Transaction &transaction, const char *name, uint32 type);
status_t Create(Transaction& transaction, const char* name,
uint32 type);
status_t Update(Transaction &transaction, const char *name, int32 type, const uint8 *oldKey,
uint16 oldLength, const uint8 *newKey, uint16 newLength, Inode *inode);
status_t Update(Transaction& transaction, const char* name,
int32 type, const uint8* oldKey,
uint16 oldLength, const uint8* newKey,
uint16 newLength, Inode* inode);
status_t InsertName(Transaction &transaction, const char *name, Inode *inode);
status_t RemoveName(Transaction &transaction, const char *name, Inode *inode);
status_t UpdateName(Transaction &transaction, const char *oldName, const char *newName,
status_t InsertName(Transaction& transaction,
const char* name, Inode* inode);
status_t RemoveName(Transaction& transaction,
const char* name, Inode* inode);
status_t UpdateName(Transaction& transaction,
const char* oldName, const char* newName,
Inode* inode);
status_t InsertSize(Transaction& transaction, Inode* inode);
status_t RemoveSize(Transaction& transaction, Inode* inode);
status_t UpdateSize(Transaction& transaction, Inode* inode);
status_t InsertLastModified(Transaction &transaction, Inode *inode);
status_t RemoveLastModified(Transaction &transaction, Inode *inode);
status_t UpdateLastModified(Transaction &transaction, Inode *inode, off_t modified = -1);
status_t InsertLastModified(Transaction& transaction,
Inode* inode);
status_t RemoveLastModified(Transaction& transaction,
Inode* inode);
status_t UpdateLastModified(Transaction& transaction,
Inode* inode, off_t modified = -1);
private:
Index(const Index &);
Index &operator=(const Index &);
Index(const Index& other);
Index& operator=(const Index& other);
// no implementation
Volume* fVolume;
@@ -54,4 +63,4 @@ class Index {
const char* fName;
};
#endif /* INDEX_H */
#endif // INDEX_H
@@ -52,7 +52,6 @@ class Create : public AbstractTraceEntry {
int32 fMode;
int fOpenMode;
uint32 fType;
};
class Remove : public AbstractTraceEntry {
@@ -138,13 +137,15 @@ class InodeAllocator {
InodeAllocator(Transaction& transaction);
~InodeAllocator();
status_t New(block_run *parentRun, mode_t mode, block_run &run,
fs_vnode_ops *vnodeOps, Inode **_inode);
status_t New(block_run* parentRun, mode_t mode,
block_run& run, fs_vnode_ops* vnodeOps,
Inode** _inode);
status_t CreateTree();
status_t Keep(fs_vnode_ops* vnodeOps, uint32 publishFlags);
private:
static void _TransactionListener(int32 id, int32 event, void *_inode);
static void _TransactionListener(int32 id, int32 event,
void* _inode);
Transaction* fTransaction;
block_run fRun;
@@ -455,7 +456,7 @@ Inode::CheckPermissions(int accessMode) const
gid_t group = getegid();
// you never have write access to a read-only volume
if (accessMode & W_OK && fVolume->IsReadOnly())
if ((accessMode & W_OK) != 0 && fVolume->IsReadOnly())
return B_READ_ONLY_DEVICE;
// root users always have full access (but they can't execute files without
@@ -511,7 +512,8 @@ Inode::_MakeSpaceForSmallData(Transaction &transaction, bfs_inode *node,
ASSERT_LOCKED_RECURSIVE(&fSmallDataLock);
while (bytes > 0) {
small_data *item = node->SmallDataStart(), *max = NULL;
small_data* item = node->SmallDataStart();
small_data* max = NULL;
int32 index = 0, maxIndex = 0;
for (; !item->IsLast(node); item = item->Next(), index++) {
// should not remove those
@@ -43,7 +43,8 @@ class RunArrays {
int32 CountArrays() const { return fArrays.CountItems(); }
uint32 CountBlocks() const { return fBlockCount; }
uint32 LogEntryLength() const { return CountBlocks() + CountArrays(); }
uint32 LogEntryLength() const
{ return CountBlocks() + CountArrays(); }
int32 MaxArrayLength();
@@ -60,7 +61,8 @@ class RunArrays {
class LogEntry : public DoublyLinkedListLinkImpl<LogEntry> {
public:
LogEntry(Journal *journal, uint32 logStart, uint32 length);
LogEntry(Journal* journal, uint32 logStart,
uint32 length);
~LogEntry();
uint32 Start() const { return fStart; }
+9 -19
View File
@@ -8,10 +8,6 @@
#include "system_dependencies.h"
#ifndef _IMPEXP_KERNEL
# define _IMPEXP_KERNEL
#endif
#include "Volume.h"
#include "Utility.h"
@@ -23,17 +19,9 @@ typedef DoublyLinkedList<LogEntry> LogEntryList;
typedef SinglyLinkedList<Inode> InodeList;
// Locking policy in BFS: if you need both, the volume lock and the
// journal lock, you must lock the volume first - or else you will
// end up in a deadlock.
// That is, if you start a transaction, and will need to lock the
// volume while the transaction is in progress (for the unsafe
// get_vnode() call, for example), you must lock the volume before
// starting the transaction.
class Journal {
public:
Journal(Volume *);
Journal(Volume* volume);
~Journal();
status_t InitCheck();
@@ -64,15 +52,17 @@ class Journal {
status_t _ReplayRunArray(int32* start);
status_t _TransactionDone(bool success);
static void _TransactionWritten(int32 transactionID, int32 event,
void *_logEntry);
static void _TransactionWritten(int32 transactionID,
int32 event, void* _logEntry);
static void _TransactionIdle(int32 transactionID, int32 event,
void* _journal);
Volume* fVolume;
recursive_lock fLock;
Transaction* fOwner;
uint32 fLogSize, fMaxTransactionSize, fUsed;
uint32 fLogSize;
uint32 fMaxTransactionSize;
uint32 fUsed;
int32 fUnwrittenTransactions;
mutex fEntriesLock;
LogEntryList fEntries;
@@ -177,8 +167,8 @@ class Transaction {
void AddInode(Inode* inode);
private:
Transaction(const Transaction &);
Transaction &operator=(const Transaction &);
Transaction(const Transaction& other);
Transaction& operator=(const Transaction& other);
// no implementation
void _UnlockInodes();
@@ -191,4 +181,4 @@ class Transaction {
int dump_journal(int argc, char** argv);
#endif
#endif /* JOURNAL_H */
#endif // JOURNAL_H
@@ -61,7 +61,8 @@ sorted_array::Remove(off_t value)
return false;
count--;
memmove(&values[index], &values[index + 1], (count - index) * sizeof(off_t));
memmove(&values[index], &values[index + 1],
(count - index) * sizeof(off_t));
return true;
}
@@ -13,7 +13,6 @@
// TODO: this is not endian safe!!!
struct sorted_array {
public:
off_t count;
off_t values[0];
+39 -20
View File
@@ -53,23 +53,34 @@ class Volume {
fs_volume* FSVolume() const { return fVolume; }
const char* Name() const { return fSuperBlock.name; }
off_t NumBlocks() const { return fSuperBlock.NumBlocks(); }
off_t UsedBlocks() const { return fSuperBlock.UsedBlocks(); }
off_t FreeBlocks() const { return NumBlocks() - UsedBlocks(); }
off_t NumBlocks() const
{ return fSuperBlock.NumBlocks(); }
off_t UsedBlocks() const
{ return fSuperBlock.UsedBlocks(); }
off_t FreeBlocks() const
{ return NumBlocks() - UsedBlocks(); }
uint32 BlockSize() const { return fBlockSize; }
uint32 BlockShift() const { return fBlockShift; }
uint32 InodeSize() const { return fSuperBlock.InodeSize(); }
uint32 AllocationGroups() const { return fSuperBlock.AllocationGroups(); }
uint32 AllocationGroupShift() const { return fAllocationGroupShift; }
uint32 InodeSize() const
{ return fSuperBlock.InodeSize(); }
uint32 AllocationGroups() const
{ return fSuperBlock.AllocationGroups(); }
uint32 AllocationGroupShift() const
{ return fAllocationGroupShift; }
disk_super_block& SuperBlock() { return fSuperBlock; }
off_t ToOffset(block_run run) const { return ToBlock(run) << BlockShift(); }
off_t ToBlock(block_run run) const { return ((((off_t)run.AllocationGroup()) << AllocationGroupShift()) | (off_t)run.Start()); }
off_t ToOffset(block_run run) const
{ return ToBlock(run) << BlockShift(); }
off_t ToBlock(block_run run) const
{ return ((((off_t)run.AllocationGroup())
<< AllocationGroupShift())
| (off_t)run.Start()); }
block_run ToBlockRun(off_t block) const;
status_t ValidateBlockRun(block_run run);
off_t ToVnode(block_run run) const { return ToBlock(run); }
off_t ToVnode(block_run run) const
{ return ToBlock(run); }
off_t ToVnode(off_t block) const { return block; }
off_t VnodeToBlock(ino_t id) const { return (off_t)id; }
@@ -77,12 +88,15 @@ class Volume {
// block bitmap
BlockAllocator& Allocator();
status_t AllocateForInode(Transaction &transaction, const Inode *parent,
mode_t type, block_run &run);
status_t AllocateForInode(Transaction &transaction, const block_run *parent,
mode_t type, block_run &run);
status_t AllocateForInode(Transaction& transaction,
const Inode* parent, mode_t type,
block_run& run);
status_t AllocateForInode(Transaction& transaction,
const block_run* parent, mode_t type,
block_run& run);
status_t Allocate(Transaction& transaction, Inode* inode,
off_t numBlocks, block_run &run, uint16 minimum = 1);
off_t numBlocks, block_run& run,
uint16 minimum = 1);
status_t Free(Transaction& transaction, block_run run);
// cache access
@@ -90,7 +104,8 @@ class Volume {
status_t FlushDevice();
// queries
void UpdateLiveQueries(Inode *inode, const char *attribute, int32 type,
void UpdateLiveQueries(Inode* inode,
const char* attribute, int32 type,
const uint8* oldKey, size_t oldLength,
const uint8* newKey, size_t newLength);
bool CheckForLiveQuery(const char* attribute);
@@ -120,7 +135,8 @@ class Volume {
BlockAllocator fBlockAllocator;
mutex fLock;
Journal* fJournal;
vint32 fLogStart, fLogEnd;
vint32 fLogStart;
vint32 fLogEnd;
Inode* fRootNode;
Inode* fIndicesNode;
@@ -161,16 +177,19 @@ Volume::Allocator()
inline status_t
Volume::AllocateForInode(Transaction &transaction, const block_run *parent, mode_t type, block_run &run)
Volume::AllocateForInode(Transaction& transaction, const block_run* parent,
mode_t type, block_run& run)
{
return fBlockAllocator.AllocateForInode(transaction, parent, type, run);
}
inline status_t
Volume::Allocate(Transaction &transaction, Inode *inode, off_t numBlocks, block_run &run, uint16 minimum)
Volume::Allocate(Transaction& transaction, Inode* inode, off_t numBlocks,
block_run& run, uint16 minimum)
{
return fBlockAllocator.Allocate(transaction, inode, numBlocks, run, minimum);
return fBlockAllocator.Allocate(transaction, inode, numBlocks, run,
minimum);
}
@@ -201,4 +220,4 @@ Volume::GetUniqueID()
return atomic_add(&fUniqueID, 1);
}
#endif /* VOLUME_H */
#endif // VOLUME_H
@@ -1354,9 +1354,7 @@ bfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
if (linkLen < *_bufferSize)
*_bufferSize = linkLen;
memcpy(buffer, inode->Node().short_symlink, *_bufferSize);
return B_OK;
return user_memcpy(buffer, inode->Node().short_symlink, *_bufferSize);
}