mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 18:56:49 +01:00
BTRFS: Implement InsertEntries() that will insert consecutive items and its data.
Signed-off-by: Augustin Cavalier <waddlesplash@gmail.com>
This commit is contained in:
parent
02bce792d8
commit
84bc447cae
@ -420,6 +420,18 @@ BTree::Path::GetEntry(int slot, btrfs_key* _key, void** _value, uint32* _size,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BTree::Path::SetEntry(int slot, const btrfs_entry& entry, void* value)
|
||||
{
|
||||
if (slot < 0)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
memcpy(fNodes[0]->Item(slot), &entry, sizeof(btrfs_entry));
|
||||
memcpy(fNodes[0]->ItemData(slot), value, entry.Size());
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate and copy block and do all the changes that it can.
|
||||
* for now, we only copy-on-write tree block,
|
||||
@ -702,6 +714,72 @@ BTree::FindExact(Path* path, btrfs_key& key, void** _value, uint32* _size,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Insert "num" of consecutive empty entries start with slot of "startKey"
|
||||
* if successful return the starting slot, otherwise return error code.
|
||||
*/
|
||||
status_t
|
||||
BTree::MakeEntries(Transaction& transaction, Path* path,
|
||||
const btrfs_key& startKey, int num, int length)
|
||||
{
|
||||
TRACE("BTree::MakeEntries() num %i key (% " B_PRIu64 " %" B_PRIu8 " %"
|
||||
B_PRIu64 ")\n", num, startKey.ObjectID(), startKey.Type(),
|
||||
startKey.Offset());
|
||||
|
||||
status_t status = Traverse(BTREE_FORWARD, path, startKey);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
int slot = status;
|
||||
status = path->InternalCopy(transaction, 1);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
status = path->CopyOnWrite(transaction, 0, slot, num, length);
|
||||
if (status == B_DEVICE_FULL) {
|
||||
// TODO: push data or split node
|
||||
return status;
|
||||
}
|
||||
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
/* MakeEntries and then fill in them.
|
||||
*/
|
||||
status_t
|
||||
BTree::InsertEntries(Transaction& transaction, Path* path,
|
||||
btrfs_entry* entries, void** data, int num)
|
||||
{
|
||||
int totalLength = sizeof(btrfs_entry) * num;
|
||||
for (int i = 0; i < num; i++)
|
||||
totalLength += entries[i].Size();
|
||||
|
||||
status_t slot = MakeEntries(transaction, path, entries[0].key, num,
|
||||
totalLength);
|
||||
if (slot < B_OK)
|
||||
return slot;
|
||||
|
||||
uint32 upperLimit;
|
||||
if (slot > 0) {
|
||||
path->GetEntry(slot - 1, NULL, NULL, NULL, &upperLimit);
|
||||
} else
|
||||
upperLimit = fVolume->BlockSize() - sizeof(btrfs_header);
|
||||
|
||||
TRACE("BTree::InsertEntries() num: %i upper limit %" B_PRIu32 "\n", num,
|
||||
upperLimit);
|
||||
for (int i = 0; i < num; i++) {
|
||||
upperLimit -= entries[i].Size();
|
||||
entries[i].SetOffset(upperLimit);
|
||||
path->SetEntry(slot + i, entries[i], data[i]);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BTree::PreviousLeaf(Path* path) const
|
||||
{
|
||||
|
@ -72,6 +72,12 @@ public:
|
||||
|
||||
status_t PreviousLeaf(Path* path) const;
|
||||
status_t NextLeaf(Path* path) const;
|
||||
status_t MakeEntries(Transaction& transaction,
|
||||
Path* path, const btrfs_key& startKey,
|
||||
int num, int length);
|
||||
status_t InsertEntries(Transaction& transaction,
|
||||
Path* path, btrfs_entry* entries,
|
||||
void** data, int num);
|
||||
|
||||
Volume* SystemVolume() const { return fVolume; }
|
||||
status_t SetRoot(off_t logical, fsblock_t* block);
|
||||
@ -181,6 +187,7 @@ public:
|
||||
uint32* _size = NULL, uint32* _offset = NULL);
|
||||
status_t GetEntry(int slot, btrfs_key* _key, void** _value,
|
||||
uint32* _size = NULL, uint32* _offset = NULL);
|
||||
status_t SetEntry(int slot, const btrfs_entry& entry, void* value);
|
||||
|
||||
int Move(int level, int step);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user