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