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 60 BTRFSAddOn::BTRFSAddOn() 61 : BDiskSystemAddOn(kPartitionTypeBTRFS, kDiskSystemFlags) 62 { 63 } 64 65 66 BTRFSAddOn::~BTRFSAddOn() 67 { 68 } 69 70 71 status_t 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 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 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 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 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 177 BTRFSPartitionHandle::BTRFSPartitionHandle(BMutablePartition* partition) 178 : BPartitionHandle(partition) 179 { 180 } 181 182 183 BTRFSPartitionHandle::~BTRFSPartitionHandle() 184 { 185 } 186 187 188 status_t 189 BTRFSPartitionHandle::Init() 190 { 191 return B_OK; 192 } 193 194 195 uint32 196 BTRFSPartitionHandle::SupportedOperations(uint32 mask) 197 { 198 return kDiskSystemFlags & mask; 199 } 200 201 202 status_t 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 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