From 84bc447cae639842c6c3b7fe2d28bd52e2384eab Mon Sep 17 00:00:00 2001 From: hyche Date: Tue, 29 Aug 2017 02:07:52 +0700 Subject: [PATCH] BTRFS: Implement InsertEntries() that will insert consecutive items and its data. Signed-off-by: Augustin Cavalier --- src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 78 +++++++++++++++++++++++++ src/add-ons/kernel/file_systems/btrfs/BTree.h | 7 +++ 2 files changed, 85 insertions(+) diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp index 39e1e9475f..46325a6858 100644 --- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp @@ -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 { diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h index 57ba503662..839681da4a 100644 --- a/src/add-ons/kernel/file_systems/btrfs/BTree.h +++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h @@ -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); -- 2.11.4.GIT