BTRFS: Implement InsertEntries() that will insert consecutive items and its data.
Signed-off-by: Augustin Cavalier <[email protected]>
This commit is contained in:
@@ -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.
|
* Allocate and copy block and do all the changes that it can.
|
||||||
* for now, we only copy-on-write tree block,
|
* 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
|
status_t
|
||||||
BTree::PreviousLeaf(Path* path) const
|
BTree::PreviousLeaf(Path* path) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ public:
|
|||||||
|
|
||||||
status_t PreviousLeaf(Path* path) const;
|
status_t PreviousLeaf(Path* path) const;
|
||||||
status_t NextLeaf(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; }
|
Volume* SystemVolume() const { return fVolume; }
|
||||||
status_t SetRoot(off_t logical, fsblock_t* block);
|
status_t SetRoot(off_t logical, fsblock_t* block);
|
||||||
@@ -181,6 +187,7 @@ public:
|
|||||||
uint32* _size = NULL, uint32* _offset = NULL);
|
uint32* _size = NULL, uint32* _offset = NULL);
|
||||||
status_t GetEntry(int slot, btrfs_key* _key, void** _value,
|
status_t GetEntry(int slot, btrfs_key* _key, void** _value,
|
||||||
uint32* _size = NULL, uint32* _offset = NULL);
|
uint32* _size = NULL, uint32* _offset = NULL);
|
||||||
|
status_t SetEntry(int slot, const btrfs_entry& entry, void* value);
|
||||||
|
|
||||||
int Move(int level, int step);
|
int Move(int level, int step);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user