xref: /haiku/src/add-ons/disk_systems/btrfs/BTRFSAddOn.cpp (revision 1712a3c957dd6644f35764806e556cb9d2ba16d1)
1 /*
2  * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2008-2012, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2012, Gerasim Troeglazov (3dEyes**), 3dEyes@gmail.com
5  * Copyright 2019, Les De Ridder, les@lesderid.net
6  *
7  * Distributed under the terms of the MIT License.
8  */
9 
10 
11 #include "BTRFSAddOn.h"
12 #include "InitializeParameterEditor.h"
13 
14 #include <new>
15 
16 #include <Directory.h>
17 #include <List.h>
18 #include <Path.h>
19 #include <Volume.h>
20 
21 #include <DiskDeviceTypes.h>
22 #include <MutablePartition.h>
23 
24 #include <AutoDeleter.h>
25 #include <StringForSize.h>
26 
27 #include <cstdio>
28 #include <debug.h>
29 
30 #include "btrfs.h"
31 #include "btrfs_disk_system.h"
32 
33 #ifdef ASSERT
34 #	undef ASSERT
35 #endif
36 
37 
38 using std::nothrow;
39 
40 static const uint32 kDiskSystemFlags =
41 	0
42 	| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
43 	| B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
44 //	| B_DISK_SYSTEM_SUPPORTS_CHECKING
45 //	| B_DISK_SYSTEM_SUPPORTS_REPAIRING
46 //	| B_DISK_SYSTEM_SUPPORTS_CHECKING_WHILE_MOUNTED
47 //	| B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED
48 //	| B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING
49 //	| B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED
50 ;
51 
52 //#define TRACE_BTRFS_ADD_ON
53 #undef TRACE
54 #ifdef TRACE_BTRFS_ADD_ON
55 #	define TRACE(x...) printf(x)
56 #else
57 #	define TRACE(x...) do {} while (false)
58 #endif
59 
BTRFSAddOn()60 BTRFSAddOn::BTRFSAddOn()
61 	: BDiskSystemAddOn(kPartitionTypeBTRFS, kDiskSystemFlags)
62 {
63 }
64 
65 
~BTRFSAddOn()66 BTRFSAddOn::~BTRFSAddOn()
67 {
68 }
69 
70 
71 status_t
CreatePartitionHandle(BMutablePartition * partition,BPartitionHandle ** _handle)72 BTRFSAddOn::CreatePartitionHandle(BMutablePartition* partition,
73 	BPartitionHandle** _handle)
74 {
75 	BTRFSPartitionHandle* handle = new(nothrow) BTRFSPartitionHandle(partition);
76 	if (!handle)
77 		return B_NO_MEMORY;
78 
79 	status_t error = handle->Init();
80 	if (error != B_OK) {
81 		delete handle;
82 		return error;
83 	}
84 
85 	*_handle = handle;
86 
87 	return B_OK;
88 }
89 
90 
91 bool
CanInitialize(const BMutablePartition * partition)92 BTRFSAddOn::CanInitialize(const BMutablePartition* partition)
93 {
94 	// We can initialize if the partition is large enough.
95 
96 	//TODO(lesderid): Check min size
97 	return true;
98 }
99 
100 
101 status_t
ValidateInitialize(const BMutablePartition * partition,BString * name,const char * parameterString)102 BTRFSAddOn::ValidateInitialize(const BMutablePartition* partition,
103 	BString* name, const char* parameterString)
104 {
105 	if (!CanInitialize(partition) || !name)
106 		return B_BAD_VALUE;
107 
108 	// truncate, if it is too long
109 	if (name->Length() >= BTRFS_LABEL_SIZE)
110 		name->Truncate(BTRFS_LABEL_SIZE - 1);
111 
112 	// replace '/' and '\\' by '-'
113 	name->ReplaceAll('/', '-');
114 	name->ReplaceAll('\\', '-');
115 
116 	// check parameters
117 	initialize_parameters parameters;
118 	status_t error = parse_initialize_parameters(parameterString, parameters);
119 	if (error != B_OK)
120 		return error;
121 
122 	return B_OK;
123 }
124 
125 
126 status_t
Initialize(BMutablePartition * partition,const char * name,const char * parameterString,BPartitionHandle ** _handle)127 BTRFSAddOn::Initialize(BMutablePartition* partition, const char* name,
128 	const char* parameterString, BPartitionHandle** _handle)
129 {
130 	if (!CanInitialize(partition) || check_volume_name(name) != B_OK)
131 		return B_BAD_VALUE;
132 
133 	initialize_parameters parameters;
134 	status_t error = parse_initialize_parameters(parameterString, parameters);
135 	if (error != B_OK)
136 		return error;
137 
138 	BTRFSPartitionHandle* handle = new(nothrow) BTRFSPartitionHandle(partition);
139 	if (!handle)
140 		return B_NO_MEMORY;
141 	ObjectDeleter<BTRFSPartitionHandle> handleDeleter(handle);
142 
143 	error = partition->SetContentType(Name());
144 	if (error != B_OK)
145 		return error;
146 
147 	partition->SetContentName(name);
148 	partition->SetContentParameters(parameterString);
149 	uint32 blockSize = parameters.blockSize;
150 	partition->SetBlockSize(blockSize);
151 	partition->SetContentSize(partition->Size() / blockSize * blockSize);
152 	partition->Changed(B_PARTITION_CHANGED_INITIALIZATION);
153 
154 	*_handle = handleDeleter.Detach();
155 
156 	return B_OK;
157 }
158 
159 
160 status_t
GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,BPartitionParameterEditor ** editor)161 BTRFSAddOn::GetParameterEditor(B_PARAMETER_EDITOR_TYPE type,
162 	BPartitionParameterEditor** editor)
163 {
164 	*editor = NULL;
165 	if (type == B_INITIALIZE_PARAMETER_EDITOR) {
166 		try {
167 			*editor = new InitializeBTRFSEditor();
168 		} catch (std::bad_alloc&) {
169 			return B_NO_MEMORY;
170 		}
171 		return B_OK;
172 	}
173 	return B_NOT_SUPPORTED;
174 }
175 
176 
BTRFSPartitionHandle(BMutablePartition * partition)177 BTRFSPartitionHandle::BTRFSPartitionHandle(BMutablePartition* partition)
178 	: BPartitionHandle(partition)
179 {
180 }
181 
182 
~BTRFSPartitionHandle()183 BTRFSPartitionHandle::~BTRFSPartitionHandle()
184 {
185 }
186 
187 
188 status_t
Init()189 BTRFSPartitionHandle::Init()
190 {
191 	return B_OK;
192 }
193 
194 
195 uint32
SupportedOperations(uint32 mask)196 BTRFSPartitionHandle::SupportedOperations(uint32 mask)
197 {
198 	return kDiskSystemFlags & mask;
199 }
200 
201 
202 status_t
Repair(bool checkOnly)203 BTRFSPartitionHandle::Repair(bool checkOnly)
204 {
205 	TRACE("BTRFSPartitionHandle::Repair(checkOnly=%d)\n", checkOnly);
206 	return B_NOT_SUPPORTED;
207 }
208 
209 
210 status_t
get_disk_system_add_ons(BList * addOns)211 get_disk_system_add_ons(BList* addOns)
212 {
213 	BTRFSAddOn* addOn = new(nothrow) BTRFSAddOn;
214 	if (!addOn) {
215 		return B_NO_MEMORY;
216 	}
217 
218 	if (!addOns->AddItem(addOn)) {
219 		delete addOn;
220 		return B_NO_MEMORY;
221 	}
222 
223 	return B_OK;
224 }
225