Ticket #13612: btrfs.patchset4

File btrfs.patchset4, 81.6 KB (added by hyche, 7 years ago)
Line 
1From b042ddd0ee6c932d9133d8fbaf2dfa8a9b73236e Mon Sep 17 00:00:00 2001
2From: hyche <cvghy116@gmail.com>
3Date: Thu, 17 Aug 2017 23:58:52 +0700
4Subject: [PATCH 01/21] BTRFS: Fix mismatched type of index in inode_ref item.
5
6---
7 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 4 ++--
8 1 file changed, 2 insertions(+), 2 deletions(-)
9
10diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
11index a6b4963..59f58e2 100644
12--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
13+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
14@@ -294,11 +294,11 @@ struct btrfs_inode {
15
16
17 struct btrfs_inode_ref {
18- uint8 index;
19+ uint64 index;
20 uint16 name_length;
21 uint8 name[];
22
23- uint8 Index() const { return index; }
24+ uint64 Index() const { return index; }
25 uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
26 } _PACKED;
27
28--
292.7.4
30
31
32From f5af1ee6e34de4ac1ea2148091d15150308dc9ef Mon Sep 17 00:00:00 2001
33From: hyche <cvghy116@gmail.com>
34Date: Mon, 21 Aug 2017 00:36:07 +0700
35Subject: [PATCH 02/21] BTRFS: Fix memory leak
36
37Missing delete for some tree roots.
38---
39 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 4 ++++
40 1 file changed, 4 insertions(+)
41
42diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
43index c219d40..3ed2f2d 100644
44--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
45+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
46@@ -439,12 +439,16 @@ status_t
47 Volume::Unmount()
48 {
49 TRACE("Volume::Unmount()\n");
50+ delete fRootTree;
51 delete fExtentTree;
52+ delete fChunkTree;
53 delete fChecksumTree;
54 delete fFSTree;
55 delete fDevTree;
56 delete fExtentAllocator;
57+ fRootTree = NULL;
58 fExtentTree = NULL;
59+ fChunkTree = NULL;
60 fChecksumTree = NULL;
61 fFSTree = NULL;
62 fDevTree = NULL;
63--
642.7.4
65
66
67From 43e1083f2ec1e738d71152e8b3fb0c5a7bebd39d Mon Sep 17 00:00:00 2001
68From: hyche <cvghy116@gmail.com>
69Date: Thu, 24 Aug 2017 01:25:09 +0700
70Subject: [PATCH 03/21] block_cache: Implement cache_has_block_in_transaction
71 function that will check the existence of block in one specific transaction.
72
73---
74 headers/os/drivers/fs_cache.h | 1 +
75 headers/private/fs_shell/fssh_api_wrapper.h | 1 +
76 headers/private/fs_shell/fssh_fs_cache.h | 2 ++
77 src/system/kernel/cache/block_cache.cpp | 15 +++++++++++++++
78 src/tools/fs_shell/block_cache.cpp | 14 ++++++++++++++
79 5 files changed, 33 insertions(+)
80
81diff --git a/headers/os/drivers/fs_cache.h b/headers/os/drivers/fs_cache.h
82index 9a71a5b..8c8193c 100644
83--- a/headers/os/drivers/fs_cache.h
84+++ b/headers/os/drivers/fs_cache.h
85@@ -53,6 +53,7 @@ extern status_t cache_next_block_in_transaction(void *cache, int32 id,
86 extern int32 cache_blocks_in_transaction(void *cache, int32 id);
87 extern int32 cache_blocks_in_main_transaction(void *cache, int32 id);
88 extern int32 cache_blocks_in_sub_transaction(void *cache, int32 id);
89+extern bool cache_has_block_in_transaction(void* cache, int32 id, off_t blockNumber);
90
91 /* block cache */
92 extern void block_cache_delete(void *cache, bool allowWrites);
93diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h
94index 233f8b4..7c1e0b3 100644
95--- a/headers/private/fs_shell/fssh_api_wrapper.h
96+++ b/headers/private/fs_shell/fssh_api_wrapper.h
97@@ -835,6 +835,7 @@
98 #define cache_blocks_in_transaction fssh_cache_blocks_in_transaction
99 #define cache_blocks_in_main_transaction fssh_cache_blocks_in_main_transaction
100 #define cache_blocks_in_sub_transaction fssh_cache_blocks_in_sub_transaction
101+#define cache_has_block_in_transaction fssh_cache_has_block_in_transaction
102
103 /* block cache */
104 #define block_cache_delete fssh_block_cache_delete
105diff --git a/headers/private/fs_shell/fssh_fs_cache.h b/headers/private/fs_shell/fssh_fs_cache.h
106index 88cc9a3..c27052c 100644
107--- a/headers/private/fs_shell/fssh_fs_cache.h
108+++ b/headers/private/fs_shell/fssh_fs_cache.h
109@@ -62,6 +62,8 @@ extern int32_t fssh_cache_blocks_in_main_transaction(void *_cache,
110 int32_t id);
111 extern int32_t fssh_cache_blocks_in_sub_transaction(void *_cache,
112 int32_t id);
113+extern bool fssh_cache_has_block_in_transaction(void *_cache,
114+ int32_t id, fssh_off_t blockNumber);
115
116 /* block cache */
117 extern void fssh_block_cache_delete(void *_cache, bool allowWrites);
118diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp
119index 9482bec..5d76a79 100644
120--- a/src/system/kernel/cache/block_cache.cpp
121+++ b/src/system/kernel/cache/block_cache.cpp
122@@ -3301,6 +3301,21 @@ cache_blocks_in_sub_transaction(void* _cache, int32 id)
123 }
124
125
126+/*! Check if block is in transaction
127+*/
128+bool
129+cache_has_block_in_transaction(void* _cache, int32 id, off_t blockNumber)
130+{
131+ block_cache* cache = (block_cache*)_cache;
132+ TransactionLocker locker(cache);
133+
134+ cached_block* block = cache->hash->Lookup(blockNumber);
135+
136+ return (block != NULL && block->transaction != NULL
137+ && block->transaction->id == id);
138+}
139+
140+
141 // #pragma mark - public block cache API
142
143
144diff --git a/src/tools/fs_shell/block_cache.cpp b/src/tools/fs_shell/block_cache.cpp
145index 461e0bc..26132ec 100644
146--- a/src/tools/fs_shell/block_cache.cpp
147+++ b/src/tools/fs_shell/block_cache.cpp
148@@ -1462,6 +1462,20 @@ fssh_cache_blocks_in_sub_transaction(void* _cache, int32_t id)
149 }
150
151
152+bool
153+fssh_cache_has_block_in_transaction(void* _cache, int32_t id,
154+ fssh_off_t blockNumber)
155+{
156+ block_cache* cache = (block_cache*)_cache;
157+ MutexLocker locker(&cache->lock);
158+
159+ cached_block* block = (cached_block*)hash_lookup(cache->hash, &blockNumber);
160+
161+ return (block != NULL && block->transaction != NULL
162+ && block->transaction->id == id);
163+}
164+
165+
166 // #pragma mark - public block cache API
167
168
169--
1702.7.4
171
172
173From 1f3ca539befd0308eaf4ce6aa11c36cf807a2524 Mon Sep 17 00:00:00 2001
174From: hyche <cvghy116@gmail.com>
175Date: Thu, 24 Aug 2017 01:38:54 +0700
176Subject: [PATCH 04/21] BTRFS: Implement a simple journaling approach, this is
177 not finished and mostly satisfy the need for passing Transaction object for
178 many functions.
179
180Some details about the current Journal:
181* Journal can only end transaction.
182* It holds a transaction id of fs (fCurrentGeneration) that increments each time a transaction starts.
183* _TransactionWritten now just printing message.
184---
185 src/add-ons/kernel/file_systems/btrfs/Jamfile | 1 +
186 src/add-ons/kernel/file_systems/btrfs/Journal.cpp | 162 ++++++++++++++++++++++
187 src/add-ons/kernel/file_systems/btrfs/Journal.h | 57 ++++++++
188 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 8 ++
189 src/add-ons/kernel/file_systems/btrfs/Volume.h | 4 +
190 src/tools/btrfs_shell/Jamfile | 1 +
191 6 files changed, 233 insertions(+)
192 create mode 100644 src/add-ons/kernel/file_systems/btrfs/Journal.cpp
193 create mode 100644 src/add-ons/kernel/file_systems/btrfs/Journal.h
194
195diff --git a/src/add-ons/kernel/file_systems/btrfs/Jamfile b/src/add-ons/kernel/file_systems/btrfs/Jamfile
196index 78ba20c..1c76f14 100644
197--- a/src/add-ons/kernel/file_systems/btrfs/Jamfile
198+++ b/src/add-ons/kernel/file_systems/btrfs/Jamfile
199@@ -18,6 +18,7 @@ KernelAddon btrfs :
200 DirectoryIterator.cpp
201 ExtentAllocator.cpp
202 Inode.cpp
203+ Journal.cpp
204 Volume.cpp
205 : kernel_libz.a
206 ;
207diff --git a/src/add-ons/kernel/file_systems/btrfs/Journal.cpp b/src/add-ons/kernel/file_systems/btrfs/Journal.cpp
208new file mode 100644
209index 0000000..ed505d6
210--- /dev/null
211+++ b/src/add-ons/kernel/file_systems/btrfs/Journal.cpp
212@@ -0,0 +1,162 @@
213+#include "Journal.h"
214+
215+
216+//#define TRACE_BTRFS
217+#ifdef TRACE_BTRFS
218+# define TRACE(x...) dprintf("\33[34mbtrfs:\33[0m " x)
219+#else
220+# define TRACE(x...) ;
221+#endif
222+# define ERROR(x...) dprintf("\33[34mbtrfs:\33[0m " x)
223+
224+
225+Journal::Journal(Volume* volume)
226+ :
227+ fVolume(volume),
228+ fOwner(NULL),
229+ fTransactionID(0),
230+ fCurrentGeneration(volume->SuperBlock().Generation())
231+{
232+ recursive_lock_init(&fLock, "btrfs journal");
233+}
234+
235+
236+Journal::~Journal()
237+{
238+ recursive_lock_destroy(&fLock);
239+}
240+
241+
242+/*static*/ void
243+Journal::_TransactionWritten(int32 transactionID, int32 event, void* _journal)
244+{
245+ TRACE("TRANSACTION WRITTEN id %i\n", transactionID);
246+}
247+
248+
249+status_t
250+Journal::_TransactionDone(bool success)
251+{
252+ if (!success) {
253+ cache_abort_transaction(fVolume->BlockCache(), fTransactionID);
254+ return B_OK;
255+ }
256+ cache_end_transaction(fVolume->BlockCache(), fTransactionID,
257+ &_TransactionWritten, this);
258+ //cache_sync_transaction(fVolume->BlockCache(), fTransactionID);
259+ return B_OK;
260+}
261+
262+
263+status_t
264+Journal::Lock(Transaction* owner)
265+{
266+ status_t status = recursive_lock_lock(&fLock);
267+ if (status != B_OK)
268+ return status;
269+ if (recursive_lock_get_recursion(&fLock) > 1) {
270+ // we'll just use the current transaction again
271+ return B_OK;
272+ }
273+
274+
275+ if (owner != NULL)
276+ owner->SetParent(fOwner);
277+
278+ fOwner = owner;
279+
280+ if (fOwner != NULL) {
281+ fTransactionID = cache_start_transaction(fVolume->BlockCache());
282+
283+ if (fTransactionID < B_OK) {
284+ recursive_lock_unlock(&fLock);
285+ return fTransactionID;
286+ }
287+ fCurrentGeneration++;
288+ TRACE("Journal::Lock() start transaction id: %i\n", fTransactionID);
289+ }
290+
291+ return B_OK;
292+}
293+
294+
295+status_t
296+Journal::UnLock(Transaction* owner, bool success)
297+{
298+ if (recursive_lock_get_recursion(&fLock) == 1) {
299+ if (owner != NULL) {
300+ status_t status = _TransactionDone(success);
301+ if (status != B_OK)
302+ return status;
303+ fOwner = owner->Parent();
304+ } else {
305+ fOwner = NULL;
306+ }
307+ }
308+ recursive_lock_unlock(&fLock);
309+ return B_OK;
310+}
311+
312+
313+// Transaction
314+
315+
316+Transaction::Transaction(Volume* volume)
317+ :
318+ fJournal(NULL),
319+ fParent(NULL)
320+{
321+ Start(volume);
322+}
323+
324+
325+Transaction::Transaction()
326+ :
327+ fJournal(NULL),
328+ fParent(NULL)
329+{
330+}
331+
332+
333+Transaction::~Transaction()
334+{
335+ if (fJournal != NULL) {
336+ fJournal->UnLock(this, false);
337+ }
338+}
339+
340+
341+bool
342+Transaction::HasBlock(fsblock_t blockNumber) const
343+{
344+ return cache_has_block_in_transaction(fJournal->GetVolume()->BlockCache(),
345+ ID(), blockNumber);
346+}
347+
348+
349+status_t
350+Transaction::Start(Volume* volume)
351+{
352+ if (fJournal != NULL)
353+ return B_OK;
354+
355+ fJournal = volume->GetJournal();
356+ if (fJournal != NULL && fJournal->Lock(this) == B_OK) {
357+ return B_OK;
358+ }
359+ fJournal = NULL;
360+ return B_ERROR;
361+}
362+
363+
364+status_t
365+Transaction::Done()
366+{
367+ status_t status = B_OK;
368+ if (fJournal != NULL) {
369+ status = fJournal->UnLock(this, true);
370+ if (status == B_OK)
371+ fJournal = NULL;
372+ }
373+ return status;
374+}
375diff --git a/src/add-ons/kernel/file_systems/btrfs/Journal.h b/src/add-ons/kernel/file_systems/btrfs/Journal.h
376new file mode 100644
377index 0000000..a6272c3
378--- /dev/null
379+++ b/src/add-ons/kernel/file_systems/btrfs/Journal.h
380@@ -0,0 +1,57 @@
381+#ifndef JOURNAL_H
382+#define JOURNAL_H
383+
384+
385+#include "Volume.h"
386+
387+class Transaction;
388+
389+
390+class Journal {
391+public:
392+ Journal(Volume* volume);
393+ ~Journal();
394+
395+ Volume* GetVolume() const { return fVolume; }
396+ Transaction* CurrentTransaction() const { return fOwner; }
397+ uint64 SystemTransactionID() const
398+ { return fCurrentGeneration; }
399+ int32 TransactionID() const { return fTransactionID; }
400+ status_t Lock(Transaction* owner);
401+ status_t UnLock(Transaction* owner, bool success);
402+
403+private:
404+ static void _TransactionWritten(int32 transactionID, int32 event,
405+ void* _journal);
406+ status_t _TransactionDone(bool success);
407+
408+private:
409+ Volume* fVolume;
410+ recursive_lock fLock;
411+ Transaction* fOwner;
412+ int32 fTransactionID;
413+ uint64 fCurrentGeneration;
414+};
415+
416+
417+class Transaction {
418+public:
419+ Transaction(Volume* volume);
420+ Transaction();
421+ ~Transaction();
422+
423+ int32 ID() const { return fJournal->TransactionID(); }
424+ uint64 SystemID() const
425+ { return fJournal->SystemTransactionID(); }
426+ bool HasBlock(fsblock_t blockNumber) const;
427+ Transaction* Parent() const { return fParent; }
428+ void SetParent(Transaction* parent) { fParent = parent; }
429+ status_t Start(Volume* volume);
430+ status_t Done();
431+private:
432+ Journal* fJournal;
433+ Transaction* fParent;
434+};
435+
436+
437+#endif // JOURNAL_H
438diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
439index 3ed2f2d..ee2cf11 100644
440--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
441+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
442@@ -13,6 +13,7 @@
443 #include "CachedBlock.h"
444 #include "Chunk.h"
445 #include "Inode.h"
446+#include "Journal.h"
447 #include "ExtentAllocator.h"
448
449
450@@ -387,6 +388,11 @@ Volume::Mount(const char* deviceName, uint32 flags)
451 fChecksumTree->SetRoot(root->LogicalAddress(), NULL);
452 free(root);
453
454+ // Initialize Journal
455+ fJournal = new(std::nothrow) Journal(this);
456+ if (fJournal == NULL)
457+ return B_NO_MEMORY;
458+
459 // Initialize ExtentAllocator;
460 fExtentAllocator = new(std::nothrow) ExtentAllocator(this);
461 if (fExtentAllocator == NULL)
462@@ -445,6 +451,7 @@ Volume::Unmount()
463 delete fChecksumTree;
464 delete fFSTree;
465 delete fDevTree;
466+ delete fJournal;
467 delete fExtentAllocator;
468 fRootTree = NULL;
469 fExtentTree = NULL;
470@@ -452,6 +459,7 @@ Volume::Unmount()
471 fChecksumTree = NULL;
472 fFSTree = NULL;
473 fDevTree = NULL;
474+ fJournal = NULL;
475 fExtentAllocator = NULL;
476
477 TRACE("Volume::Unmount(): Putting root node\n");
478diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
479index a4b292c..4f9acf5 100644
480--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
481+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
482@@ -17,6 +17,8 @@ enum volume_flags {
483 class BTree;
484 class Chunk;
485 class Inode;
486+class Journal;
487+class Transaction;
488 class ExtentAllocator;
489
490
491@@ -46,6 +48,7 @@ public:
492 uint32 SectorSize() const { return fSectorSize; }
493 uint32 BlockSize() const { return fBlockSize; }
494 Chunk* SystemChunk() const { return fChunk; }
495+ Journal* GetJournal() const { return fJournal; }
496 ExtentAllocator* GetAllocator() const { return fExtentAllocator; }
497
498 btrfs_super_block& SuperBlock() { return fSuperBlock; }
499@@ -76,6 +79,7 @@ private:
500
501 ExtentAllocator* fExtentAllocator;
502 Chunk* fChunk;
503+ Journal* fJournal;
504 BTree* fChunkTree;
505 BTree* fRootTree;
506 BTree* fDevTree;
507diff --git a/src/tools/btrfs_shell/Jamfile b/src/tools/btrfs_shell/Jamfile
508index 99231c8..8ec1718 100644
509--- a/src/tools/btrfs_shell/Jamfile
510+++ b/src/tools/btrfs_shell/Jamfile
511@@ -44,6 +44,7 @@ local btrfsSources =
512 DirectoryIterator.cpp
513 ExtentAllocator.cpp
514 Inode.cpp
515+ Journal.cpp
516 Volume.cpp
517 kernel_interface.cpp
518 ;
519--
5202.7.4
521
522
523From 564f759fbb57a2e38cef74deefe2ece8388c4353 Mon Sep 17 00:00:00 2001
524From: hyche <cvghy116@gmail.com>
525Date: Thu, 24 Aug 2017 02:02:17 +0700
526Subject: [PATCH 05/21] BTRFS: Implement GetNewBlock() function that will find
527 the logical address for allocating and convert it to physical block.
528
529---
530 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 14 ++++++++++++++
531 src/add-ons/kernel/file_systems/btrfs/Volume.h | 3 +++
532 2 files changed, 17 insertions(+)
533
534diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
535index ee2cf11..5a86ca2 100644
536--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
537+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
538@@ -534,6 +534,20 @@ Volume::FindBlock(off_t logical, off_t& physical)
539 }
540
541
542+/* Wrapper function for allocating new block
543+ */
544+status_t
545+Volume::GetNewBlock(uint64& logical, fsblock_t& physical, uint64 start,
546+ uint64 flags)
547+{
548+ status_t status = fExtentAllocator->AllocateTreeBlock(logical, start, flags);
549+ if (status != B_OK)
550+ return status;
551+
552+ return FindBlock(logical, physical);
553+}
554+
555+
556 // #pragma mark - Disk scanning and initialization
557
558
559diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
560index 4f9acf5..11b4deb 100644
561--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
562+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
563@@ -62,6 +62,9 @@ public:
564
565 status_t FindBlock(off_t logical, fsblock_t& physical);
566 status_t FindBlock(off_t logical, off_t& physical);
567+ status_t GetNewBlock(uint64& logical, fsblock_t& physical,
568+ uint64 start = (uint64)-1,
569+ uint64 flags = BTRFS_BLOCKGROUP_FLAG_METADATA);
570
571 private:
572 mutex fLock;
573--
5742.7.4
575
576
577From f9aa2fb0339c2e32325de9959ed1deab1abe0feb Mon Sep 17 00:00:00 2001
578From: hyche <cvghy116@gmail.com>
579Date: Thu, 24 Aug 2017 02:22:02 +0700
580Subject: [PATCH 06/21] BTRFS: Implement some space relevant helpers.
581
582---
583 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 58 +++++++++++++++++++++++++
584 src/add-ons/kernel/file_systems/btrfs/BTree.h | 9 +++-
585 2 files changed, 65 insertions(+), 2 deletions(-)
586
587diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
588index bf93bf3..9e43ad8 100644
589--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
590+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
591@@ -140,6 +140,64 @@ BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type)
592 }
593
594
595+/*
596+ * calculate used space except the header.
597+ * type is only for leaf node
598+ * type 1: only item space
599+ * type 2: only item data space
600+ * type 3: both type 1 and 2
601+ */
602+int
603+BTree::Node::_CalculateSpace(uint32 from, uint32 to, uint8 type) const
604+{
605+ if (to < from || to >= ItemCount())
606+ return 0;
607+
608+ if (Level() != 0)
609+ return sizeof(btrfs_index) * (to - from + 1);
610+
611+ uint32 result = 0;
612+ if ((type & 1) == 1) {
613+ result += sizeof(btrfs_entry) * (to - from + 1);
614+ }
615+ if ((type & 2) == 2) {
616+ result += Item(from)->Offset() + Item(from)->Size()
617+ - Item(to)->Offset();
618+ }
619+
620+ return result;
621+}
622+
623+
624+int
625+BTree::Node::SpaceUsed() const
626+{
627+ if (Level() == 0)
628+ return _CalculateSpace(0, ItemCount() - 1, 3);
629+ return _CalculateSpace(0, ItemCount() - 1, 0);
630+}
631+
632+
633+int
634+BTree::Node::SpaceLeft() const
635+{
636+ return fVolume->BlockSize() - SpaceUsed() - sizeof(btrfs_header);
637+}
638+
639+
640+status_t
641+BTree::Node::_SpaceCheck(int length) const
642+{
643+ // this is a little bit weird here because we can't find
644+ // any suitable error code
645+ if (length < 0 && std::abs(length) >= SpaceUsed())
646+ return B_DIRECTORY_NOT_EMPTY; // not enough data to delete
647+ if (length > 0 && length >= SpaceLeft())
648+ return B_DEVICE_FULL; // no spare space
649+ return B_OK;
650+}
651+
652+
653 // #pragma mark - BTree::Path implementation
654
655
656diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
657index d44a401..f1c0e5b 100644
658--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
659+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
660@@ -128,18 +128,23 @@ public:
661
662 void SetTo(off_t block);
663 void SetToWritable(off_t block, int32 transactionId, bool empty);
664+ int SpaceUsed() const;
665+ int SpaceLeft() const;
666
667 off_t BlockNum() const { return fBlockNumber;}
668 bool IsWritable() const { return fWritable; }
669
670 status_t SearchSlot(const btrfs_key& key, int* slot,
671 btree_traversing type) const;
672- private:
673+ private:
674 Node(const Node&);
675 Node& operator=(const Node&);
676 //no implementation
677
678- btrfs_stream* fNode;
679+ status_t _SpaceCheck(int length) const;
680+ int _CalculateSpace(uint32 from, uint32 to, uint8 type = 1) const;
681+
682+ btrfs_stream* fNode;
683 Volume* fVolume;
684 off_t fBlockNumber;
685 bool fWritable;
686--
6872.7.4
688
689
690From 67e4992def5a8229348e236173523b8742ad5e00 Mon Sep 17 00:00:00 2001
691From: hyche <cvghy116@gmail.com>
692Date: Thu, 24 Aug 2017 02:26:49 +0700
693Subject: [PATCH 07/21] BTRFS: Implement some copy relevant helpers.
694
695Copy() copys data from other node, MoveEntries() changes data on the current node.
696---
697 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 119 ++++++++++++++++++++++++
698 src/add-ons/kernel/file_systems/btrfs/BTree.h | 5 +
699 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 1 +
700 3 files changed, 125 insertions(+)
701
702diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
703index 9e43ad8..6b3c17c 100644
704--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
705+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
706@@ -185,6 +185,30 @@ BTree::Node::SpaceLeft() const
707 }
708
709
710+void
711+BTree::Node::_Copy(const Node* origin, uint32 at, uint32 from, uint32 to,
712+ int length) const
713+{
714+ TRACE("Node::_Copy() at: %d from: %d to: %d length: %d\n",
715+ at, from, to, length);
716+
717+ if (Level() == 0) {
718+ memcpy(Item(at), origin->Item(from), origin->_CalculateSpace(from, to));
719+ // Item offset of copied node must be changed to get the
720+ // item data offset correctly. length can be zero
721+ // but let it there doesn't harm anything.
722+ for (uint32 i = at; i - at <= to - from; ++i)
723+ Item(i)->SetOffset(Item(i)->Offset() - length);
724+
725+ memcpy(ItemData(at + to - from), origin->ItemData(to),
726+ origin->_CalculateSpace(from, to, 2));
727+ } else {
728+ memcpy(Index(at), origin->Index(from),
729+ origin->_CalculateSpace(from, to));
730+ }
731+}
732+
733+
734 status_t
735 BTree::Node::_SpaceCheck(int length) const
736 {
737@@ -198,6 +222,101 @@ BTree::Node::_SpaceCheck(int length) const
738 }
739
740
741+/*
742+ * copy node header, items and items data
743+ * length is size to insert/remove
744+ * if node is a internal node, length isnt used
745+ * length = 0: Copy a whole
746+ * length < 0: removing
747+ * length > 0: inserting
748+ */
749+status_t
750+BTree::Node::Copy(const Node* origin, uint32 start, uint32 end, int length)
751+ const
752+{
753+ status_t status = origin->_SpaceCheck(length);
754+ if (status != B_OK)
755+ return status;
756+
757+ memcpy(fNode, origin->fNode, sizeof(btrfs_header));
758+ if (length == 0) {
759+ // like removing [0, start - 1] and keeping [start, end]
760+ length = -origin->_CalculateSpace(0, start - 1, 2);
761+ _Copy(origin, 0, start, end, length);
762+ } else if (length < 0) {
763+ //removing all items in [start, end]
764+ if (start > 0)
765+ _Copy(origin, 0, 0, start - 1, 0); // <-- [start,...
766+ if (end + 1 < origin->ItemCount()) {
767+ // ..., end] -->
768+ // we only care data size
769+ length += origin->_CalculateSpace(start, end);
770+ _Copy(origin, start, end + 1, origin->ItemCount() - 1, length);
771+ }
772+ } else {
773+ //inserting in [start, end] - make a hole for later
774+ if (start > 0)
775+ _Copy(origin, 0, 0, start - 1, 0);
776+ if (start < origin->ItemCount()) {
777+ length -= origin->_CalculateSpace(start, end);
778+ _Copy(origin, end + 1, start, origin->ItemCount() - 1, length);
779+ }
780+ }
781+
782+ return B_OK;
783+}
784+
785+
786+/* Like copy but here we use memmove on current node.
787+ */
788+status_t
789+BTree::Node::MoveEntries(uint32 start, uint32 end, int length) const
790+{
791+ status_t status = _SpaceCheck(length);
792+ if (status != B_OK || length == 0/*B_OK*/)
793+ return status;
794+
795+ int entrySize = sizeof(btrfs_entry);
796+ if (Level() != 0)
797+ entrySize = sizeof(btrfs_index);
798+
799+ uint8* base = (uint8*)fNode + sizeof(btrfs_header);
800+ end++;
801+ if (length < 0) {
802+ // removing [start, end]
803+ TRACE("Node::MoveEntries() removing ... start %" B_PRIu32 " end %"
804+ B_PRIu32 " length %i\n", start, end, length);
805+ length += _CalculateSpace(start, end - 1);
806+ } else {
807+ // length > 0
808+ // inserting into [start, end] - make room for later
809+ TRACE("Node::MoveEntries() inserting ... start %" B_PRIu32 " end %"
810+ B_PRIu32 " length %i\n", start, end, length);
811+ length -= _CalculateSpace(start, end - 1);
812+ std::swap(start, end);
813+ }
814+
815+ if (end >= ItemCount())
816+ return B_OK;
817+
818+ int dataSize = _CalculateSpace(end, ItemCount() - 1, 2);
819+ // moving items/block pointers
820+ memmove(base + start * entrySize, base + end * entrySize,
821+ _CalculateSpace(end, ItemCount() - 1));
822+ if (Level() == 0) {
823+ // moving item data
824+ int num = start - end;
825+ for(uint32 i = start; i < ItemCount() + num; ++i)
826+ Item(i)->SetOffset(Item(i)->Offset() - length);
827+
828+ memmove(ItemData(ItemCount() - 1) - length, ItemData(ItemCount() - 1),
829+ dataSize);
830+ }
831+
832+ return B_OK;
833+}
834+
835+
836 // #pragma mark - BTree::Path implementation
837
838
839diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
840index f1c0e5b..14e675c 100644
841--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
842+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
843@@ -133,6 +133,9 @@ public:
844
845 off_t BlockNum() const { return fBlockNumber;}
846 bool IsWritable() const { return fWritable; }
847+ status_t Copy(const Node* origin, uint32 start, uint32 end,
848+ int length) const;
849+ status_t MoveEntries(uint32 start, uint32 end, int length) const;
850
851 status_t SearchSlot(const btrfs_key& key, int* slot,
852 btree_traversing type) const;
853@@ -141,6 +144,8 @@ public:
854 Node& operator=(const Node&);
855 //no implementation
856
857+ void _Copy(const Node* origin, uint32 at, uint32 from, uint32 to,
858+ int length) const;
859 status_t _SpaceCheck(int length) const;
860 int _CalculateSpace(uint32 from, uint32 to, uint8 type = 1) const;
861
862diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
863index 59f58e2..f2010b9 100644
864--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
865+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
866@@ -132,6 +132,7 @@ struct btrfs_entry {
867 { return B_LENDIAN_TO_HOST_INT32(offset); }
868 uint32 Size() const
869 { return B_LENDIAN_TO_HOST_INT32(size); }
870+ void SetOffset(uint32 off) { offset = B_HOST_TO_LENDIAN_INT32(off); }
871 } _PACKED;
872
873
874--
8752.7.4
876
877
878From f9007088a1fb0502a328791aa47b15ab9d28d354 Mon Sep 17 00:00:00 2001
879From: hyche <cvghy116@gmail.com>
880Date: Thu, 24 Aug 2017 03:09:00 +0700
881Subject: [PATCH 08/21] BTRFS: Implement CopyOnWrite relevant functions, and
882 BTree holds new attribute that record its root level.
883
884CopyOnWrite works like this:
885* Cache original node
886* Allocating new block
887* Cache new block to be writable
888* Copy original node to new node, and changing.
889Also if a node is already be COW-ed it cannot be COW-ed again, it will be changed in-place instead.
890
891InternalCopy does CopyOnWrite all the nodes that we don't need to change anything on them.
892---
893 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 141 +++++++++++++++++++++++-
894 src/add-ons/kernel/file_systems/btrfs/BTree.h | 17 +++
895 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 12 ++
896 3 files changed, 168 insertions(+), 2 deletions(-)
897
898diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
899index 6b3c17c..39e1e94 100644
900--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
901+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
902@@ -9,6 +9,7 @@
903
904
905 #include "BTree.h"
906+#include "Journal.h"
907
908
909 //#define TRACE_BTRFS
910@@ -419,12 +420,131 @@ BTree::Path::GetEntry(int slot, btrfs_key* _key, void** _value, uint32* _size,
911 }
912
913
914+/*
915+ * Allocate and copy block and do all the changes that it can.
916+ * for now, we only copy-on-write tree block,
917+ * file data is "nocow" by default.
918+ *
919+ * o parent o
920+ * | ===> \
921+ * o x o
922+ */
923+status_t
924+BTree::Path::CopyOnWrite(Transaction& transaction, int level, uint32 start,
925+ int num, int length)
926+{
927+ Node* node = fNodes[level];
928+ if (node == NULL)
929+ return B_BAD_VALUE;
930+
931+ status_t status;
932+ if (transaction.HasBlock(node->BlockNum())) {
933+ // cow-ed block can not be cow-ed again
934+ status = node->MoveEntries(start, start + num - 1, length);
935+ if (status != B_OK)
936+ return status;
937+
938+ node->SetGeneration(transaction.SystemID());
939+ if (length < 0)
940+ node->SetItemCount(node->ItemCount() - num);
941+ else if (length > 0)
942+ node->SetItemCount(node->ItemCount() + num);
943+
944+ return B_OK;
945+ }
946+
947+ uint64 address;
948+ fsblock_t block;
949+ status = fTree->SystemVolume()->GetNewBlock(address, block);
950+ if (status != B_OK)
951+ return status;
952+
953+ fNodes[level] = new(std::nothrow) BTree::Node(fTree->SystemVolume());
954+ if (fNodes[level] == NULL)
955+ return B_NO_MEMORY;
956+
957+ fNodes[level]->SetToWritable(block, transaction.ID(), true);
958+
959+ status = fNodes[level]->Copy(node, start, start + num - 1, length);
960+ if (status != B_OK)
961+ return status;
962+
963+ fNodes[level]->SetGeneration(transaction.SystemID());
964+ fNodes[level]->SetLogicalAddress(address);
965+ if (length < 0)
966+ fNodes[level]->SetItemCount(node->ItemCount() - num);
967+ else if (length > 0)
968+ fNodes[level]->SetItemCount(node->ItemCount() + num);
969+ else
970+ fNodes[level]->SetItemCount(num);
971+
972+ // change pointer of this node in parent
973+ int parentSlot;
974+ Node* parentNode = GetNode(level + 1, &parentSlot);
975+ if (parentNode != NULL)
976+ parentNode->Index(parentSlot)->SetLogicalAddress(address);
977+
978+ if (level == fTree->RootLevel())
979+ fTree->SetRoot(fNodes[level]);
980+
981+ delete node;
982+ return B_OK;
983+}
984+
985+
986+/* Copy-On-Write all internal nodes start from a specific level.
987+ * level > 0: to root
988+ * level <= 0: to leaf
989+ *
990+ * path cow-path path cow-path
991+ * =================================================
992+ * root cow-root root level < 0
993+ * | | |
994+ * n1 cow-n1 ...______
995+ * | | | \
996+ * n2 cow-n2 n1 cow-n1
997+ * | / | |
998+ * ...____/ n2 cow-n2
999+ * | | |
1000+ * leaf level > 0 leaf cow-leaf
1001+ */
1002+status_t
1003+BTree::Path::InternalCopy(Transaction& transaction, int level)
1004+{
1005+ if (std::abs(level) >= fTree->RootLevel())
1006+ return B_OK;
1007+
1008+ TRACE("Path::InternalCopy() level %i\n", level);
1009+ int from, to;
1010+ if (level > 0) {
1011+ from = level;
1012+ to = fTree->RootLevel();
1013+ } else {
1014+ from = 0;
1015+ to = std::abs(level);
1016+ }
1017+
1018+ Node* node = NULL;
1019+ status_t status;
1020+ while (from <= to) {
1021+ node = fNodes[from];
1022+ status = CopyOnWrite(transaction, from, 0, node->ItemCount(), 0);
1023+ from++;
1024+ if (status != B_OK)
1025+ return status;
1026+ }
1027+
1028+ return B_OK;
1029+}
1030+
1031+
1032 // #pragma mark - BTree implementation
1033
1034
1035 BTree::BTree(Volume* volume)
1036 :
1037 fRootBlock(0),
1038+ fRootLevel(0),
1039 fVolume(volume)
1040 {
1041 mutex_init(&fIteratorLock, "btrfs b+tree iterator");
1042@@ -434,6 +554,7 @@ BTree::BTree(Volume* volume)
1043 BTree::BTree(Volume* volume, btrfs_stream* stream)
1044 :
1045 fRootBlock(0),
1046+ fRootLevel(0),
1047 fVolume(volume)
1048 {
1049 mutex_init(&fIteratorLock, "btrfs b+tree iterator");
1050@@ -660,24 +781,40 @@ BTree::NextLeaf(Path* path) const
1051 }
1052
1053
1054+/* Set root infomation, to use this function root must be valid and
1055+ * exists on disk.
1056+ */
1057 status_t
1058 BTree::SetRoot(off_t logical, fsblock_t* block)
1059 {
1060 if (block != NULL) {
1061 fRootBlock = *block;
1062- //TODO: mapping physical block -> logical address
1063 } else {
1064- fLogicalRoot = logical;
1065 if (fVolume->FindBlock(logical, fRootBlock) != B_OK) {
1066 ERROR("Find() unmapped block %" B_PRId64 "\n", fRootBlock);
1067 return B_ERROR;
1068 }
1069 }
1070+
1071+ btrfs_header header;
1072+ read_pos(fVolume->Device(), fRootBlock * fVolume->BlockSize(), &header,
1073+ sizeof(btrfs_header));
1074+ fRootLevel = header.Level();
1075+ fLogicalRoot = header.LogicalAddress();
1076 return B_OK;
1077 }
1078
1079
1080 void
1081+BTree::SetRoot(Node* root)
1082+{
1083+ fRootBlock = root->BlockNum();
1084+ fLogicalRoot = root->LogicalAddress();
1085+ fRootLevel = root->Level();
1086+}
1087+
1088+
1089+void
1090 BTree::_AddIterator(TreeIterator* iterator)
1091 {
1092 MutexLocker _(fIteratorLock);
1093diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1094index 14e675c..57ba503 100644
1095--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1096+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1097@@ -27,6 +27,9 @@ enum btree_traversing {
1098 };
1099
1100
1101+class Transaction;
1102+
1103+
1104 // #pragma mark - in-memory structures
1105
1106
1107@@ -44,6 +47,7 @@ struct node_and_key {
1108 class BTree {
1109 public:
1110 class Path;
1111+ class Node;
1112
1113 public:
1114 BTree(Volume* volume);
1115@@ -71,8 +75,10 @@ public:
1116
1117 Volume* SystemVolume() const { return fVolume; }
1118 status_t SetRoot(off_t logical, fsblock_t* block);
1119+ void SetRoot(Node* root);
1120 fsblock_t RootBlock() const { return fRootBlock; }
1121 off_t LogicalRoot() const { return fLogicalRoot; }
1122+ uint8 RootLevel() const { return fRootLevel; }
1123
1124 private:
1125 BTree(const BTree& other);
1126@@ -90,6 +96,7 @@ private:
1127
1128 fsblock_t fRootBlock;
1129 off_t fLogicalRoot;
1130+ uint8 fRootLevel;
1131 Volume* fVolume;
1132 mutex fIteratorLock;
1133 SinglyLinkedList<TreeIterator> fIterators;
1134@@ -114,6 +121,12 @@ public:
1135 { return fNode->header.ItemCount(); }
1136 uint8 Level() const
1137 { return fNode->header.Level(); }
1138+ void SetLogicalAddress(uint64 address)
1139+ { fNode->header.SetLogicalAddress(address); }
1140+ void SetGeneration(uint64 generation)
1141+ { fNode->header.SetGeneration(generation); }
1142+ void SetItemCount(uint32 itemCount)
1143+ { fNode->header.SetItemCount(itemCount); }
1144
1145 btrfs_index* Index(uint32 i) const
1146 { return &fNode->index[i]; }
1147@@ -171,6 +184,10 @@ public:
1148
1149 int Move(int level, int step);
1150
1151+ status_t CopyOnWrite(Transaction& transaction, int level,
1152+ uint32 start, int num, int length);
1153+ status_t InternalCopy(Transaction& transaction, int level);
1154+
1155 BTree* Tree() const { return fTree; }
1156 private:
1157 Path(const Path&);
1158diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1159index f2010b9..faf2a68 100644
1160--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1161+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1162@@ -110,6 +110,13 @@ struct btrfs_header {
1163 uint32 ItemCount() const
1164 { return B_LENDIAN_TO_HOST_INT32(item_count); }
1165 uint8 Level() const { return level; }
1166+
1167+ void SetLogicalAddress(uint64 logical)
1168+ { logical_address = B_HOST_TO_LENDIAN_INT64(logical); }
1169+ void SetGeneration(uint64 gen)
1170+ { generation = B_HOST_TO_LENDIAN_INT64(gen); }
1171+ void SetItemCount(uint32 itemCount)
1172+ { item_count = B_HOST_TO_LENDIAN_INT32(itemCount); }
1173 } _PACKED;
1174
1175
1176@@ -121,6 +128,11 @@ struct btrfs_index {
1177 { return B_LENDIAN_TO_HOST_INT64(logical_address); }
1178 uint64 Generation() const
1179 { return B_LENDIAN_TO_HOST_INT64(generation); }
1180+
1181+ void SetLogicalAddress(uint64 address)
1182+ { logical_address = B_HOST_TO_LENDIAN_INT64(address); }
1183+ void SetGeneration(uint64 gen)
1184+ { generation = B_HOST_TO_LENDIAN_INT64(gen); }
1185 } _PACKED;
1186
1187
1188--
11892.7.4
1190
1191
1192From 07d812543cebe36fa0ff48fc0c78bd414a07480b Mon Sep 17 00:00:00 2001
1193From: hyche <cvghy116@gmail.com>
1194Date: Sun, 27 Aug 2017 05:13:22 +0700
1195Subject: [PATCH 09/21] fs_shell: Added socket filetype.
1196
1197---
1198 headers/private/fs_shell/fssh_api_wrapper.h | 15 ++++++++-------
1199 headers/private/fs_shell/fssh_stat.h | 1 +
1200 2 files changed, 9 insertions(+), 7 deletions(-)
1201
1202diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h
1203index 7c1e0b3..88a1441 100644
1204--- a/headers/private/fs_shell/fssh_api_wrapper.h
1205+++ b/headers/private/fs_shell/fssh_api_wrapper.h
1206@@ -1277,13 +1277,14 @@
1207 #define S_LINK_AUTO_DELETE FSSH_S_LINK_AUTO_DELETE
1208
1209 /* standard file types */
1210-#define S_IFMT FSSH_S_IFMT
1211-#define S_IFLNK FSSH_S_IFLNK
1212-#define S_IFREG FSSH_S_IFREG
1213-#define S_IFBLK FSSH_S_IFBLK
1214-#define S_IFDIR FSSH_S_IFDIR
1215-#define S_IFCHR FSSH_S_IFCHR
1216-#define S_IFIFO FSSH_S_IFIFO
1217+#define S_IFMT FSSH_S_IFMT
1218+#define S_IFSOCK FSSH_S_IFSOCK
1219+#define S_IFLNK FSSH_S_IFLNK
1220+#define S_IFREG FSSH_S_IFREG
1221+#define S_IFBLK FSSH_S_IFBLK
1222+#define S_IFDIR FSSH_S_IFDIR
1223+#define S_IFCHR FSSH_S_IFCHR
1224+#define S_IFIFO FSSH_S_IFIFO
1225
1226 #define S_ISREG(mode) FSSH_S_ISREG(mode)
1227 #define S_ISLNK(mode) FSSH_S_ISLNK(mode)
1228diff --git a/headers/private/fs_shell/fssh_stat.h b/headers/private/fs_shell/fssh_stat.h
1229index c2a395a..4cd5af8 100644
1230--- a/headers/private/fs_shell/fssh_stat.h
1231+++ b/headers/private/fs_shell/fssh_stat.h
1232@@ -59,6 +59,7 @@ typedef struct fssh_stat fssh_struct_stat;
1233
1234 /* standard file types */
1235 #define FSSH_S_IFMT 00000170000 /* type of file */
1236+#define FSSH_S_IFSOCK 00000140000 /* socket */
1237 #define FSSH_S_IFLNK 00000120000 /* symbolic link */
1238 #define FSSH_S_IFREG 00000100000 /* regular */
1239 #define FSSH_S_IFBLK 00000060000 /* block special */
1240--
12412.7.4
1242
1243
1244From 579bc7bdc847f13226828dd304ca5c877148b4bd Mon Sep 17 00:00:00 2001
1245From: hyche <cvghy116@gmail.com>
1246Date: Sun, 27 Aug 2017 05:18:04 +0700
1247Subject: [PATCH 10/21] BTRFS: Added function to convert standard filetypes to
1248 btrfs filetypes.
1249
1250---
1251 src/add-ons/kernel/file_systems/btrfs/Utility.h | 26 +++++++++++++++++++++++++
1252 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 11 +++++++++++
1253 2 files changed, 37 insertions(+)
1254
1255diff --git a/src/add-ons/kernel/file_systems/btrfs/Utility.h b/src/add-ons/kernel/file_systems/btrfs/Utility.h
1256index 6f7430f..2c4672c 100644
1257--- a/src/add-ons/kernel/file_systems/btrfs/Utility.h
1258+++ b/src/add-ons/kernel/file_systems/btrfs/Utility.h
1259@@ -22,6 +22,32 @@ enum inode_type {
1260 };
1261
1262
1263+inline uint8
1264+get_filetype(int32 mode)
1265+{
1266+ mode &= S_IFMT;
1267+ switch (mode)
1268+ {
1269+ case S_IFSOCK:
1270+ return BTRFS_FILETYPE_SOCKET;
1271+ case S_IFLNK:
1272+ return BTRFS_FILETYPE_SYMLINK;
1273+ case S_IFREG:
1274+ return BTRFS_FILETYPE_REGULAR;
1275+ case S_IFBLK:
1276+ return BTRFS_FILETYPE_BLKDEV;
1277+ case S_IFDIR:
1278+ return BTRFS_FILETYPE_DIRECTORY;
1279+ case S_IFCHR:
1280+ return BTRFS_FILETYPE_CHRDEV;
1281+ case S_IFIFO:
1282+ return BTRFS_FILETYPE_FIFO;
1283+ default:
1284+ return BTRFS_FILETYPE_UNKNOWN;
1285+ }
1286+}
1287+
1288+
1289 /*! Converts the open mode, the open flags given to bfs_open(), into
1290 access modes, e.g. since O_RDONLY requires read access to the
1291 file, it will be converted to R_OK.
1292diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1293index faf2a68..f8b3acc 100644
1294--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1295+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1296@@ -475,6 +475,17 @@ struct btrfs_extent_data_ref {
1297 #define BTRFS_BLOCKGROUP_FLAG_RAID6 256
1298 #define BTRFS_BLOCKGROUP_FLAG_MASK 511
1299
1300+// d_type in struct dirent
1301+#define BTRFS_FILETYPE_UNKNOWN 0
1302+#define BTRFS_FILETYPE_REGULAR 1
1303+#define BTRFS_FILETYPE_DIRECTORY 2
1304+#define BTRFS_FILETYPE_CHRDEV 3 // character device
1305+#define BTRFS_FILETYPE_BLKDEV 4 // block device
1306+#define BTRFS_FILETYPE_FIFO 5 // fifo device
1307+#define BTRFS_FILETYPE_SOCKET 6
1308+#define BTRFS_FILETYPE_SYMLINK 7
1309+#define BTRFS_FILETYPE_XATTR 8 // ondisk but not user-visible
1310+
1311
1312 struct file_cookie {
1313 bigtime_t last_notification;
1314--
13152.7.4
1316
1317
1318From 49210804b9bce77ec8fe3dd0b4e6bbbf6304c183 Mon Sep 17 00:00:00 2001
1319From: hyche <cvghy116@gmail.com>
1320Date: Tue, 29 Aug 2017 02:07:52 +0700
1321Subject: [PATCH 11/21] BTRFS: Implement InsertEntries() that will insert
1322 consecutive items and its data.
1323
1324---
1325 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 78 +++++++++++++++++++++++++
1326 src/add-ons/kernel/file_systems/btrfs/BTree.h | 7 +++
1327 2 files changed, 85 insertions(+)
1328
1329diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1330index 39e1e94..46325a6 100644
1331--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1332+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1333@@ -420,6 +420,18 @@ BTree::Path::GetEntry(int slot, btrfs_key* _key, void** _value, uint32* _size,
1334 }
1335
1336
1337+status_t
1338+BTree::Path::SetEntry(int slot, const btrfs_entry& entry, void* value)
1339+{
1340+ if (slot < 0)
1341+ return B_ENTRY_NOT_FOUND;
1342+
1343+ memcpy(fNodes[0]->Item(slot), &entry, sizeof(btrfs_entry));
1344+ memcpy(fNodes[0]->ItemData(slot), value, entry.Size());
1345+ return B_OK;
1346+}
1347+
1348+
1349 /*
1350 * Allocate and copy block and do all the changes that it can.
1351 * for now, we only copy-on-write tree block,
1352@@ -702,6 +714,72 @@ BTree::FindExact(Path* path, btrfs_key& key, void** _value, uint32* _size,
1353 }
1354
1355
1356+/*
1357+ * Insert "num" of consecutive empty entries start with slot of "startKey"
1358+ * if successful return the starting slot, otherwise return error code.
1359+ */
1360+status_t
1361+BTree::MakeEntries(Transaction& transaction, Path* path,
1362+ const btrfs_key& startKey, int num, int length)
1363+{
1364+ TRACE("BTree::MakeEntries() num %i key (% " B_PRIu64 " %" B_PRIu8 " %"
1365+ B_PRIu64 ")\n", num, startKey.ObjectID(), startKey.Type(),
1366+ startKey.Offset());
1367+
1368+ status_t status = Traverse(BTREE_FORWARD, path, startKey);
1369+ if (status < B_OK)
1370+ return status;
1371+
1372+ int slot = status;
1373+ status = path->InternalCopy(transaction, 1);
1374+ if (status != B_OK)
1375+ return status;
1376+
1377+ status = path->CopyOnWrite(transaction, 0, slot, num, length);
1378+ if (status == B_DEVICE_FULL) {
1379+ // TODO: push data or split node
1380+ return status;
1381+ }
1382+
1383+ if (status != B_OK)
1384+ return status;
1385+ return slot;
1386+}
1387+
1388+
1389+/* MakeEntries and then fill in them.
1390+ */
1391+status_t
1392+BTree::InsertEntries(Transaction& transaction, Path* path,
1393+ btrfs_entry* entries, void** data, int num)
1394+{
1395+ int totalLength = sizeof(btrfs_entry) * num;
1396+ for (int i = 0; i < num; i++)
1397+ totalLength += entries[i].Size();
1398+
1399+ status_t slot = MakeEntries(transaction, path, entries[0].key, num,
1400+ totalLength);
1401+ if (slot < B_OK)
1402+ return slot;
1403+
1404+ uint32 upperLimit;
1405+ if (slot > 0) {
1406+ path->GetEntry(slot - 1, NULL, NULL, NULL, &upperLimit);
1407+ } else
1408+ upperLimit = fVolume->BlockSize() - sizeof(btrfs_header);
1409+
1410+ TRACE("BTree::InsertEntries() num: %i upper limit %" B_PRIu32 "\n", num,
1411+ upperLimit);
1412+ for (int i = 0; i < num; i++) {
1413+ upperLimit -= entries[i].Size();
1414+ entries[i].SetOffset(upperLimit);
1415+ path->SetEntry(slot + i, entries[i], data[i]);
1416+ }
1417+
1418+ return B_OK;
1419+}
1420+
1421+
1422 status_t
1423 BTree::PreviousLeaf(Path* path) const
1424 {
1425diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1426index 57ba503..839681d 100644
1427--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1428+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1429@@ -72,6 +72,12 @@ public:
1430
1431 status_t PreviousLeaf(Path* path) const;
1432 status_t NextLeaf(Path* path) const;
1433+ status_t MakeEntries(Transaction& transaction,
1434+ Path* path, const btrfs_key& startKey,
1435+ int num, int length);
1436+ status_t InsertEntries(Transaction& transaction,
1437+ Path* path, btrfs_entry* entries,
1438+ void** data, int num);
1439
1440 Volume* SystemVolume() const { return fVolume; }
1441 status_t SetRoot(off_t logical, fsblock_t* block);
1442@@ -181,6 +187,7 @@ public:
1443 uint32* _size = NULL, uint32* _offset = NULL);
1444 status_t GetEntry(int slot, btrfs_key* _key, void** _value,
1445 uint32* _size = NULL, uint32* _offset = NULL);
1446+ status_t SetEntry(int slot, const btrfs_entry& entry, void* value);
1447
1448 int Move(int level, int step);
1449
1450--
14512.7.4
1452
1453
1454From 3823e3dfa6941431edcf32113feb6d1bf0081a9c Mon Sep 17 00:00:00 2001
1455From: hyche <cvghy116@gmail.com>
1456Date: Tue, 29 Aug 2017 02:10:11 +0700
1457Subject: [PATCH 12/21] BTRFS: Implement RemoveEntries() for BTree that will
1458 remove consecutive items and its data.
1459
1460---
1461 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 37 +++++++++++++++++++++++++
1462 src/add-ons/kernel/file_systems/btrfs/BTree.h | 3 ++
1463 2 files changed, 40 insertions(+)
1464
1465diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1466index 46325a6..e5f3797 100644
1467--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1468+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1469@@ -780,6 +780,43 @@ BTree::InsertEntries(Transaction& transaction, Path* path,
1470 }
1471
1472
1473+/* Like MakeEntries, but here we remove entries instead.
1474+ * Removed data stored in _data
1475+ * May merge those functions into one.
1476+ */
1477+status_t
1478+BTree::RemoveEntries(Transaction& transaction, Path* path,
1479+ const btrfs_key& startKey, void** _data, int num)
1480+{
1481+ TRACE("BTree::RemoveEntries() num %i key (% " B_PRIu64 " %" B_PRIu8 " %"
1482+ B_PRIu64 ")\n", num, startKey.ObjectID(), startKey.Type(),
1483+ startKey.Offset());
1484+
1485+ status_t status = Traverse(BTREE_EXACT, path, startKey);
1486+ if (status < B_OK)
1487+ return status;
1488+
1489+ int slot = status;
1490+ int length = -sizeof(btrfs_entry) * num;
1491+ for (int i = 0; i < num; i++) {
1492+ uint32 itemSize;
1493+ path->GetEntry(slot + i, NULL, &_data[i], &itemSize);
1494+ length -= itemSize;
1495+ }
1496+
1497+ status = path->InternalCopy(transaction, 1);
1498+ if (status != B_OK)
1499+ return status;
1500+
1501+ status = path->CopyOnWrite(transaction, 0, slot, num, length);
1502+ if (status == B_DIRECTORY_NOT_EMPTY) {
1503+ // TODO: merge node or push data
1504+ }
1505+
1506+ return status;
1507+}
1508+
1509+
1510 status_t
1511 BTree::PreviousLeaf(Path* path) const
1512 {
1513diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1514index 839681d..1da3561 100644
1515--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1516+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1517@@ -78,6 +78,9 @@ public:
1518 status_t InsertEntries(Transaction& transaction,
1519 Path* path, btrfs_entry* entries,
1520 void** data, int num);
1521+ status_t RemoveEntries(Transaction& transaction,
1522+ Path* path, const btrfs_key& startKey,
1523+ void** _data, int num);
1524
1525 Volume* SystemVolume() const { return fVolume; }
1526 status_t SetRoot(off_t logical, fsblock_t* block);
1527--
15282.7.4
1529
1530
1531From 3636dffc13b3bd89597c34fb214c855050883c51 Mon Sep 17 00:00:00 2001
1532From: hyche <cvghy116@gmail.com>
1533Date: Tue, 29 Aug 2017 06:08:43 +0700
1534Subject: [PATCH 13/21] BTRFS: Implement Create() that allocate new Inode
1535 object.
1536
1537---
1538 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 59 +++++++++++++++++++++++++
1539 src/add-ons/kernel/file_systems/btrfs/Inode.h | 7 +++
1540 src/add-ons/kernel/file_systems/btrfs/Volume.h | 2 +
1541 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 5 +++
1542 4 files changed, 73 insertions(+)
1543
1544diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1545index 173fe19..bb3b49c 100644
1546--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1547+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1548@@ -43,6 +43,22 @@ Inode::Inode(Volume* volume, ino_t id)
1549 }
1550
1551
1552+Inode::Inode(Volume* volume, ino_t id, const btrfs_inode& item)
1553+ :
1554+ fVolume(volume),
1555+ fID(id),
1556+ fCache(NULL),
1557+ fMap(NULL),
1558+ fInitStatus(B_OK),
1559+ fNode(item)
1560+{
1561+ if (!IsDirectory() && !IsSymLink()) {
1562+ fCache = file_cache_create(fVolume->ID(), ID(), Size());
1563+ fMap = file_map_create(fVolume->ID(), ID(), Size());
1564+ }
1565+}
1566+
1567+
1568 Inode::Inode(Volume* volume)
1569 :
1570 fVolume(volume),
1571@@ -94,6 +110,49 @@ Inode::UpdateNodeFromDisk()
1572 }
1573
1574
1575+/*
1576+ * Create new Inode object with inode_item
1577+ */
1578+Inode*
1579+Inode::Create(Transaction& transaction, ino_t id, Inode* parent, int32 mode,
1580+ uint64 size, uint64 flags)
1581+{
1582+ TRACE("Inode::Create() id % " B_PRIu64 " mode %" B_PRId32 " flags %"
1583+ B_PRIu64"\n", id, flags, mode);
1584+
1585+ Volume* volume = parent->GetVolume();
1586+ uint64 nbytes = size; // allocated size
1587+ if (size > volume->MaxInlineSize())
1588+ nbytes = (size / volume->SectorSize() + 1) * volume->SectorSize();
1589+
1590+ btrfs_inode inode;
1591+
1592+ inode.generation = B_HOST_TO_LENDIAN_INT64(transaction.SystemID());
1593+ inode.transaction_id = B_HOST_TO_LENDIAN_INT64(transaction.SystemID());
1594+ inode.size = B_HOST_TO_LENDIAN_INT64(size);
1595+ inode.nbytes = B_HOST_TO_LENDIAN_INT64(nbytes);
1596+ inode.blockgroup = 0; // normal inode only
1597+ inode.num_links = B_HOST_TO_LENDIAN_INT32(1);
1598+ inode.uid = B_HOST_TO_LENDIAN_INT32(geteuid());
1599+ inode.gid = B_HOST_TO_LENDIAN_INT32(parent ? parent->GroupID() : getegid());
1600+ inode.mode = B_HOST_TO_LENDIAN_INT32(mode);;
1601+ inode.rdev = 0; // normal file only
1602+ inode.flags = B_HOST_TO_LENDIAN_INT64(flags);
1603+ inode.sequence = 0; // incremented each time mtime value is changed
1604+
1605+ uint64 now = real_time_clock_usecs();
1606+ struct timespec timespec;
1607+ timespec.tv_sec = now / 1000000;
1608+ timespec.tv_nsec = (now % 1000000) * 1000;
1609+ btrfs_inode::SetTime(inode.access_time, timespec);
1610+ btrfs_inode::SetTime(inode.creation_time, timespec);
1611+ btrfs_inode::SetTime(inode.change_time, timespec);
1612+ btrfs_inode::SetTime(inode.modification_time, timespec);
1613+
1614+ return new Inode(volume, id, inode);
1615+}
1616+
1617+
1618 status_t
1619 Inode::CheckPermissions(int accessMode) const
1620 {
1621diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1622index 003baf4..29c106d 100644
1623--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
1624+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1625@@ -9,6 +9,7 @@
1626
1627 #include "btrfs.h"
1628 #include "Volume.h"
1629+#include "Journal.h"
1630
1631
1632 //#define TRACE_BTRFS
1633@@ -22,6 +23,8 @@
1634 class Inode {
1635 public:
1636 Inode(Volume* volume, ino_t id);
1637+ Inode(Volume* volume, ino_t id,
1638+ const btrfs_inode& item);
1639 ~Inode();
1640
1641 status_t InitCheck();
1642@@ -64,6 +67,9 @@ public:
1643 void* Map() const { return fMap; }
1644
1645 status_t FindParent(ino_t* id);
1646+ static Inode* Create(Transaction& transaction, ino_t id,
1647+ Inode* parent, int32 mode, uint64 size = 0,
1648+ uint64 flags = 0);
1649 private:
1650 Inode(Volume* volume);
1651 Inode(const Inode&);
1652@@ -71,6 +77,7 @@ private:
1653 // no implementation
1654
1655 uint64 _NumBlocks();
1656+private:
1657
1658 rw_lock fLock;
1659 ::Volume* fVolume;
1660diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
1661index 11b4deb..6ed1d3c 100644
1662--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
1663+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
1664@@ -46,6 +46,8 @@ public:
1665 BTree* RootTree() const { return fRootTree; }
1666
1667 uint32 SectorSize() const { return fSectorSize; }
1668+ uint32 MaxInlineSize() const
1669+ { return fSectorSize / 2; }
1670 uint32 BlockSize() const { return fBlockSize; }
1671 Chunk* SystemChunk() const { return fChunk; }
1672 Journal* GetJournal() const { return fJournal; }
1673diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1674index f8b3acc..2567c3b 100644
1675--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1676+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1677@@ -303,6 +303,11 @@ struct btrfs_inode {
1678 { _DecodeTime(timespec, modification_time); }
1679 void GetCreationTime(struct timespec& timespec) const
1680 { _DecodeTime(timespec, creation_time); }
1681+ static void SetTime(btrfs_timespec& time, const struct timespec& timespec)
1682+ {
1683+ time.seconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_sec);
1684+ time.nanoseconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_nsec);
1685+ }
1686 } _PACKED;
1687
1688
1689--
16902.7.4
1691
1692
1693From a9001e38c4d0b04f06b8846cabb3d397364d545b Mon Sep 17 00:00:00 2001
1694From: hyche <cvghy116@gmail.com>
1695Date: Tue, 29 Aug 2017 06:21:42 +0700
1696Subject: [PATCH 14/21] BTRFS: Implement Insert() in Inode that inserts
1697 inode_item.
1698
1699---
1700 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 24 +++++++++++++++++++++++-
1701 src/add-ons/kernel/file_systems/btrfs/Inode.h | 2 ++
1702 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 1 +
1703 3 files changed, 26 insertions(+), 1 deletion(-)
1704
1705diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1706index bb3b49c..f9229ad 100644
1707--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1708+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1709@@ -7,7 +7,6 @@
1710
1711
1712 #include "Inode.h"
1713-#include "BTree.h"
1714 #include "CachedBlock.h"
1715 #include "Utility.h"
1716
1717@@ -372,3 +371,26 @@ Inode::FindParent(ino_t* id)
1718 return B_OK;
1719 }
1720
1721+
1722+/* Insert inode_item
1723+ */
1724+status_t
1725+Inode::Insert(Transaction& transaction, BTree::Path* path)
1726+{
1727+ BTree* tree = path->Tree();
1728+
1729+ btrfs_entry item;
1730+ item.key.SetObjectID(fID);
1731+ item.key.SetType(BTRFS_KEY_TYPE_INODE_ITEM);
1732+ item.key.SetOffset(0);
1733+ item.SetSize(sizeof(btrfs_inode));
1734+
1735+ void* data[1];
1736+ data[0] = (void*)&fNode;
1737+ status_t status = tree->InsertEntries(transaction, path, &item, data, 1);
1738+ if (status != B_OK)
1739+ return status;
1740+
1741+
1742+ return B_OK;
1743+}
1744diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1745index 29c106d..60c5aa0 100644
1746--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
1747+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1748@@ -10,6 +10,7 @@
1749 #include "btrfs.h"
1750 #include "Volume.h"
1751 #include "Journal.h"
1752+#include "BTree.h"
1753
1754
1755 //#define TRACE_BTRFS
1756@@ -70,6 +71,7 @@ public:
1757 static Inode* Create(Transaction& transaction, ino_t id,
1758 Inode* parent, int32 mode, uint64 size = 0,
1759 uint64 flags = 0);
1760+ status_t Insert(Transaction& transaction, BTree::Path* path);
1761 private:
1762 Inode(Volume* volume);
1763 Inode(const Inode&);
1764diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1765index 2567c3b..a1121f4 100644
1766--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1767+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1768@@ -145,6 +145,7 @@ struct btrfs_entry {
1769 uint32 Size() const
1770 { return B_LENDIAN_TO_HOST_INT32(size); }
1771 void SetOffset(uint32 off) { offset = B_HOST_TO_LENDIAN_INT32(off); }
1772+ void SetSize(uint32 itemSize) { size = B_HOST_TO_LENDIAN_INT32(itemSize); }
1773 } _PACKED;
1774
1775
1776--
17772.7.4
1778
1779
1780From 01beb759d270cd100f5e028e700f5f2189c71130 Mon Sep 17 00:00:00 2001
1781From: hyche <cvghy116@gmail.com>
1782Date: Tue, 29 Aug 2017 06:38:42 +0700
1783Subject: [PATCH 15/21] BTRFS: Implement MakeReference() in Inode that will
1784 link file name to inode.
1785
1786---
1787 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 78 +++++++++++++++++++++++++
1788 src/add-ons/kernel/file_systems/btrfs/Inode.h | 3 +
1789 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 22 +++++++
1790 3 files changed, 103 insertions(+)
1791
1792diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1793index f9229ad..7c0a72d 100644
1794--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1795+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1796@@ -8,6 +8,7 @@
1797
1798 #include "Inode.h"
1799 #include "CachedBlock.h"
1800+#include "CRCTable.h"
1801 #include "Utility.h"
1802
1803
1804@@ -372,6 +373,21 @@ Inode::FindParent(ino_t* id)
1805 }
1806
1807
1808+uint64
1809+Inode::FindNextIndex(BTree::Path* path) const
1810+{
1811+ btrfs_key key;
1812+ key.SetObjectID(fID);
1813+ key.SetType(BTRFS_KEY_TYPE_DIR_INDEX);
1814+ key.SetOffset(-1);
1815+
1816+ if (fVolume->FSTree()->FindPrevious(path, key, NULL))
1817+ return 2; // not found any dir index item
1818+
1819+ return key.Offset() + 1;
1820+}
1821+
1822+
1823 /* Insert inode_item
1824 */
1825 status_t
1826@@ -391,6 +407,68 @@ Inode::Insert(Transaction& transaction, BTree::Path* path)
1827 if (status != B_OK)
1828 return status;
1829
1830+ return B_OK;
1831+}
1832+
1833+
1834+/* Insert 3 items: inode_ref, dir_item, dir_index
1835+ * Basically, make a link between name and its node (location)
1836+ */
1837+status_t
1838+Inode::MakeReference(Transaction& transaction, BTree::Path* path,
1839+ Inode* parent, const char* name, int32 mode)
1840+{
1841+ BTree* tree = fVolume->FSTree();
1842+ uint16 nameLength = strlen(name);
1843+ uint64 index = parent->FindNextIndex(path);
1844+ void* data[1];
1845+
1846+ // insert inode_ref
1847+ btrfs_entry entry;
1848+ btrfs_inode_ref inodeRef;
1849+
1850+ inodeRef.index = index;
1851+ inodeRef.SetName(name, nameLength);
1852+ data[0] = (void*)&inodeRef;
1853+
1854+ entry.key.SetObjectID(fID);
1855+ entry.key.SetType(BTRFS_KEY_TYPE_INODE_REF);
1856+ entry.key.SetOffset(parent->ID());
1857+ entry.SetSize(inodeRef.Length());
1858+
1859+ status_t status = tree->InsertEntries(transaction, path, &entry, data, 1);
1860+ if (status != B_OK)
1861+ return status;
1862+
1863+ // insert dir_entry
1864+ uint32 hash = calculate_crc((uint32)~1, (uint8*)name, nameLength);
1865+ btrfs_dir_entry directoryEntry;
1866+ directoryEntry.location.SetObjectID(fID);
1867+ directoryEntry.location.SetType(BTRFS_KEY_TYPE_INODE_ITEM);
1868+ directoryEntry.location.SetOffset(0);
1869+ directoryEntry.SetTransactionID(transaction.SystemID());
1870+ // TODO: xattribute, 0 for standard directory
1871+ directoryEntry.SetAttributeData(NULL, 0);
1872+ directoryEntry.SetName(name, nameLength);
1873+ directoryEntry.type = get_filetype(mode);
1874+ data[0] = (void*)&directoryEntry;
1875+
1876+ entry.key.SetObjectID(parent->ID());
1877+ entry.key.SetType(BTRFS_KEY_TYPE_DIR_ITEM);
1878+ entry.key.SetOffset(hash);
1879+ entry.SetSize(directoryEntry.Length());
1880+
1881+ status = tree->InsertEntries(transaction, path, &entry, data, 1);
1882+ if (status != B_OK)
1883+ return status;
1884+
1885+ // insert dir_index (has same data with dir_entry)
1886+ entry.key.SetType(BTRFS_KEY_TYPE_DIR_INDEX);
1887+ entry.key.SetOffset(index);
1888+
1889+ status = tree->InsertEntries(transaction, path, &entry, data, 1);
1890+ if (status != B_OK)
1891+ return status;
1892
1893 return B_OK;
1894 }
1895diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1896index 60c5aa0..953f9ba 100644
1897--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
1898+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
1899@@ -68,10 +68,13 @@ public:
1900 void* Map() const { return fMap; }
1901
1902 status_t FindParent(ino_t* id);
1903+ uint64 FindNextIndex(BTree::Path* path) const;
1904 static Inode* Create(Transaction& transaction, ino_t id,
1905 Inode* parent, int32 mode, uint64 size = 0,
1906 uint64 flags = 0);
1907 status_t Insert(Transaction& transaction, BTree::Path* path);
1908+ status_t MakeReference(Transaction& transaction, BTree::Path* path,
1909+ Inode* parent, const char* name, int32 mode);
1910 private:
1911 Inode(Volume* volume);
1912 Inode(const Inode&);
1913diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1914index a1121f4..d0481e0 100644
1915--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1916+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1917@@ -319,6 +319,13 @@ struct btrfs_inode_ref {
1918
1919 uint64 Index() const { return index; }
1920 uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
1921+ uint16 Length() const
1922+ { return sizeof(btrfs_inode_ref) + NameLength(); }
1923+ void SetName(const char* name, uint16 nameLength)
1924+ {
1925+ name_length = B_HOST_TO_LENDIAN_INT16(nameLength);
1926+ memcpy(this->name, name, nameLength);
1927+ }
1928 } _PACKED;
1929
1930
1931@@ -348,11 +355,26 @@ struct btrfs_dir_entry {
1932 uint16 data_length;
1933 uint16 name_length;
1934 uint8 type;
1935+ uint8 name[];
1936+ uint8 data[]; // attribute data
1937 uint16 DataLength() const { return B_LENDIAN_TO_HOST_INT16(data_length); }
1938 uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
1939 ino_t InodeID() const { return location.ObjectID(); }
1940 uint16 Length() const
1941 { return sizeof(*this) + NameLength() + DataLength(); }
1942+ void SetTransactionID(uint64 id)
1943+ { transaction_id = B_HOST_TO_LENDIAN_INT64(id); }
1944+ void SetAttributeData(void* data, uint16 dataLength)
1945+ {
1946+ data_length = B_HOST_TO_LENDIAN_INT16(dataLength);
1947+ if (data != NULL)
1948+ memcpy(this->data, data, dataLength);
1949+ }
1950+ void SetName(const char* name, uint16 nameLength)
1951+ {
1952+ name_length = B_HOST_TO_LENDIAN_INT16(nameLength);
1953+ memcpy(this->name, name, nameLength);
1954+ }
1955 } _PACKED;
1956
1957
1958--
19592.7.4
1960
1961
1962From 41c3fa3afc91893fbec05e0f673e825f6a4f6c24 Mon Sep 17 00:00:00 2001
1963From: hyche <cvghy116@gmail.com>
1964Date: Tue, 29 Aug 2017 06:41:56 +0700
1965Subject: [PATCH 16/21] BTRFS: Implement Remove() in Inode that removes
1966 inode_item.
1967
1968---
1969 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 18 ++++++++++++++++++
1970 src/add-ons/kernel/file_systems/btrfs/Inode.h | 1 +
1971 2 files changed, 19 insertions(+)
1972
1973diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1974index 7c0a72d..d02803e 100644
1975--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1976+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
1977@@ -411,6 +411,24 @@ Inode::Insert(Transaction& transaction, BTree::Path* path)
1978 }
1979
1980
1981+/* Remove inode_item
1982+ */
1983+status_t
1984+Inode::Remove(Transaction& transaction, BTree::Path* path)
1985+{
1986+ BTree* tree = path->Tree();
1987+ btrfs_key key;
1988+ key.SetObjectID(fID);
1989+ key.SetType(BTRFS_KEY_TYPE_INODE_ITEM);
1990+ key.SetOffset(0);
1991+ status_t status = tree->RemoveEntries(transaction, path, key, NULL, 1);
1992+ if (status != B_OK)
1993+ return status;
1994+
1995+ return B_OK;
1996+}
1997+
1998+
1999 /* Insert 3 items: inode_ref, dir_item, dir_index
2000 * Basically, make a link between name and its node (location)
2001 */
2002diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2003index 953f9ba..00d6de4 100644
2004--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
2005+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2006@@ -73,6 +73,7 @@ public:
2007 Inode* parent, int32 mode, uint64 size = 0,
2008 uint64 flags = 0);
2009 status_t Insert(Transaction& transaction, BTree::Path* path);
2010+ status_t Remove(Transaction& transaction, BTree::Path* path);
2011 status_t MakeReference(Transaction& transaction, BTree::Path* path,
2012 Inode* parent, const char* name, int32 mode);
2013 private:
2014--
20152.7.4
2016
2017
2018From 4233d179ddd15ce5ca994ac9b95616e5aa7be76a Mon Sep 17 00:00:00 2001
2019From: hyche <cvghy116@gmail.com>
2020Date: Tue, 29 Aug 2017 06:43:21 +0700
2021Subject: [PATCH 17/21] BTRFS: Implement Dereference() in Inode that remove the
2022 "name" and unlink it with inode.
2023
2024---
2025 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 40 +++++++++++++++++++++++++
2026 src/add-ons/kernel/file_systems/btrfs/Inode.h | 2 ++
2027 2 files changed, 42 insertions(+)
2028
2029diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2030index d02803e..0b212aa 100644
2031--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2032+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2033@@ -490,3 +490,43 @@ Inode::MakeReference(Transaction& transaction, BTree::Path* path,
2034
2035 return B_OK;
2036 }
2037+
2038+
2039+// Remove the "name" and unlink it with inode.
2040+status_t
2041+Inode::Dereference(Transaction& transaction, BTree::Path* path, ino_t parentID,
2042+ const char* name)
2043+{
2044+ BTree* tree = path->Tree();
2045+
2046+ // remove inode_ref item
2047+ btrfs_key key;
2048+ key.SetObjectID(fID);
2049+ key.SetType(BTRFS_KEY_TYPE_INODE_REF);
2050+ key.SetOffset(parentID);
2051+ btrfs_inode_ref* inodeRef;
2052+ status_t status = tree->RemoveEntries(transaction, path, key,
2053+ (void**)&inodeRef, 1);
2054+ if (status != B_OK)
2055+ return status;
2056+
2057+ // remove dir_item
2058+ uint32 hash = calculate_crc((uint32)~1, (uint8*)name, strlen(name));
2059+ key.SetObjectID(parentID);
2060+ key.SetType(BTRFS_KEY_TYPE_DIR_ITEM);
2061+ key.SetOffset(hash);
2062+ status = tree->RemoveEntries(transaction, path, key, NULL, 1);
2063+ if (status != B_OK)
2064+ return status;
2065+
2066+ // remove dir_index
2067+ uint64 index = inodeRef->Index();
2068+ free(inodeRef);
2069+ key.SetType(BTRFS_KEY_TYPE_DIR_INDEX);
2070+ key.SetOffset(index);
2071+ status = tree->RemoveEntries(transaction, path, key, NULL, 1);
2072+ if (status != B_OK)
2073+ return status;
2074+
2075+ return B_OK;
2076+}
2077diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2078index 00d6de4..933a61e 100644
2079--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
2080+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2081@@ -76,6 +76,8 @@ public:
2082 status_t Remove(Transaction& transaction, BTree::Path* path);
2083 status_t MakeReference(Transaction& transaction, BTree::Path* path,
2084 Inode* parent, const char* name, int32 mode);
2085+ status_t Dereference(Transaction& transaction, BTree::Path* path,
2086+ ino_t parentID, const char* name);
2087 private:
2088 Inode(Volume* volume);
2089 Inode(const Inode&);
2090--
20912.7.4
2092
2093
2094From fb61af260215dfb4d245cb6cfc3e3252249ddb93 Mon Sep 17 00:00:00 2001
2095From: hyche <cvghy116@gmail.com>
2096Date: Tue, 29 Aug 2017 06:47:02 +0700
2097Subject: [PATCH 18/21] BTRFS: Implement btrfs_create_dir that can create
2098 directories in most case.
2099
2100We need to handle a case when node is full, the solution should be split or push data to another node.
2101---
2102 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 11 +++++
2103 src/add-ons/kernel/file_systems/btrfs/Volume.h | 2 +
2104 .../kernel/file_systems/btrfs/kernel_interface.cpp | 48 +++++++++++++++++++++-
2105 3 files changed, 60 insertions(+), 1 deletion(-)
2106
2107diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2108index 5a86ca2..2c61623 100644
2109--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2110+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2111@@ -388,6 +388,17 @@ Volume::Mount(const char* deviceName, uint32 flags)
2112 fChecksumTree->SetRoot(root->LogicalAddress(), NULL);
2113 free(root);
2114
2115+ search_key.SetObjectID(-1);
2116+ search_key.SetType(0);
2117+ status = fFSTree->FindPrevious(&path, search_key, NULL);
2118+ if (status != B_OK) {
2119+ ERROR("Volume::Mount() Couldn't find any inode!!\n");
2120+ return status;
2121+ }
2122+ fLargestInodeID = search_key.ObjectID();
2123+ TRACE("Volume::Mount() Find larget inode id % " B_PRIu64 "\n",
2124+ fLargestInodeID);
2125+
2126 // Initialize Journal
2127 fJournal = new(std::nothrow) Journal(this);
2128 if (fJournal == NULL)
2129diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
2130index 6ed1d3c..a29a4ac 100644
2131--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
2132+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
2133@@ -49,6 +49,7 @@ public:
2134 uint32 MaxInlineSize() const
2135 { return fSectorSize / 2; }
2136 uint32 BlockSize() const { return fBlockSize; }
2137+ ino_t GetNextInodeID() { return ++fLargestInodeID; }
2138 Chunk* SystemChunk() const { return fChunk; }
2139 Journal* GetJournal() const { return fJournal; }
2140 ExtentAllocator* GetAllocator() const { return fExtentAllocator; }
2141@@ -72,6 +73,7 @@ private:
2142 mutex fLock;
2143 fs_volume* fFSVolume;
2144 int fDevice;
2145+ ino_t fLargestInodeID;
2146 btrfs_super_block fSuperBlock;
2147 char fName[32];
2148
2149diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2150index 2670215..c3f20cd 100644
2151--- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2152+++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2153@@ -483,6 +483,52 @@ btrfs_read_link(fs_volume* _volume, fs_vnode* _node, char* buffer,
2154
2155
2156 static status_t
2157+btrfs_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name,
2158+ int mode)
2159+{
2160+ Volume* volume = (Volume*)_volume->private_volume;
2161+ Inode* directory = (Inode*)_directory->private_node;
2162+ BTree::Path path(volume->FSTree());
2163+
2164+ if (volume->IsReadOnly())
2165+ return B_READ_ONLY_DEVICE;
2166+
2167+ if (!directory->IsDirectory())
2168+ return B_NOT_A_DIRECTORY;
2169+
2170+ status_t status = directory->CheckPermissions(W_OK);
2171+ if (status < B_OK)
2172+ return status;
2173+
2174+ Transaction transaction(volume);
2175+ ino_t id = volume->GetNextInodeID();
2176+ mode = S_DIRECTORY | (mode & S_IUMSK);
2177+ Inode* inode = Inode::Create(transaction, id, directory, mode);
2178+ if (inode == NULL)
2179+ return B_NO_MEMORY;
2180+
2181+ status = inode->Insert(transaction, &path);
2182+ if (status != B_OK)
2183+ return status;
2184+
2185+ status = inode->MakeReference(transaction, &path, directory, name, mode);
2186+ if (status != B_OK)
2187+ return status;
2188+
2189+ put_vnode(volume->FSVolume(), inode->ID());
2190+ entry_cache_add(volume->ID(), directory->ID(), name, inode->ID());
2191+
2192+ status = transaction.Done();
2193+ if (status == B_OK)
2194+ notify_entry_created(volume->ID(), directory->ID(), name, inode->ID());
2195+ else
2196+ entry_cache_remove(volume->ID(), directory->ID(), name);
2197+
2198+ return status;
2199+}
2200+
2201+
2202+static status_t
2203 btrfs_open_dir(fs_volume* /*_volume*/, fs_vnode* _node, void** _cookie)
2204 {
2205 Inode* inode = (Inode*)_node->private_node;
2206@@ -814,7 +860,7 @@ fs_vnode_ops gBtrfsVnodeOps = {
2207 NULL, // fs_write,
2208
2209 /* directory operations */
2210- NULL, // fs_create_dir,
2211+ &btrfs_create_dir,
2212 NULL, // fs_remove_dir,
2213 &btrfs_open_dir,
2214 &btrfs_close_dir,
2215--
22162.7.4
2217
2218
2219From ccba0c3e61b6293bd988f5bef9f43355b7e951d7 Mon Sep 17 00:00:00 2001
2220From: hyche <cvghy116@gmail.com>
2221Date: Tue, 29 Aug 2017 06:55:13 +0700
2222Subject: [PATCH 19/21] BTRFS: Implement btrfs_remove_dir that can remove
2223 directories in most case.
2224
2225We need to handle a case when node size is small reasonably it can be merged with another node or push data from other node to this node.
2226---
2227 .../kernel/file_systems/btrfs/kernel_interface.cpp | 44 +++++++++++++++++++++-
2228 1 file changed, 43 insertions(+), 1 deletion(-)
2229
2230diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2231index c3f20cd..ef56195 100644
2232--- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2233+++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2234@@ -529,6 +529,48 @@ btrfs_create_dir(fs_volume* _volume, fs_vnode* _directory, const char* name,
2235
2236
2237 static status_t
2238+btrfs_remove_dir(fs_volume* _volume, fs_vnode* _directory, const char* name)
2239+{
2240+ Volume* volume = (Volume*)_volume->private_volume;
2241+ Inode* directory = (Inode*)_directory->private_node;
2242+
2243+ Transaction transaction(volume);
2244+ BTree::Path path(volume->FSTree());
2245+
2246+ ino_t id;
2247+ status_t status = DirectoryIterator(directory).Lookup(name, strlen(name),
2248+ &id);
2249+ if (status != B_OK)
2250+ return status;
2251+
2252+ Inode inode(volume, id);
2253+ status = inode.InitCheck();
2254+ if (status != B_OK)
2255+ return status;
2256+
2257+ status = inode.Remove(transaction, &path);
2258+ if (status != B_OK)
2259+ return status;
2260+ status = inode.Dereference(transaction, &path, directory->ID(), name);
2261+ if (status != B_OK)
2262+ return status;
2263+
2264+ entry_cache_remove(volume->ID(), directory->ID(), name);
2265+ entry_cache_remove(volume->ID(), id, "..");
2266+
2267+ status = transaction.Done();
2268+ if (status == B_OK)
2269+ notify_entry_removed(volume->ID(), directory->ID(), name, id);
2270+ else {
2271+ entry_cache_add(volume->ID(), directory->ID(), name, id);
2272+ entry_cache_add(volume->ID(), id, "..", id);
2273+ }
2274+
2275+ return status;
2276+}
2277+
2278+
2279+static status_t
2280 btrfs_open_dir(fs_volume* /*_volume*/, fs_vnode* _node, void** _cookie)
2281 {
2282 Inode* inode = (Inode*)_node->private_node;
2283@@ -861,7 +903,7 @@ fs_vnode_ops gBtrfsVnodeOps = {
2284
2285 /* directory operations */
2286 &btrfs_create_dir,
2287- NULL, // fs_remove_dir,
2288+ &btrfs_remove_dir,
2289 &btrfs_open_dir,
2290 &btrfs_close_dir,
2291 &btrfs_free_dir_cookie,
2292--
22932.7.4
2294
2295
2296From 2b6961bcee054d156afb213f520c641ce66449b0 Mon Sep 17 00:00:00 2001
2297From: hyche <cvghy116@gmail.com>
2298Date: Wed, 30 Aug 2017 07:15:37 +0700
2299Subject: [PATCH 20/21] BTRFS: Let BTRFS be writable in RAM only for someone
2300 who want to test new features through fs_shell, or real device.
2301
2302This is because we don't allow write-access to disk due to cache_sync_transaction is commented in Journal and allowWrites flag in cache_block_delete
2303is always false.
2304---
2305 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 6 ++----
2306 1 file changed, 2 insertions(+), 4 deletions(-)
2307
2308diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2309index 2c61623..a8b0614 100644
2310--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2311+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2312@@ -240,9 +240,6 @@ Volume::Name() const
2313 status_t
2314 Volume::Mount(const char* deviceName, uint32 flags)
2315 {
2316- flags |= B_MOUNT_READ_ONLY;
2317- // we only support read-only for now
2318-
2319 if ((flags & B_MOUNT_READ_ONLY) != 0) {
2320 TRACE("Volume::Mount(): Read only\n");
2321 } else {
2322@@ -476,7 +473,8 @@ Volume::Unmount()
2323 TRACE("Volume::Unmount(): Putting root node\n");
2324 put_vnode(fFSVolume, RootNode()->ID());
2325 TRACE("Volume::Unmount(): Deleting the block cache\n");
2326- block_cache_delete(fBlockCache, !IsReadOnly());
2327+ //block_cache_delete(fBlockCache, !IsReadOnly());
2328+ block_cache_delete(fBlockCache, false);
2329 TRACE("Volume::Unmount(): Closing device\n");
2330 close(fDevice);
2331
2332--
23332.7.4
2334
2335
2336From 568ba3007524141786b709d5b6cf7cc98e77a700 Mon Sep 17 00:00:00 2001
2337From: hyche <cvghy116@gmail.com>
2338Date: Wed, 30 Aug 2017 07:40:57 +0700
2339Subject: [PATCH 21/21] BTRFS: Add author and license.
2340
2341---
2342 src/add-ons/kernel/file_systems/btrfs/Attribute.cpp | 1 +
2343 src/add-ons/kernel/file_systems/btrfs/Attribute.h | 1 +
2344 src/add-ons/kernel/file_systems/btrfs/AttributeIterator.cpp | 1 +
2345 src/add-ons/kernel/file_systems/btrfs/AttributeIterator.h | 1 +
2346 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 1 +
2347 src/add-ons/kernel/file_systems/btrfs/BTree.h | 1 +
2348 src/add-ons/kernel/file_systems/btrfs/CachedBlock.h | 1 +
2349 src/add-ons/kernel/file_systems/btrfs/Chunk.cpp | 1 +
2350 src/add-ons/kernel/file_systems/btrfs/Chunk.h | 1 +
2351 src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.cpp | 1 +
2352 src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.h | 1 +
2353 src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp | 6 ++++++
2354 src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h | 4 ++++
2355 src/add-ons/kernel/file_systems/btrfs/Inode.cpp | 1 +
2356 src/add-ons/kernel/file_systems/btrfs/Inode.h | 1 +
2357 src/add-ons/kernel/file_systems/btrfs/Journal.cpp | 7 +++++++
2358 src/add-ons/kernel/file_systems/btrfs/Journal.h | 5 +++++
2359 src/add-ons/kernel/file_systems/btrfs/Utility.h | 1 +
2360 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 1 +
2361 src/add-ons/kernel/file_systems/btrfs/Volume.h | 1 +
2362 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 1 +
2363 src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp | 1 +
2364 src/add-ons/kernel/file_systems/btrfs/system_dependencies.h | 4 ++++
2365 23 files changed, 44 insertions(+)
2366
2367diff --git a/src/add-ons/kernel/file_systems/btrfs/Attribute.cpp b/src/add-ons/kernel/file_systems/btrfs/Attribute.cpp
2368index 1c0b286..3defc5a 100644
2369--- a/src/add-ons/kernel/file_systems/btrfs/Attribute.cpp
2370+++ b/src/add-ons/kernel/file_systems/btrfs/Attribute.cpp
2371@@ -1,4 +1,5 @@
2372 /*
2373+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2374 * Copyright 2010-2011, Jérôme Duval, korli@users.berlios.de.
2375 * Copyright 2010, François Revol, <revol@free.fr>.
2376 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
2377diff --git a/src/add-ons/kernel/file_systems/btrfs/Attribute.h b/src/add-ons/kernel/file_systems/btrfs/Attribute.h
2378index ebbb3e9..630440f 100644
2379--- a/src/add-ons/kernel/file_systems/btrfs/Attribute.h
2380+++ b/src/add-ons/kernel/file_systems/btrfs/Attribute.h
2381@@ -1,4 +1,5 @@
2382 /*
2383+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2384 * Copyright 2010-2011, Jérôme Duval, korli@users.berlios.de.
2385 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
2386 * This file may be used under the terms of the MIT License.
2387diff --git a/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.cpp b/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.cpp
2388index b9dfc91..fa103bb 100644
2389--- a/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.cpp
2390+++ b/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.cpp
2391@@ -1,4 +1,5 @@
2392 /*
2393+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2394 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2395 * This file may be used under the terms of the MIT License.
2396 */
2397diff --git a/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.h b/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.h
2398index b9491f4..73db74d 100644
2399--- a/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.h
2400+++ b/src/add-ons/kernel/file_systems/btrfs/AttributeIterator.h
2401@@ -1,4 +1,5 @@
2402 /*
2403+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2404 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2405 * This file may be used under the terms of the MIT License.
2406 */
2407diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
2408index e5f3797..2e4159b 100644
2409--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
2410+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
2411@@ -1,4 +1,5 @@
2412 /*
2413+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2414 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2415 * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
2416 * This file may be used under the terms of the MIT License.
2417diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
2418index 1da3561..09ea6ab 100644
2419--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
2420+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
2421@@ -1,4 +1,5 @@
2422 /*
2423+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2424 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2425 * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
2426 * This file may be used under the terms of the MIT License.
2427diff --git a/src/add-ons/kernel/file_systems/btrfs/CachedBlock.h b/src/add-ons/kernel/file_systems/btrfs/CachedBlock.h
2428index 769774f..6c2f687 100644
2429--- a/src/add-ons/kernel/file_systems/btrfs/CachedBlock.h
2430+++ b/src/add-ons/kernel/file_systems/btrfs/CachedBlock.h
2431@@ -1,4 +1,5 @@
2432 /*
2433+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2434 * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
2435 * This file may be used under the terms of the MIT License.
2436 */
2437diff --git a/src/add-ons/kernel/file_systems/btrfs/Chunk.cpp b/src/add-ons/kernel/file_systems/btrfs/Chunk.cpp
2438index cba77ce..523ee2e 100644
2439--- a/src/add-ons/kernel/file_systems/btrfs/Chunk.cpp
2440+++ b/src/add-ons/kernel/file_systems/btrfs/Chunk.cpp
2441@@ -4,6 +4,7 @@
2442 *
2443 * Authors:
2444 * Jérôme Duval
2445+ * Chế Vũ Gia Hy
2446 */
2447
2448
2449diff --git a/src/add-ons/kernel/file_systems/btrfs/Chunk.h b/src/add-ons/kernel/file_systems/btrfs/Chunk.h
2450index c1fbe49..1bc5bab 100644
2451--- a/src/add-ons/kernel/file_systems/btrfs/Chunk.h
2452+++ b/src/add-ons/kernel/file_systems/btrfs/Chunk.h
2453@@ -4,6 +4,7 @@
2454 *
2455 * Authors:
2456 * Jérôme Duval
2457+ * Chế Vũ Gia Hy
2458 */
2459 #ifndef CHUNK_H
2460 #define CHUNK_H
2461diff --git a/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.cpp b/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.cpp
2462index 0be81a4..9680fb6 100644
2463--- a/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.cpp
2464+++ b/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.cpp
2465@@ -1,4 +1,5 @@
2466 /*
2467+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2468 * Copyright 2011-2013, Jérôme Duval, korli@users.berlios.de.
2469 * This file may be used under the terms of the MIT License.
2470 */
2471diff --git a/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.h b/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.h
2472index 086863d..6c01819 100644
2473--- a/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.h
2474+++ b/src/add-ons/kernel/file_systems/btrfs/DirectoryIterator.h
2475@@ -1,4 +1,5 @@
2476 /*
2477+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2478 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2479 * This file may be used under the terms of the MIT License.
2480 */
2481diff --git a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
2482index 58e126c..82dc298 100644
2483--- a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
2484+++ b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
2485@@ -1,3 +1,9 @@
2486+/*
2487+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2488+ * This file may be used under the terms of the MIT License.
2489+ */
2490+
2491+
2492 #include "ExtentAllocator.h"
2493 #include "Chunk.h"
2494
2495diff --git a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
2496index 53cef4e..1f0fade 100644
2497--- a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
2498+++ b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
2499@@ -1,3 +1,7 @@
2500+/*
2501+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2502+ * This file may be used under the terms of the MIT License.
2503+ */
2504 #ifndef EXTENT_ALLOCATOR_H
2505 #define EXTENT_ALLOCATOR_H
2506
2507diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2508index 0b212aa..be9b204 100644
2509--- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2510+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp
2511@@ -1,4 +1,5 @@
2512 /*
2513+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2514 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2515 * Copyright 2008-2014, Axel Dörfler, axeld@pinc-software.de.
2516 * Copyright 2005-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
2517diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2518index 933a61e..ff8edd8 100644
2519--- a/src/add-ons/kernel/file_systems/btrfs/Inode.h
2520+++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h
2521@@ -1,4 +1,5 @@
2522 /*
2523+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2524 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2525 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
2526 * This file may be used under the terms of the MIT License.
2527diff --git a/src/add-ons/kernel/file_systems/btrfs/Journal.cpp b/src/add-ons/kernel/file_systems/btrfs/Journal.cpp
2528index ed505d6..f35f9da 100644
2529--- a/src/add-ons/kernel/file_systems/btrfs/Journal.cpp
2530+++ b/src/add-ons/kernel/file_systems/btrfs/Journal.cpp
2531@@ -1,3 +1,10 @@
2532+/*
2533+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2534+ * Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de.
2535+ * This file may be used under the terms of the MIT License.
2536+ */
2537+
2538+
2539 #include "Journal.h"
2540
2541
2542diff --git a/src/add-ons/kernel/file_systems/btrfs/Journal.h b/src/add-ons/kernel/file_systems/btrfs/Journal.h
2543index a6272c3..77ccc7d 100644
2544--- a/src/add-ons/kernel/file_systems/btrfs/Journal.h
2545+++ b/src/add-ons/kernel/file_systems/btrfs/Journal.h
2546@@ -1,3 +1,8 @@
2547+/*
2548+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2549+ * Copyright 2001-2012, Axel Dörfler, axeld@pinc-software.de.
2550+ * This file may be used under the terms of the MIT License.
2551+ */
2552 #ifndef JOURNAL_H
2553 #define JOURNAL_H
2554
2555diff --git a/src/add-ons/kernel/file_systems/btrfs/Utility.h b/src/add-ons/kernel/file_systems/btrfs/Utility.h
2556index 2c4672c..7080174 100644
2557--- a/src/add-ons/kernel/file_systems/btrfs/Utility.h
2558+++ b/src/add-ons/kernel/file_systems/btrfs/Utility.h
2559@@ -1,4 +1,5 @@
2560 /*
2561+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2562 * Copyright 2001-2009, Axel Dörfler, axeld@pinc-software.de.
2563 * This file may be used under the terms of the MIT License.
2564 */
2565diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2566index a8b0614..cfc3a4a 100644
2567--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2568+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
2569@@ -1,4 +1,5 @@
2570 /*
2571+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2572 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2573 * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
2574 * This file may be used under the terms of the MIT License.
2575diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
2576index a29a4ac..0ed952f 100644
2577--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
2578+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
2579@@ -1,4 +1,5 @@
2580 /*
2581+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2582 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2583 * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
2584 * This file may be used under the terms of the MIT License.
2585diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
2586index d0481e0..57058f5 100644
2587--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
2588+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
2589@@ -1,4 +1,5 @@
2590 /*
2591+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2592 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2593 * Distributed under the terms of the MIT License.
2594 */
2595diff --git a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2596index ef56195..3c994a6 100644
2597--- a/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2598+++ b/src/add-ons/kernel/file_systems/btrfs/kernel_interface.cpp
2599@@ -1,4 +1,5 @@
2600 /*
2601+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2602 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
2603 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
2604 * This file may be used under the terms of the MIT License.
2605diff --git a/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h b/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
2606index 578e276..9f3b2d5 100644
2607--- a/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
2608+++ b/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
2609@@ -1,3 +1,7 @@
2610+/*
2611+ * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com.
2612+ * This file may be used under the terms of the MIT License.
2613+ */
2614 #ifndef _SYSTEM_DEPENDENCIES_H
2615 #define _SYSTEM_DEPENDENCIES_H
2616
2617--
26182.7.4
2619