Ticket #13612: btrfs.patchset2

File btrfs.patchset2, 50.6 KB (added by hyche, 7 years ago)
Line 
1From 7698541e6beb9133c5841593681f5e9595ef354e Mon Sep 17 00:00:00 2001
2From: hyche <cvghy116@gmail.com>
3Date: Sun, 4 Jun 2017 23:07:38 +0700
4Subject: [PATCH 01/15] btrfs_shell: Added cat command
5
6---
7 src/tools/btrfs_shell/Jamfile | 5 +++
8 src/tools/btrfs_shell/additional_commands.cpp | 19 +++++++++
9 src/tools/btrfs_shell/command_cat.cpp | 61 +++++++++++++++++++++++++++
10 src/tools/btrfs_shell/command_cat.h | 17 ++++++++
11 4 files changed, 102 insertions(+)
12 create mode 100644 src/tools/btrfs_shell/additional_commands.cpp
13 create mode 100644 src/tools/btrfs_shell/command_cat.cpp
14 create mode 100644 src/tools/btrfs_shell/command_cat.h
15
16diff --git a/src/tools/btrfs_shell/Jamfile b/src/tools/btrfs_shell/Jamfile
17index a3786e6..dcf071e 100644
18--- a/src/tools/btrfs_shell/Jamfile
19+++ b/src/tools/btrfs_shell/Jamfile
20@@ -26,8 +26,11 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
21 fsShellCommandLibs = $(HOST_NETWORK_LIBS) ;
22 }
23
24+UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
25+
26 if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
27 UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
28+ UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
29 }
30
31 UsePrivateHeaders shared storage fs_shell ;
32@@ -50,6 +53,8 @@ BuildPlatformMergeObject <build>btrfs.o : $(btrfsSources) ;
33
34 BuildPlatformMain <build>btrfs_shell
35 :
36+ additional_commands.cpp
37+ command_cat.cpp
38 :
39 <build>btrfs.o
40 <build>fs_shell.a $(libHaikuCompat) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
41diff --git a/src/tools/btrfs_shell/additional_commands.cpp b/src/tools/btrfs_shell/additional_commands.cpp
42new file mode 100644
43index 0000000..82a1f12
44--- /dev/null
45+++ b/src/tools/btrfs_shell/additional_commands.cpp
46@@ -0,0 +1,19 @@
47+#include "fssh.h"
48+
49+#include "command_cat.h"
50+
51+
52+namespace FSShell {
53+
54+
55+void
56+register_additional_commands()
57+{
58+ CommandManager::Default()->AddCommands(
59+ command_cat, "cat", "concatenate file(s) to stdout",
60+ NULL
61+ );
62+}
63+
64+
65+} // namespace FSShell
66diff --git a/src/tools/btrfs_shell/command_cat.cpp b/src/tools/btrfs_shell/command_cat.cpp
67new file mode 100644
68index 0000000..e1417a8
69--- /dev/null
70+++ b/src/tools/btrfs_shell/command_cat.cpp
71@@ -0,0 +1,61 @@
72+#include <stdio.h>
73+#include <stdlib.h>
74+
75+#include "syscalls.h"
76+#include "system_dependencies.h"
77+
78+
79+namespace FSShell {
80+
81+
82+fssh_status_t
83+command_cat(int argc, const char* const* argv)
84+{
85+ long numBytes = 10;
86+ int fileStart = 1;
87+ if (argc < 2 || strcmp(argv[1], "--help") == 0) {
88+ printf(
89+ "Usage: %s [ -n ] [FILE]...\n"
90+ "\t -n\tNumber of bytes to read\n",
91+ argv[0]
92+ );
93+ return FSSH_B_OK;
94+ }
95+
96+ if (argc > 3 && strcmp(argv[1], "-n") == 0) {
97+ fileStart += 2;
98+ numBytes = strtol(argv[2], NULL, 10);
99+ }
100+
101+ const char* const* files = argv + fileStart;
102+ for (; *files; files++) {
103+ const char* file = *files;
104+ int fd = _kern_open(-1, file, O_RDONLY, O_RDONLY);
105+ if (fd < 0) {
106+ fssh_dprintf("Error: %s\n", fssh_strerror(fd));
107+ return FSSH_B_BAD_VALUE;
108+ }
109+
110+ char buffer[numBytes + 1];
111+ if (buffer == NULL) {
112+ fssh_dprintf("Error: No memory\n");
113+ _kern_close(fd);
114+ return FSSH_B_NO_MEMORY;
115+ }
116+
117+ if (_kern_read(fd, 0, buffer, numBytes) != numBytes) {
118+ fssh_dprintf("Error: fail to read, length: %i\n", numBytes);
119+ _kern_close(fd);
120+ return FSSH_B_BAD_VALUE;
121+ }
122+
123+ _kern_close(fd);
124+ buffer[numBytes] = '\0';
125+ printf("%s\n", buffer);
126+ }
127+
128+ return FSSH_B_OK;
129+}
130+
131+
132+} // namespace FSShell
133diff --git a/src/tools/btrfs_shell/command_cat.h b/src/tools/btrfs_shell/command_cat.h
134new file mode 100644
135index 0000000..a86fd78
136--- /dev/null
137+++ b/src/tools/btrfs_shell/command_cat.h
138@@ -0,0 +1,17 @@
139+#ifndef COMMAND_CAT_H
140+#define COMMAND_CAT_H
141+
142+
143+#include "fssh_types.h"
144+
145+
146+namespace FSShell {
147+
148+
149+fssh_status_t command_cat(int argc, const char* const* argv);
150+
151+
152+} // namespace FSShell
153+
154+
155+#endif // COMMAND_CAT_H
156--
1572.7.4
158
159
160From 370ee09fe5619ef2163545847485362f7adead78 Mon Sep 17 00:00:00 2001
161From: hyche <cvghy116@gmail.com>
162Date: Mon, 26 Jun 2017 23:04:51 +0700
163Subject: [PATCH 02/15] BTRFS: Added logical address (root) for BTree
164
165---
166 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 2 ++
167 src/add-ons/kernel/file_systems/btrfs/BTree.h | 3 ++-
168 2 files changed, 4 insertions(+), 1 deletion(-)
169
170diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
171index 9fed7c9..95f7a14 100644
172--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
173+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
174@@ -279,7 +279,9 @@ BTree::SetRoot(off_t logical, fsblock_t* block)
175 {
176 if (block != NULL) {
177 fRootBlock = *block;
178+ //TODO: mapping physical block -> logical address
179 } else {
180+ fLogicalRoot = logical;
181 if (fVolume->FindBlock(logical, fRootBlock) != B_OK) {
182 ERROR("Find() unmapped block %" B_PRId64 "\n", fRootBlock);
183 return B_ERROR;
184diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
185index ab66735..7ae98dd 100644
186--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
187+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
188@@ -57,8 +57,8 @@ public:
189 size_t* size = NULL);
190
191 status_t SetRoot(off_t logical, fsblock_t* block);
192-
193 fsblock_t RootBlock() const { return fRootBlock; }
194+ off_t LogicalRoot() const { return fLogicalRoot; }
195
196 private:
197 BTree(const BTree& other);
198@@ -73,6 +73,7 @@ private:
199 friend class TreeIterator;
200
201 fsblock_t fRootBlock;
202+ off_t fLogicalRoot;
203 Volume* fVolume;
204 mutex fIteratorLock;
205 SinglyLinkedList<TreeIterator> fIterators;
206--
2072.7.4
208
209
210From 9f9ba0bdc16c867a2f4c7c380cdac7b3390683cf Mon Sep 17 00:00:00 2001
211From: hyche <cvghy116@gmail.com>
212Date: Sat, 1 Jul 2017 00:10:27 +0700
213Subject: [PATCH 03/15] btrfs_shell: Support AVLTree
214
215---
216 headers/private/kernel/util/AVLTreeBase.h | 7 +++++-
217 .../file_systems/btrfs/system_dependencies.h | 2 ++
218 src/system/kernel/util/AVLTreeBase.cpp | 28 ++++++++++++----------
219 src/tools/btrfs_shell/Jamfile | 10 +++++++-
220 4 files changed, 33 insertions(+), 14 deletions(-)
221
222diff --git a/headers/private/kernel/util/AVLTreeBase.h b/headers/private/kernel/util/AVLTreeBase.h
223index 6c9bd7b..6e5cfac 100644
224--- a/headers/private/kernel/util/AVLTreeBase.h
225+++ b/headers/private/kernel/util/AVLTreeBase.h
226@@ -6,7 +6,12 @@
227 #define _KERNEL_UTIL_AVL_TREE_BASE_H
228
229
230-#include <SupportDefs.h>
231+#ifndef FS_SHELL
232+# include <SupportDefs.h>
233+#else
234+# include <algorithm>
235+# include "fssh_api_wrapper.h"
236+#endif
237
238
239 class AVLTreeIterator;
240diff --git a/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h b/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
241index dd337be..578e276 100644
242--- a/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
243+++ b/src/add-ons/kernel/file_systems/btrfs/system_dependencies.h
244@@ -7,6 +7,7 @@
245 // This needs to be included before the fs_shell wrapper
246 #include <zlib.h>
247 #include <new>
248+#include <util/AVLTree.h>
249
250 #include "fssh_api_wrapper.h"
251 #include "fssh_auto_deleter.h"
252@@ -18,6 +19,7 @@
253 #include <util/AutoLock.h>
254 #include <util/SinglyLinkedList.h>
255 #include <util/Stack.h>
256+#include <util/AVLTree.h>
257 #include <sys/stat.h>
258 #include <sys/types.h>
259 #include <ByteOrder.h>
260diff --git a/src/system/kernel/util/AVLTreeBase.cpp b/src/system/kernel/util/AVLTreeBase.cpp
261index 91c3ff0..af473e8 100644
262--- a/src/system/kernel/util/AVLTreeBase.cpp
263+++ b/src/system/kernel/util/AVLTreeBase.cpp
264@@ -6,22 +6,26 @@
265
266 #include <util/AVLTreeBase.h>
267
268-#include <algorithm>
269-
270-#include <KernelExport.h>
271-
272+#ifndef FS_SHELL
273+# include <algorithm>
274+# include <KernelExport.h>
275+#endif
276
277 #ifdef _KERNEL_MODE
278 # define CHECK_FAILED(message...) panic(message)
279 #else
280-# include <stdio.h>
281-# include <OS.h>
282-# define CHECK_FAILED(message...) \
283- do { \
284- fprintf(stderr, message); \
285- fprintf(stderr, "\n"); \
286- debugger("AVLTreeBase check failed"); \
287- } while (false)
288+# ifndef FS_SHELL
289+# include <stdio.h>
290+# include <OS.h>
291+# define CHECK_FAILED(message...) \
292+ do { \
293+ fprintf(stderr, message); \
294+ fprintf(stderr, "\n"); \
295+ debugger("AVLTreeBase check failed"); \
296+ } while (false)
297+# else
298+# define CHECK_FAILED(message...) dprintf(message)
299+# endif
300 #endif
301
302
303diff --git a/src/tools/btrfs_shell/Jamfile b/src/tools/btrfs_shell/Jamfile
304index dcf071e..5502c7e 100644
305--- a/src/tools/btrfs_shell/Jamfile
306+++ b/src/tools/btrfs_shell/Jamfile
307@@ -33,6 +33,7 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
308 UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
309 }
310
311+UsePrivateKernelHeaders ;
312 UsePrivateHeaders shared storage fs_shell ;
313 UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
314 UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
315@@ -49,7 +50,11 @@ local btrfsSources =
316 kernel_interface.cpp
317 ;
318
319-BuildPlatformMergeObject <build>btrfs.o : $(btrfsSources) ;
320+local utilitySources =
321+ AVLTreeBase.cpp
322+;
323+
324+BuildPlatformMergeObject <build>btrfs.o : $(btrfsSources) $(utilitySources) ;
325
326 BuildPlatformMain <build>btrfs_shell
327 :
328@@ -60,3 +65,6 @@ BuildPlatformMain <build>btrfs_shell
329 <build>fs_shell.a $(libHaikuCompat) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
330 $(HOST_LIBROOT) $(fsShellCommandLibs)
331 ;
332+
333+SEARCH on [ FGristFiles $(utilitySources) ]
334+ += [ FDirName $(HAIKU_TOP) src system kernel util ] ;
335--
3362.7.4
337
338
339From 052a981c147e5a04da759c0de4551fa7e703380f Mon Sep 17 00:00:00 2001
340From: hyche <cvghy116@gmail.com>
341Date: Sun, 2 Jul 2017 23:53:20 +0700
342Subject: [PATCH 04/15] BTRFS: Added more on-disk data structures
343
344---
345 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 111 +++++++++++++++++++++++++-
346 1 file changed, 110 insertions(+), 1 deletion(-)
347
348diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
349index fa79f32..3a0d3ea 100644
350--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
351+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
352@@ -12,8 +12,61 @@
353 typedef uint64 fileblock_t; // file block number
354 typedef uint64 fsblock_t; // filesystem block number
355
356-
357 #define BTRFS_SUPER_BLOCK_OFFSET 0x10000
358+#define BTRFS_NUM_ROOT_BACKUPS 4
359+
360+
361+struct btrfs_backup_roots {
362+ uint64 root;
363+ uint64 root_generation;
364+ uint64 chunk_root;
365+ uint64 chunk_root_generation;
366+ uint64 extent_root;
367+ uint64 extent_root_generation;
368+ uint64 fs_root;
369+ uint64 fs_root_generation;
370+ uint64 device_root;
371+ uint64 device_root_generation;
372+ uint64 csum_root;
373+ uint64 csum_root_generation;
374+ uint64 total_size;
375+ uint64 used_size;
376+ uint64 num_devices;
377+ uint8 unused_1[32];
378+ uint8 root_level;
379+ uint8 chunk_root_level;
380+ uint8 extent_root_level;
381+ uint8 fs_root_level;
382+ uint8 device_root_level;
383+ uint8 csum_root_level;
384+ uint8 unused_2[10];
385+
386+ uint64 Root() const { return B_LENDIAN_TO_HOST_INT64(root); }
387+ uint64 RootGen() const
388+ { return B_LENDIAN_TO_HOST_INT64(root_generation); }
389+ uint64 ChunkRoot() const { return B_LENDIAN_TO_HOST_INT64(chunk_root); }
390+ uint64 ChunkRootGen() const
391+ { return B_LENDIAN_TO_HOST_INT64(chunk_root_generation); }
392+ uint64 ExtentRoot() const { return B_LENDIAN_TO_HOST_INT64(extent_root); }
393+ uint64 ExtentRootGen() const
394+ { return B_LENDIAN_TO_HOST_INT64(extent_root_generation); }
395+ uint64 FSRoot() const { return B_LENDIAN_TO_HOST_INT64(fs_root); }
396+ uint64 FSRootGen() const
397+ { return B_LENDIAN_TO_HOST_INT64(fs_root_generation); }
398+ uint64 DeviceRoot() const { return B_LENDIAN_TO_HOST_INT64(device_root); }
399+ uint64 DeviceRootGen() const
400+ { return B_LENDIAN_TO_HOST_INT64(device_root_generation); }
401+ uint64 CSumRoot() const { return B_LENDIAN_TO_HOST_INT64(csum_root); }
402+ uint64 CSumRootGen() const
403+ { return B_LENDIAN_TO_HOST_INT64(csum_root_generation); }
404+ uint8 RootLevel() const { return root_level; }
405+ uint8 ChunkRootLevel() const { return chunk_root_level; }
406+ uint8 ExtentRootLevel() const { return extent_root_level; }
407+ uint8 FSRootLevel() const { return fs_root_level; }
408+ uint8 DeviceRootLevel() const { return device_root_level; }
409+ uint8 CSumRootLevel() const { return csum_root_level; }
410+} _PACKED;
411+
412
413 struct btrfs_key {
414 uint64 object_id;
415@@ -177,6 +230,7 @@ struct btrfs_super_block {
416 char label[256];
417 uint64 reserved[32];
418 uint8 system_chunk_array[2048];
419+ btrfs_backup_roots backup_roots[BTRFS_NUM_ROOT_BACKUPS];
420
421 bool IsValid();
422 // implemented in Volume.cpp
423@@ -239,6 +293,16 @@ struct btrfs_inode {
424 } _PACKED;
425
426
427+struct btrfs_inode_ref {
428+ uint8 index;
429+ uint16 name_length;
430+ uint8 name[];
431+
432+ uint8 Index() const { return index; }
433+ uint16 NameLength() const { return B_LENDIAN_TO_HOST_INT16(name_length); }
434+} _PACKED;
435+
436+
437 struct btrfs_root {
438 btrfs_inode inode;
439 uint64 generation;
440@@ -306,6 +370,51 @@ struct btrfs_extent_data {
441 } _PACKED;
442
443
444+struct btrfs_block_group {
445+ uint64 used_space;
446+ uint64 chunk_object_id;
447+ uint64 flags;
448+
449+ uint64 UsedSpace() const { return B_LENDIAN_TO_HOST_INT64(used_space); }
450+ uint64 ChunkObjectID() const
451+ { return B_HOST_TO_LENDIAN_INT64(chunk_object_id); }
452+ uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
453+} _PACKED;
454+
455+
456+struct btrfs_extent {
457+ uint64 refs;
458+ uint64 generation;
459+ uint64 flags;
460+
461+ uint64 RefCount() const { return B_LENDIAN_TO_HOST_INT64(refs); }
462+ uint64 Generation() const { return B_LENDIAN_TO_HOST_INT64(generation); }
463+ uint64 Flags() const { return B_LENDIAN_TO_HOST_INT64(flags); }
464+} _PACKED;
465+
466+
467+struct btrfs_extent_inline_ref {
468+ uint8 type;
469+ uint64 offset;
470+
471+ uint8 Type() const { return type; }
472+ uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset); }
473+} _PACKED;
474+
475+
476+struct btrfs_extent_data_ref {
477+ uint64 root_id;
478+ uint64 inode_id;
479+ uint64 offset;
480+ uint32 ref_count;
481+
482+ uint64 RootID() const { return B_LENDIAN_TO_HOST_INT64(root_id); }
483+ uint64 InodeID() const { return B_LENDIAN_TO_HOST_INT64(inode_id); }
484+ uint64 Offset() const { return B_LENDIAN_TO_HOST_INT64(offset);}
485+ uint32 RefCount() const { return B_LENDIAN_TO_HOST_INT32(ref_count); }
486+} _PACKED;
487+
488+
489 #define BTRFS_SUPER_BLOCK_MAGIC "_BHRfS_M"
490 #define BTRFS_FIRST_SUBVOLUME 256
491
492--
4932.7.4
494
495
496From 4ba7b70ff3fcc3f5bab5a58ba86d678c9f6c6d9d Mon Sep 17 00:00:00 2001
497From: hyche <cvghy116@gmail.com>
498Date: Sun, 2 Jul 2017 23:55:42 +0700
499Subject: [PATCH 05/15] BTRFS: Added more flags and key types
500
501---
502 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 26 +++++++++++++++++++++-----
503 1 file changed, 21 insertions(+), 5 deletions(-)
504
505diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
506index 3a0d3ea..54e4634 100644
507--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
508+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
509@@ -427,22 +427,38 @@ struct btrfs_extent_data_ref {
510 #define BTRFS_OBJECT_ID_CHECKSUM_TREE 7
511 #define BTRFS_OBJECT_ID_FIRST_CHUNK_TREE 256
512
513-#define BTRFS_KEY_TYPE_CHUNK_ITEM 228
514+#define BTRFS_KEY_TYPE_INODE_ITEM 1
515+#define BTRFS_KEY_TYPE_INODE_REF 12
516+#define BTRFS_KEY_TYPE_XATTR_ITEM 24
517 #define BTRFS_KEY_TYPE_DIR_ITEM 84
518 #define BTRFS_KEY_TYPE_DIR_INDEX 96
519 #define BTRFS_KEY_TYPE_EXTENT_DATA 108
520-#define BTRFS_KEY_TYPE_INODE_ITEM 1
521-#define BTRFS_KEY_TYPE_INODE_REF 12
522 #define BTRFS_KEY_TYPE_ROOT_ITEM 132
523-#define BTRFS_KEY_TYPE_XATTR_ITEM 24
524+#define BTRFS_KEY_TYPE_EXTENT_ITEM 168
525+#define BTRFS_KEY_TYPE_METADATA_ITEM 169
526+#define BTRFS_KEY_TYPE_EXTENT_DATA_REF 178
527+#define BTRFS_KEY_TYPE_BLOCKGROUP_ITEM 192
528+#define BTRFS_KEY_TYPE_CHUNK_ITEM 228
529
530 #define BTRFS_EXTENT_COMPRESS_NONE 0
531 #define BTRFS_EXTENT_COMPRESS_ZLIB 1
532 #define BTRFS_EXTENT_COMPRESS_LZO 2
533-
534 #define BTRFS_EXTENT_DATA_INLINE 0
535 #define BTRFS_EXTENT_DATA_REGULAR 1
536 #define BTRFS_EXTENT_DATA_PRE 2
537+#define BTRFS_EXTENT_FLAG_DATA 1
538+#define BTRFS_EXTENT_FLAG_TREE_BLOCK 2
539+
540+#define BTRFS_BLOCKGROUP_FLAG_DATA 1
541+#define BTRFS_BLOCKGROUP_FLAG_SYSTEM 2
542+#define BTRFS_BLOCKGROUP_FLAG_METADA 4
543+#define BTRFS_BLOCKGROUP_FLAG_RAID0 8
544+#define BTRFS_BLOCKGROUP_FLAG_RAID1 16
545+#define BTRFS_BLOCKGROUP_FLAG_DUP 32
546+#define BTRFS_BLOCKGROUP_FLAG_RAID10 64
547+#define BTRFS_BLOCKGROUP_FLAG_RAID5 128
548+#define BTRFS_BLOCKGROUP_FLAG_RAID6 256
549+#define BTRFS_BLOCKGROUP_FLAG_MASK 511
550
551
552 struct file_cookie {
553--
5542.7.4
555
556
557From a4a1be758af3f433dbf2be87f4dbd8788355746d Mon Sep 17 00:00:00 2001
558From: hyche <cvghy116@gmail.com>
559Date: Tue, 4 Jul 2017 23:51:02 +0700
560Subject: [PATCH 06/15] BTRFS: Added retrieve Volume from BTree
561
562---
563 src/add-ons/kernel/file_systems/btrfs/BTree.h | 2 ++
564 src/add-ons/kernel/file_systems/btrfs/Volume.h | 18 ++++++++++--------
565 2 files changed, 12 insertions(+), 8 deletions(-)
566
567diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
568index 7ae98dd..a85348d 100644
569--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
570+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
571@@ -56,6 +56,8 @@ public:
572 status_t FindPrevious(btrfs_key& key, void** value,
573 size_t* size = NULL);
574
575+ Volume* SystemVolume() const { return fVolume; }
576+
577 status_t SetRoot(off_t logical, fsblock_t* block);
578 fsblock_t RootBlock() const { return fRootBlock; }
579 off_t LogicalRoot() const { return fLogicalRoot; }
580diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h
581index 6561087..d839dc0 100644
582--- a/src/add-ons/kernel/file_systems/btrfs/Volume.h
583+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h
584@@ -38,11 +38,13 @@ public:
585 { return fFSVolume ? fFSVolume->id : -1; }
586 fs_volume* FSVolume() const { return fFSVolume; }
587 const char* Name() const;
588- BTree* FSTree() const { return fFSTree; }
589- BTree* RootTree() const { return fRootTree; }
590+ BTree* FSTree() const { return fFSTree; }
591+ BTree* ExtentTree() const { return fExtentTree; }
592+ BTree* RootTree() const { return fRootTree; }
593
594 uint32 SectorSize() const { return fSectorSize; }
595 uint32 BlockSize() const { return fBlockSize; }
596+ Chunk* SystemChunk() const { return fChunk; }
597
598 btrfs_super_block& SuperBlock() { return fSuperBlock; }
599
600@@ -71,12 +73,12 @@ private:
601 Inode* fRootNode;
602
603 Chunk* fChunk;
604- BTree* fChunkTree;
605- BTree* fRootTree;
606- BTree* fDevTree;
607- BTree* fExtentTree;
608- BTree* fFSTree;
609- BTree* fChecksumTree;
610+ BTree* fChunkTree;
611+ BTree* fRootTree;
612+ BTree* fDevTree;
613+ BTree* fExtentTree;
614+ BTree* fFSTree;
615+ BTree* fChecksumTree;
616 };
617
618
619--
6202.7.4
621
622
623From 46eba5c02d2a8405c9707b60707db9a33ea7244e Mon Sep 17 00:00:00 2001
624From: hyche <cvghy116@gmail.com>
625Date: Wed, 5 Jul 2017 00:08:54 +0700
626Subject: [PATCH 07/15] BTRFS: Some modifications of BTree _Find
627
628* Added "read" argument, may change variable type in the future instead of just bool variable.
629* Now search key's objectId is changed to found key's objectId.
630---
631 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 36 ++++++++++++++-----------
632 src/add-ons/kernel/file_systems/btrfs/BTree.h | 10 +++----
633 2 files changed, 25 insertions(+), 21 deletions(-)
634
635diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
636index 95f7a14..fec0dee 100644
637--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
638+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
639@@ -203,7 +203,7 @@ btrfs_key::Compare(const btrfs_key& key) const
640 */
641 status_t
642 BTree::_Find(btrfs_key& key, void** _value, size_t* _size,
643- btree_traversing type)
644+ bool read, btree_traversing type)
645 {
646 TRACE("Find() objectid %" B_PRId64 " type %d offset %" B_PRId64 " \n",
647 key.ObjectID(), key.Type(), key.Offset());
648@@ -229,8 +229,15 @@ BTree::_Find(btrfs_key& key, void** _value, size_t* _size,
649
650 TRACE("Find() dump count %" B_PRId32 "\n", node.ItemCount());
651 ret = node.SearchSlot(key, &slot, type);
652+ if ((slot >= node.ItemCount() || node.Item(slot)->key.Type() != key.Type())
653+ && read == true
654+ || ret != B_OK) {
655+ TRACE("Find() not found %" B_PRId64 " %" B_PRId64 "\n", key.Offset(),
656+ key.ObjectID());
657+ return B_ENTRY_NOT_FOUND;
658+ }
659
660- if ( ret == B_OK && node.Item(slot)->key.Type() == key.Type()) {
661+ if (read == true) {
662 TRACE("Find() found %" B_PRIu32 " %" B_PRIu32 "\n",
663 node.Item(slot)->Offset(), node.Item(slot)->Size());
664
665@@ -239,38 +246,35 @@ BTree::_Find(btrfs_key& key, void** _value, size_t* _size,
666 memcpy(*_value, node.ItemData(slot),
667 node.Item(slot)->Size());
668 key.SetOffset(node.Item(slot)->key.Offset());
669+ key.SetObjectID(node.Item(slot)->key.ObjectID());
670 if (_size != NULL)
671 *_size = node.Item(slot)->Size();
672 }
673- return B_OK;
674+ } else {
675+ *_value = (void*)&slot;
676 }
677-
678-
679- TRACE("Find() not found %" B_PRId64 " %" B_PRId64 "\n", key.Offset(),
680- key.ObjectID());
681-
682- return B_ENTRY_NOT_FOUND;
683+ return B_OK;
684 }
685
686
687 status_t
688-BTree::FindNext(btrfs_key& key, void** _value, size_t* _size)
689+BTree::FindNext(btrfs_key& key, void** _value, size_t* _size, bool read)
690 {
691- return _Find(key, _value, _size, BTREE_FORWARD);
692+ return _Find(key, _value, _size, read, BTREE_FORWARD);
693 }
694
695
696 status_t
697-BTree::FindPrevious(btrfs_key& key, void** _value, size_t* _size)
698+BTree::FindPrevious(btrfs_key& key, void** _value, size_t* _size, bool read)
699 {
700- return _Find(key, _value, _size, BTREE_BACKWARD);
701+ return _Find(key, _value, _size, read, BTREE_BACKWARD);
702 }
703
704
705 status_t
706-BTree::FindExact(btrfs_key& key, void** _value, size_t* _size)
707+BTree::FindExact(btrfs_key& key, void** _value, size_t* _size, bool read)
708 {
709- return _Find(key, _value, _size, BTREE_EXACT);
710+ return _Find(key, _value, _size, read, BTREE_EXACT);
711 }
712
713
714@@ -338,7 +342,7 @@ TreeIterator::Traverse(btree_traversing direction, btrfs_key& key,
715
716 fCurrentKey.SetOffset(fCurrentKey.Offset() + direction);
717 status_t status = fTree->_Find(fCurrentKey, value, size,
718- direction);
719+ true, direction);
720 if (status != B_OK) {
721 TRACE("TreeIterator::Traverse() Find failed\n");
722 return B_ENTRY_NOT_FOUND;
723diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
724index a85348d..eebd132 100644
725--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
726+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
727@@ -50,11 +50,11 @@ public:
728 fsblock_t rootBlock);
729 ~BTree();
730 status_t FindExact(btrfs_key& key, void** value,
731- size_t* size = NULL);
732+ size_t* size = NULL, bool read = true);
733 status_t FindNext(btrfs_key& key, void** value,
734- size_t* size = NULL);
735+ size_t* size = NULL, bool read = true);
736 status_t FindPrevious(btrfs_key& key, void** value,
737- size_t* size = NULL);
738+ size_t* size = NULL, bool read = true);
739
740 Volume* SystemVolume() const { return fVolume; }
741
742@@ -67,8 +67,8 @@ private:
743 BTree& operator=(const BTree& other);
744 // no implementation
745
746- status_t _Find(btrfs_key& key, void** value,
747- size_t* size, btree_traversing type);
748+ status_t _Find(btrfs_key& key, void** value, size_t* size,
749+ bool read, btree_traversing type);
750 void _AddIterator(TreeIterator* iterator);
751 void _RemoveIterator(TreeIterator* iterator);
752 private:
753--
7542.7.4
755
756
757From 0c2d2d7f0fb65dffb9d3cafaeab889d45aa4654d Mon Sep 17 00:00:00 2001
758From: hyche <cvghy116@gmail.com>
759Date: Wed, 5 Jul 2017 00:18:23 +0700
760Subject: [PATCH 08/15] btrfs_shell: remove BEOS_COMPATIBLE as Haiku doesn't
761 support anymore
762
763---
764 src/tools/btrfs_shell/Jamfile | 7 ++-----
765 1 file changed, 2 insertions(+), 5 deletions(-)
766
767diff --git a/src/tools/btrfs_shell/Jamfile b/src/tools/btrfs_shell/Jamfile
768index 5502c7e..5029613 100644
769--- a/src/tools/btrfs_shell/Jamfile
770+++ b/src/tools/btrfs_shell/Jamfile
771@@ -27,11 +27,8 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
772 }
773
774 UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
775-
776-if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
777- UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
778- UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
779-}
780+UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
781+UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
782
783 UsePrivateKernelHeaders ;
784 UsePrivateHeaders shared storage fs_shell ;
785--
7862.7.4
787
788
789From 98af25d8751ea77823513163aba6ccfb670e2948 Mon Sep 17 00:00:00 2001
790From: hyche <cvghy116@gmail.com>
791Date: Wed, 5 Jul 2017 00:23:38 +0700
792Subject: [PATCH 09/15] BTRFS: Added new file ExtentAllocator
793
794* New class BlockGroup: This holds block_group item, it handles free extents and extents, now its only dump it out.
795* New class ExtentAllocator: This will know how to allocate blocks or extents, currently no ideas how to implement it.
796* New class FreeExtentTree: An AVLTree that tracks free extents.
797* Jamfile: Added more fields.
798---
799 .../kernel/file_systems/btrfs/ExtentAllocator.cpp | 246 +++++++++++++++++++++
800 .../kernel/file_systems/btrfs/ExtentAllocator.h | 64 ++++++
801 src/add-ons/kernel/file_systems/btrfs/Jamfile | 1 +
802 src/tools/btrfs_shell/Jamfile | 1 +
803 4 files changed, 312 insertions(+)
804 create mode 100644 src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
805 create mode 100644 src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
806
807diff --git a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
808new file mode 100644
809index 0000000..c814d6d
810--- /dev/null
811+++ b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
812@@ -0,0 +1,246 @@
813+#include "ExtentAllocator.h"
814+#include "Chunk.h"
815+
816+
817+struct FreeExtent : AVLTreeNode {
818+ uint64 offset;
819+ uint64 length;
820+ uint64 flags;
821+
822+ FreeExtent(uint64 offset, uint64 length, uint64 flags)
823+ {
824+ this->offset = offset;
825+ this->length = length;
826+ this->flags = flags;
827+ }
828+
829+ uint64 End() const
830+ {
831+ return offset + length;
832+ }
833+
834+ bool Intersect(const FreeExtent* other)
835+ {
836+ if (offset >= other->End() || End() <= other->offset) {
837+ return false;
838+ }
839+ if (offset >= other->offset) {
840+ length = std::min(length, other->End() - offset);
841+ } else {
842+ offset = other->offset;
843+ length = std::min(other->length, End() - other->offset);
844+ }
845+ return true;
846+ }
847+
848+ void info() const
849+ {
850+ TRACE("free extent at %" B_PRIu64 "( %" B_PRIu64 " ) length %" B_PRIu64
851+ " flags %" B_PRIu64 "\n", offset, offset/16384, length/16384, flags);
852+ }
853+};
854+
855+
856+struct TreeDefinition {
857+ typedef uint64 Key;
858+ typedef FreeExtent Value;
859+
860+ AVLTreeNode* GetAVLTreeNode(Value* value) const
861+ {
862+ return value;
863+ }
864+
865+ Value* GetValue(AVLTreeNode* node) const
866+ {
867+ return static_cast<Value*>(node);
868+ }
869+
870+ int Compare(const Key& a, const Value* b) const
871+ {
872+ if (a < b->offset)
873+ return -1;
874+ if (a >= b->End())
875+ return 1;
876+ return 0;
877+ }
878+
879+ int Compare(const Value* a, const Value* b) const
880+ {
881+ int comp = Compare(a->offset, b);
882+ //TODO: check more conditions here for inserting
883+ return comp;
884+ }
885+};
886+
887+
888+struct FreeExtentTree : public AVLTree<TreeDefinition> {
889+ FreeExtentTree(const TreeDefinition& definition)
890+ :
891+ AVLTree<TreeDefinition>(definition)
892+ {
893+ }
894+
895+ void DumpInOrder() const
896+ {
897+ _DumpInOrder(RootNode());
898+ }
899+
900+private:
901+ void _DumpInOrder(FreeExtent* node) const
902+ {
903+ if (node == NULL)
904+ return;
905+ _DumpInOrder(fDefinition.GetValue(node->left));
906+ node->info();
907+ _DumpInOrder(fDefinition.GetValue(node->right));
908+ }
909+};
910+
911+
912+//BlockGroup
913+
914+
915+BlockGroup::BlockGroup(BTree* extentTree)
916+ :
917+ fBlockGroup(NULL),
918+ fExtentTree(extentTree)
919+{
920+ if (Allocate(BTRFS_BLOCKGROUP_FLAG_METADA) != B_OK) {
921+ panic("Fail to initliaze BlockGroup\n");
922+ }
923+}
924+
925+
926+BlockGroup::BlockGroup(BTree* extentTree, uint64 flag)
927+ :
928+ fBlockGroup(NULL),
929+ fExtentTree(extentTree)
930+{
931+ if (Allocate(flag) != B_OK) {
932+ panic("Fail to initliaze BlockGroup\n");
933+ }
934+}
935+
936+
937+BlockGroup::~BlockGroup()
938+{
939+ if (fBlockGroup != NULL)
940+ free(fBlockGroup);
941+}
942+
943+
944+// Allocate BlockGroup that has flag
945+status_t
946+BlockGroup::Allocate(uint64 flag)
947+{
948+ Chunk* chunk = fExtentTree->SystemVolume()->SystemChunk();
949+ fKey.SetObjectID(chunk->Offset());
950+ fKey.SetType(BTRFS_KEY_TYPE_BLOCKGROUP_ITEM);
951+ fKey.SetOffset(0);
952+ status_t status;
953+
954+ while(true) {
955+ status = fExtentTree->FindNext(fKey, (void**)&fBlockGroup);
956+ if ((fBlockGroup->Flags() & flag) == flag || status != B_OK)
957+ break;
958+ fKey.SetObjectID(End());
959+ fKey.SetOffset(0);
960+ }
961+
962+ if (status != B_OK) {
963+ TRACE("BlockGroup::Allocate() cannot find block group has flag: %"
964+ B_PRIu64 "\n", flag);
965+ }
966+
967+ return status;
968+}
969+
970+
971+status_t
972+BlockGroup::LoadExtent(FreeExtentTree* tree, bool inverse)
973+{
974+ btrfs_key searchKey;
975+ void* data;
976+ status_t status;
977+ uint64 flags = fBlockGroup->flags;
978+ uint64 start = Start();
979+
980+ searchKey.SetType(BTRFS_KEY_TYPE_METADATA_ITEM);
981+ uint64 extentSize = fExtentTree->SystemVolume()->BlockSize();
982+ if ((flags & BTRFS_BLOCKGROUP_FLAG_MASK) == BTRFS_BLOCKGROUP_FLAG_DATA)
983+ searchKey.SetType(BTRFS_KEY_TYPE_EXTENT_ITEM);
984+ searchKey.SetObjectID(start);
985+ searchKey.SetOffset(0);
986+
987+ while(true) {
988+ status = fExtentTree->FindNext(searchKey, &data);
989+ if (status != B_OK) {
990+ if (searchKey.ObjectID() == Start()) {
991+ //handle special case when key has objectid == BlockGroup's objectid
992+ searchKey.SetObjectID(Start() + 1);
993+ searchKey.SetOffset(0);
994+ continue;
995+ }
996+ break;
997+ }
998+ if ((flags & BTRFS_BLOCKGROUP_FLAG_MASK) == BTRFS_BLOCKGROUP_FLAG_DATA) {
999+ extentSize = searchKey.Offset();
1000+ }
1001+
1002+ if (inverse == false) {
1003+ } else {
1004+ _InsertFreeExtent(tree, start, searchKey.ObjectID() - start, flags);
1005+ }
1006+ start = searchKey.ObjectID() + extentSize;
1007+ searchKey.SetObjectID(start);
1008+ searchKey.SetOffset(0);
1009+ }
1010+ if (inverse == true) {
1011+ _InsertFreeExtent(tree, start, End() - start, flags);
1012+ }
1013+
1014+ return B_OK;
1015+}
1016+
1017+
1018+status_t
1019+BlockGroup::_InsertFreeExtent(FreeExtentTree* tree, uint64 start, uint64 length,
1020+ uint64 flags)
1021+{
1022+ if (length <= 0)
1023+ return B_BAD_DATA;
1024+ FreeExtent* freeExtent = new FreeExtent(start, length, flags);
1025+ tree->Insert(freeExtent);
1026+ return B_OK;
1027+}
1028+
1029+
1030+// ExtentAllocator
1031+
1032+
1033+ExtentAllocator::ExtentAllocator(Volume* volume)
1034+ :
1035+ fTree(NULL),
1036+ fBlockGroup(NULL),
1037+ fVolume(volume)
1038+{
1039+ fTree = new FreeExtentTree(TreeDefinition());
1040+ fBlockGroup = new BlockGroup(volume->ExtentTree());
1041+}
1042+
1043+
1044+ExtentAllocator::~ExtentAllocator()
1045+{
1046+ delete fTree;
1047+ delete fBlockGroup;
1048+}
1049+
1050+
1051+void
1052+ExtentAllocator::_LoadFreeExtent()
1053+{
1054+ BTree* extentTree = new BTree(fVolume);
1055+ fBlockGroup->LoadExtent(fTree, true);
1056+ fTree->DumpInOrder();
1057+ delete extentTree;
1058+}
1059diff --git a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
1060new file mode 100644
1061index 0000000..56f29d0
1062--- /dev/null
1063+++ b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.h
1064@@ -0,0 +1,64 @@
1065+#ifndef EXTENT_ALLOCATOR_H
1066+#define EXTENT_ALLOCATOR_H
1067+
1068+
1069+#include "Volume.h"
1070+#include "BTree.h"
1071+
1072+
1073+//#define TRACE_BTRFS
1074+#ifdef TRACE_BTRFS
1075+# define TRACE(x...) dprintf("\33[34mbtrfs:\33[0m " x)
1076+#else
1077+# define TRACE(x...) ;
1078+#endif
1079+
1080+
1081+struct FreeExtent;
1082+struct FreeExtentTree;
1083+
1084+
1085+class BlockGroup {
1086+public:
1087+ BlockGroup(BTree* extentTree);
1088+ BlockGroup(BTree* extentTree, uint64 flag);
1089+ ~BlockGroup();
1090+
1091+ status_t Allocate(uint64 flag);
1092+ status_t LoadExtent(FreeExtentTree* tree,
1093+ bool inverse=false);
1094+ uint64 Start() const { return fKey.ObjectID(); }
1095+ uint64 End() const
1096+ { return fKey.ObjectID() + fKey.Offset(); }
1097+
1098+private:
1099+ BlockGroup(const BlockGroup&);
1100+ BlockGroup& operator=(const BlockGroup&);
1101+ status_t _InsertFreeExtent(FreeExtentTree* tree,
1102+ uint64 size, uint64 length, uint64 flags);
1103+
1104+private:
1105+ btrfs_key fKey;
1106+ btrfs_block_group* fBlockGroup;
1107+ BTree* fExtentTree;
1108+};
1109+
1110+
1111+class ExtentAllocator {
1112+public:
1113+ ExtentAllocator(Volume* volume);
1114+ ~ExtentAllocator();
1115+
1116+private:
1117+ ExtentAllocator(const ExtentAllocator&);
1118+ ExtentAllocator& operator=(const ExtentAllocator&);
1119+ void _LoadFreeExtent();
1120+
1121+private:
1122+ Volume* fVolume;
1123+ BlockGroup* fBlockGroup;
1124+ FreeExtentTree* fTree;
1125+};
1126+
1127+
1128+#endif // EXTENT_ALLOCATOR_H
1129diff --git a/src/add-ons/kernel/file_systems/btrfs/Jamfile b/src/add-ons/kernel/file_systems/btrfs/Jamfile
1130index d408e55..78ba20c 100644
1131--- a/src/add-ons/kernel/file_systems/btrfs/Jamfile
1132+++ b/src/add-ons/kernel/file_systems/btrfs/Jamfile
1133@@ -16,6 +16,7 @@ KernelAddon btrfs :
1134 Chunk.cpp
1135 CRCTable.cpp
1136 DirectoryIterator.cpp
1137+ ExtentAllocator.cpp
1138 Inode.cpp
1139 Volume.cpp
1140 : kernel_libz.a
1141diff --git a/src/tools/btrfs_shell/Jamfile b/src/tools/btrfs_shell/Jamfile
1142index 5029613..99231c8 100644
1143--- a/src/tools/btrfs_shell/Jamfile
1144+++ b/src/tools/btrfs_shell/Jamfile
1145@@ -42,6 +42,7 @@ local btrfsSources =
1146 Chunk.cpp
1147 CRCTable.cpp
1148 DirectoryIterator.cpp
1149+ ExtentAllocator.cpp
1150 Inode.cpp
1151 Volume.cpp
1152 kernel_interface.cpp
1153--
11542.7.4
1155
1156
1157From bbaeac057cfc1cd1911eaa0b5adc98f3116a8205 Mon Sep 17 00:00:00 2001
1158From: hyche <cvghy116@gmail.com>
1159Date: Thu, 6 Jul 2017 17:34:49 +0700
1160Subject: [PATCH 10/15] BTRFS: Node now holding Volume instead of cache in
1161 order to retrieve more values.
1162
1163---
1164 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 19 ++++++++++---------
1165 src/add-ons/kernel/file_systems/btrfs/BTree.h | 12 ++++++------
1166 src/add-ons/kernel/file_systems/btrfs/Chunk.h | 6 +++---
1167 .../kernel/file_systems/btrfs/ExtentAllocator.cpp | 4 ++--
1168 src/add-ons/kernel/file_systems/btrfs/Volume.cpp | 1 -
1169 5 files changed, 21 insertions(+), 21 deletions(-)
1170
1171diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1172index fec0dee..3699cb1 100644
1173--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1174+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1175@@ -20,10 +20,10 @@
1176 # define ERROR(x...) dprintf("\33[34mbtrfs:\33[0m " x)
1177
1178
1179-BTree::Node::Node(void* cache)
1180+BTree::Node::Node(Volume* volume)
1181 :
1182 fNode(NULL),
1183- fCache(cache),
1184+ fVolume(volume),
1185 fBlockNumber(0),
1186 fCurrentSlot(0),
1187 fWritable(false)
1188@@ -31,10 +31,10 @@ BTree::Node::Node(void* cache)
1189 }
1190
1191
1192-BTree::Node::Node(void* cache, off_t block)
1193+BTree::Node::Node(Volume* volume, off_t block)
1194 :
1195 fNode(NULL),
1196- fCache(cache),
1197+ fVolume(volume),
1198 fBlockNumber(0),
1199 fCurrentSlot(0),
1200 fWritable(false)
1201@@ -55,11 +55,12 @@ BTree::Node::Keep()
1202 fNode = NULL;
1203 }
1204
1205+
1206 void
1207 BTree::Node::Unset()
1208 {
1209 if (fNode != NULL) {
1210- block_cache_put(fCache, fBlockNumber);
1211+ block_cache_put(fVolume->BlockCache(), fBlockNumber);
1212 fNode = NULL;
1213 }
1214 }
1215@@ -70,7 +71,7 @@ BTree::Node::SetTo(off_t block)
1216 {
1217 Unset();
1218 fBlockNumber = block;
1219- fNode = (btrfs_stream*)block_cache_get(fCache, block);
1220+ fNode = (btrfs_stream*)block_cache_get(fVolume->BlockCache(), block);
1221 }
1222
1223
1224@@ -81,10 +82,10 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
1225 fBlockNumber = block;
1226 fWritable = true;
1227 if (empty) {
1228- fNode = (btrfs_stream*)block_cache_get_empty(fCache, block,
1229+ fNode = (btrfs_stream*)block_cache_get_empty(fVolume->BlockCache(), block,
1230 transactionId);
1231 } else {
1232- fNode = (btrfs_stream*)block_cache_get_writable(fCache, block,
1233+ fNode = (btrfs_stream*)block_cache_get_writable(fVolume->BlockCache(), block,
1234 transactionId);
1235 }
1236 }
1237@@ -207,7 +208,7 @@ BTree::_Find(btrfs_key& key, void** _value, size_t* _size,
1238 {
1239 TRACE("Find() objectid %" B_PRId64 " type %d offset %" B_PRId64 " \n",
1240 key.ObjectID(), key.Type(), key.Offset());
1241- BTree::Node node(fVolume->BlockCache(), fRootBlock);
1242+ BTree::Node node(fVolume, fRootBlock);
1243 int slot, ret;
1244 fsblock_t physicalBlock;
1245
1246diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1247index eebd132..aca0852 100644
1248--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1249+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1250@@ -3,8 +3,8 @@
1251 * Copyright 2001-2010, Axel Dörfler, axeld@pinc-software.de.
1252 * This file may be used under the terms of the MIT License.
1253 */
1254-#ifndef B_PLUS_TREE_H
1255-#define B_PLUS_TREE_H
1256+#ifndef B_TREE_H
1257+#define B_TREE_H
1258
1259
1260 #include "btrfs.h"
1261@@ -83,8 +83,8 @@ private:
1262 public:
1263 class Node {
1264 public:
1265- Node(void* cache);
1266- Node(void* cache, off_t block);
1267+ Node(Volume* volume);
1268+ Node(Volume* volume, off_t block);
1269 ~Node();
1270
1271 // just return from Header
1272@@ -127,7 +127,7 @@ public:
1273 //no implementation
1274
1275 btrfs_stream* fNode;
1276- void* fCache;
1277+ Volume* fVolume;
1278 off_t fBlockNumber;
1279 uint32 fCurrentSlot;
1280 bool fWritable;
1281@@ -202,4 +202,4 @@ TreeIterator::GetPreviousEntry(btrfs_key& key, void** value,
1282 }
1283
1284
1285-#endif // B_PLUS_TREE_H
1286+#endif // B_TREE_H
1287diff --git a/src/add-ons/kernel/file_systems/btrfs/Chunk.h b/src/add-ons/kernel/file_systems/btrfs/Chunk.h
1288index c1fbe49..2b1a3c3 100644
1289--- a/src/add-ons/kernel/file_systems/btrfs/Chunk.h
1290+++ b/src/add-ons/kernel/file_systems/btrfs/Chunk.h
1291@@ -14,8 +14,7 @@
1292
1293 class Chunk {
1294 public:
1295- Chunk(btrfs_chunk* chunk,
1296- fsblock_t offset);
1297+ Chunk(btrfs_chunk* chunk, fsblock_t offset);
1298 ~Chunk();
1299 uint32 Size() const;
1300 status_t FindBlock(off_t logical, off_t& physical);
1301@@ -23,9 +22,10 @@ public:
1302 fsblock_t End() const
1303 { return fChunkOffset + fChunk->Length(); }
1304 private:
1305- btrfs_chunk* fChunk;
1306+ btrfs_chunk* fChunk;
1307 fsblock_t fChunkOffset;
1308 status_t fInitStatus;
1309 };
1310
1311+
1312 #endif // CHUNK_H
1313diff --git a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
1314index c814d6d..e033a95 100644
1315--- a/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
1316+++ b/src/add-ons/kernel/file_systems/btrfs/ExtentAllocator.cpp
1317@@ -220,9 +220,9 @@ BlockGroup::_InsertFreeExtent(FreeExtentTree* tree, uint64 start, uint64 length,
1318
1319 ExtentAllocator::ExtentAllocator(Volume* volume)
1320 :
1321- fTree(NULL),
1322+ fVolume(volume),
1323 fBlockGroup(NULL),
1324- fVolume(volume)
1325+ fTree(NULL)
1326 {
1327 fTree = new FreeExtentTree(TreeDefinition());
1328 fBlockGroup = new BlockGroup(volume->ExtentTree());
1329diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
1330index 561a102..ecad3d0 100644
1331--- a/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
1332+++ b/src/add-ons/kernel/file_systems/btrfs/Volume.cpp
1333@@ -520,4 +520,3 @@ Volume::Identify(int fd, btrfs_super_block* superBlock)
1334
1335 return B_OK;
1336 }
1337-
1338--
13392.7.4
1340
1341
1342From c1a370328d878375a59c013c4b41ceb30f883a46 Mon Sep 17 00:00:00 2001
1343From: hyche <cvghy116@gmail.com>
1344Date: Fri, 7 Jul 2017 23:01:16 +0700
1345Subject: [PATCH 11/15] BTRFS: Initialized space calculating helpers
1346
1347---
1348 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 42 +++++++++++++++++++++++++
1349 src/add-ons/kernel/file_systems/btrfs/BTree.h | 8 ++++-
1350 2 files changed, 49 insertions(+), 1 deletion(-)
1351
1352diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1353index 3699cb1..7abd9fc 100644
1354--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1355+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1356@@ -91,6 +91,48 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
1357 }
1358
1359
1360+//calculate used space, 0 is for internal node, from 1 -> 3 is for leaf
1361+//type 0: calculate for internal nodes
1362+//type 1: only item space
1363+//type 2: only item data space
1364+//type 3: both type 1 and 2
1365+uint32
1366+BTree::Node::_CalculateSpace(uint32 from, uint32 to, uint8 type) const
1367+{
1368+ if (to < from || from < 0 || to >= ItemCount() || ItemCount() == 0)
1369+ return 0;
1370+
1371+ uint32 result = 0;
1372+ if (type == 0) {
1373+ result = sizeof(btrfs_index) * (to - from + 1);
1374+ }
1375+ if ((type & 1) == 1) {
1376+ result += sizeof(btrfs_entry) * (to - from + 1);
1377+ }
1378+ if ((type & 2) == 2) {
1379+ result += Item(from)->Offset() + Item(from)->Size()
1380+ - Item(to)->Offset();
1381+ }
1382+ return result + sizeof(btrfs_header);
1383+}
1384+
1385+
1386+uint32
1387+BTree::Node::SpaceUsed() const
1388+{
1389+ if (Level() == 0)
1390+ return _CalculateSpace(0, ItemCount() - 1, 3);
1391+ return _CalculateSpace(0, ItemCount() - 1, 0);
1392+}
1393+
1394+
1395+uint32
1396+BTree::Node::SpaceLeft() const
1397+{
1398+ return fVolume->BlockSize() - SpaceUsed();
1399+}
1400+
1401+
1402 int32
1403 BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type) const
1404 {
1405diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1406index aca0852..5905645 100644
1407--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1408+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1409@@ -119,13 +119,19 @@ public:
1410 off_t BlockNum() const { return fBlockNumber;}
1411 bool IsWritable() const { return fWritable; }
1412
1413+ uint32 SpaceUsed() const;
1414+ uint32 SpaceLeft() const;
1415+
1416+
1417 int32 SearchSlot(const btrfs_key& key, int* slot,
1418 btree_traversing type) const;
1419- private:
1420+ private:
1421 Node(const Node&);
1422 Node& operator=(const Node&);
1423 //no implementation
1424
1425+ uint32 _CalculateSpace(uint32 from, uint32 to, uint8 type) const;
1426+
1427 btrfs_stream* fNode;
1428 Volume* fVolume;
1429 off_t fBlockNumber;
1430--
14312.7.4
1432
1433
1434From c388583f0fb47e44c219d9486d3cd6b5581d22bc Mon Sep 17 00:00:00 2001
1435From: hyche <cvghy116@gmail.com>
1436Date: Fri, 7 Jul 2017 23:02:26 +0700
1437Subject: [PATCH 12/15] BTRFS: Initialized node copy helpers
1438
1439---
1440 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 58 ++++++++++++++++++++++---
1441 src/add-ons/kernel/file_systems/btrfs/BTree.h | 4 ++
1442 2 files changed, 57 insertions(+), 5 deletions(-)
1443
1444diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1445index 7abd9fc..1801a83 100644
1446--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1447+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1448@@ -91,11 +91,13 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
1449 }
1450
1451
1452-//calculate used space, 0 is for internal node, from 1 -> 3 is for leaf
1453-//type 0: calculate for internal nodes
1454-//type 1: only item space
1455-//type 2: only item data space
1456-//type 3: both type 1 and 2
1457+/*
1458+ * calculate used space, 0 is for internal node, from 1 -> 3 is for leaf
1459+ * type 0: calculate for internal nodes
1460+ * type 1: only item space
1461+ * type 2: only item data space
1462+ * type 3: both type 1 and 2
1463+ */
1464 uint32
1465 BTree::Node::_CalculateSpace(uint32 from, uint32 to, uint8 type) const
1466 {
1467@@ -133,6 +135,52 @@ BTree::Node::SpaceLeft() const
1468 }
1469
1470
1471+void
1472+BTree::Node::_Copy(const BTree::Node* origin, uint32 at, uint32 from,
1473+ uint32 to) const
1474+{
1475+ if (Level() == 0) {
1476+ memcpy(Item(at), origin->Item(from),
1477+ origin->_CalculateSpace(from, to, 1));
1478+ memcpy(ItemData(at), origin->ItemData(from),
1479+ origin->_CalculateSpace(from, to, 2));
1480+ } else {
1481+ memcpy(Index(at), origin->Index(from),
1482+ origin->_CalculateSpace(from, to, 0));
1483+ }
1484+}
1485+
1486+
1487+/*
1488+ * copy item and item data except its header
1489+ * length < 0: removing
1490+ * length > 0: inserting
1491+ */
1492+status_t
1493+BTree::Node::Copy(const BTree::Node* origin, uint32 start, uint32 end,
1494+ int length) const
1495+{
1496+ if (length < 0 && std::abs(length) >= SpaceUsed() - sizeof(btrfs_header)
1497+ || (length > 0 && length >= SpaceLeft()))
1498+ return B_BAD_VALUE;
1499+
1500+ if (length == 0) {
1501+ //copy all
1502+ _Copy(origin, 0, 0, ItemCount() - 1);
1503+ } else if (length < 0) {
1504+ //removing all items in [start, end]
1505+ _Copy(origin, 0, 0, start - 1); // <-- [start,...
1506+ _Copy(origin, start, end + 1, ItemCount() - 1); // ..., end] -->
1507+ } else {
1508+ //inserting in [start, end] - make a hole for later
1509+ _Copy(origin, 0, 0, start - 1);
1510+ _Copy(origin, end + 1, start, ItemCount() - 1);
1511+ }
1512+
1513+ return B_OK;
1514+}
1515+
1516+
1517 int32
1518 BTree::Node::SearchSlot(const btrfs_key& key, int* slot, btree_traversing type) const
1519 {
1520diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1521index 5905645..5d35e95 100644
1522--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1523+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1524@@ -122,6 +122,8 @@ public:
1525 uint32 SpaceUsed() const;
1526 uint32 SpaceLeft() const;
1527
1528+ status_t Copy(const Node* origin, uint32 start,
1529+ uint32 end, int length) const;
1530
1531 int32 SearchSlot(const btrfs_key& key, int* slot,
1532 btree_traversing type) const;
1533@@ -130,6 +132,8 @@ public:
1534 Node& operator=(const Node&);
1535 //no implementation
1536
1537+ void _Copy(const Node* origin, uint32 at, uint32 from,
1538+ uint32 to) const;
1539 uint32 _CalculateSpace(uint32 from, uint32 to, uint8 type) const;
1540
1541 btrfs_stream* fNode;
1542--
15432.7.4
1544
1545
1546From 70c027a1aeee730485bfa9a939bf27c7e7603be2 Mon Sep 17 00:00:00 2001
1547From: hyche <cvghy116@gmail.com>
1548Date: Fri, 7 Jul 2017 23:04:23 +0700
1549Subject: [PATCH 13/15] BTRFS: Added setters for btrfs_header and btrfs_entry
1550
1551---
1552 src/add-ons/kernel/file_systems/btrfs/btrfs.h | 8 ++++++++
1553 1 file changed, 8 insertions(+)
1554
1555diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1556index 54e4634..be88e2b 100644
1557--- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1558+++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h
1559@@ -110,6 +110,13 @@ struct btrfs_header {
1560 uint32 ItemCount() const
1561 { return B_LENDIAN_TO_HOST_INT32(item_count); }
1562 uint8 Level() const { return level; }
1563+ void SetLogicalAddress(uint64 logical)
1564+ { logical_address = B_HOST_TO_LENDIAN_INT64(logical); }
1565+ void SetFlags(uint64 flags) { flags = B_HOST_TO_LENDIAN_INT64(flags); }
1566+ void SetGeneration(uint64 gen) { generation = B_HOST_TO_LENDIAN_INT64(gen);}
1567+ void SetOwner(uint64 id) { owner = B_HOST_TO_LENDIAN_INT64(id); }
1568+ void SetItemCount(uint32 itemCount)
1569+ { item_count = B_HOST_TO_LENDIAN_INT32(itemCount); }
1570 } _PACKED;
1571
1572
1573@@ -132,6 +139,7 @@ struct btrfs_entry {
1574 { return B_LENDIAN_TO_HOST_INT32(offset); }
1575 uint32 Size() const
1576 { return B_LENDIAN_TO_HOST_INT32(size); }
1577+ void SetOffset(uint32 off) { offset = B_HOST_TO_LENDIAN_INT32(off); }
1578 } _PACKED;
1579
1580
1581--
15822.7.4
1583
1584
1585From e60967ff020110eb178b0904b3c566d447a63790 Mon Sep 17 00:00:00 2001
1586From: hyche <cvghy116@gmail.com>
1587Date: Sun, 16 Jul 2017 23:16:52 +0700
1588Subject: [PATCH 14/15] BTRFS: Changed _CalculateSpace function
1589
1590* Now it doesn't take btrfs_header into account.
1591* Removed reduntdant condition test.
1592---
1593 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 11 ++++++-----
1594 1 file changed, 6 insertions(+), 5 deletions(-)
1595
1596diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1597index 1801a83..359ddfe 100644
1598--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1599+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1600@@ -92,7 +92,8 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
1601
1602
1603 /*
1604- * calculate used space, 0 is for internal node, from 1 -> 3 is for leaf
1605+ * calculate used space except the header,
1606+ * 0 is for internal node, from 1 -> 3 is for leaf
1607 * type 0: calculate for internal nodes
1608 * type 1: only item space
1609 * type 2: only item data space
1610@@ -101,7 +102,7 @@ BTree::Node::SetToWritable(off_t block, int32 transactionId, bool empty)
1611 uint32
1612 BTree::Node::_CalculateSpace(uint32 from, uint32 to, uint8 type) const
1613 {
1614- if (to < from || from < 0 || to >= ItemCount() || ItemCount() == 0)
1615+ if (to < from || from < 0 || to >= ItemCount())
1616 return 0;
1617
1618 uint32 result = 0;
1619@@ -115,7 +116,7 @@ BTree::Node::_CalculateSpace(uint32 from, uint32 to, uint8 type) const
1620 result += Item(from)->Offset() + Item(from)->Size()
1621 - Item(to)->Offset();
1622 }
1623- return result + sizeof(btrfs_header);
1624+ return result;
1625 }
1626
1627
1628@@ -123,8 +124,8 @@ uint32
1629 BTree::Node::SpaceUsed() const
1630 {
1631 if (Level() == 0)
1632- return _CalculateSpace(0, ItemCount() - 1, 3);
1633- return _CalculateSpace(0, ItemCount() - 1, 0);
1634+ return _CalculateSpace(0, ItemCount() - 1, 3) + sizeof(btrfs_header);
1635+ return _CalculateSpace(0, ItemCount() - 1, 0) + sizeof(btrfs_header);
1636 }
1637
1638
1639--
16402.7.4
1641
1642
1643From af029401ba37a7dcfd650266e8e8fa0ad595cb1c Mon Sep 17 00:00:00 2001
1644From: hyche <cvghy116@gmail.com>
1645Date: Sun, 16 Jul 2017 23:21:18 +0700
1646Subject: [PATCH 15/15] BTRFS: Fix copy helpers
1647
1648* Fix not handle memory correctly.
1649* Fix misused methods of copy and original node.
1650* Fix insert/remove items when in corner cases (e.g removing/inserting items at the beginning or ending).
1651---
1652 src/add-ons/kernel/file_systems/btrfs/BTree.cpp | 43 +++++++++++++++++++------
1653 src/add-ons/kernel/file_systems/btrfs/BTree.h | 2 +-
1654 2 files changed, 34 insertions(+), 11 deletions(-)
1655
1656diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1657index 359ddfe..1a7ddd8 100644
1658--- a/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1659+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.cpp
1660@@ -138,12 +138,22 @@ BTree::Node::SpaceLeft() const
1661
1662 void
1663 BTree::Node::_Copy(const BTree::Node* origin, uint32 at, uint32 from,
1664- uint32 to) const
1665+ uint32 to, int length) const
1666 {
1667+ TRACE("BTreeNode::_Copy() at: %d from: %d to: %d length: %d\n",
1668+ at, from, to, length);
1669 if (Level() == 0) {
1670 memcpy(Item(at), origin->Item(from),
1671 origin->_CalculateSpace(from, to, 1));
1672- memcpy(ItemData(at), origin->ItemData(from),
1673+
1674+ // Item offset of copied node must be changed to get the
1675+ // item data offset correctly. length can be zero
1676+ // but let it there doesn't harm anything.
1677+ for (int i = at; i - at <= to - from; ++i) {
1678+ Item(i)->SetOffset(Item(i)->Offset() - length);
1679+ TRACE("BTreeNode::_Copy() i: %d offset %d\n", i, Item(i)->Offset());
1680+ }
1681+ memcpy(ItemData(at + to - from), origin->ItemData(to),
1682 origin->_CalculateSpace(from, to, 2));
1683 } else {
1684 memcpy(Index(at), origin->Index(from),
1685@@ -161,21 +171,34 @@ status_t
1686 BTree::Node::Copy(const BTree::Node* origin, uint32 start, uint32 end,
1687 int length) const
1688 {
1689- if (length < 0 && std::abs(length) >= SpaceUsed() - sizeof(btrfs_header)
1690- || (length > 0 && length >= SpaceLeft()))
1691+ if (length < 0
1692+ && std::abs(length) >= origin->SpaceUsed() - sizeof(btrfs_header)
1693+ || (length > 0 && length >= origin->SpaceLeft()))
1694 return B_BAD_VALUE;
1695
1696+ TRACE("BTreeNode::Copy() start %d end %d length %d\n", start,
1697+ end, length);
1698 if (length == 0) {
1699- //copy all
1700- _Copy(origin, 0, 0, ItemCount() - 1);
1701+ _Copy(origin, 0, 0, origin->ItemCount() - 1, 0);
1702 } else if (length < 0) {
1703 //removing all items in [start, end]
1704- _Copy(origin, 0, 0, start - 1); // <-- [start,...
1705- _Copy(origin, start, end + 1, ItemCount() - 1); // ..., end] -->
1706+ if (start > 0)
1707+ _Copy(origin, 0, 0, start - 1, 0); // <-- [start,...
1708+ if (end + 1 < origin->ItemCount()) {
1709+ // we only care data size
1710+ length += sizeof(btrfs_entry) * (end - start + 1);
1711+ // ..., end] -->
1712+ _Copy(origin, start, end + 1, origin->ItemCount() - 1, length);
1713+ }
1714 } else {
1715 //inserting in [start, end] - make a hole for later
1716- _Copy(origin, 0, 0, start - 1);
1717- _Copy(origin, end + 1, start, ItemCount() - 1);
1718+ if (start > 0)
1719+ _Copy(origin, 0, 0, start - 1, 0);
1720+ if (start < origin->ItemCount()) {
1721+ // again we care data size only
1722+ length -= sizeof(btrfs_entry) * (end - start + 1);
1723+ _Copy(origin, end + 1, start, origin->ItemCount() - 1, length);
1724+ }
1725 }
1726
1727 return B_OK;
1728diff --git a/src/add-ons/kernel/file_systems/btrfs/BTree.h b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1729index 5d35e95..a2d6232 100644
1730--- a/src/add-ons/kernel/file_systems/btrfs/BTree.h
1731+++ b/src/add-ons/kernel/file_systems/btrfs/BTree.h
1732@@ -133,7 +133,7 @@ public:
1733 //no implementation
1734
1735 void _Copy(const Node* origin, uint32 at, uint32 from,
1736- uint32 to) const;
1737+ uint32 to, int length) const;
1738 uint32 _CalculateSpace(uint32 from, uint32 to, uint8 type) const;
1739
1740 btrfs_stream* fNode;
1741--
17422.7.4
1743