1 // KFileSystem.cpp 2 3 #include <fcntl.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 7 #include <fs_interface.h> 8 9 #include "ddm_modules.h" 10 #include "KDiskDeviceJob.h" 11 #include "KDiskDeviceUtils.h" 12 #include "KFileSystem.h" 13 #include "KPartition.h" 14 15 16 // constructor 17 KFileSystem::KFileSystem(const char *name) 18 : KDiskSystem(name), 19 fModule(NULL) 20 { 21 } 22 23 24 // destructor 25 KFileSystem::~KFileSystem() 26 { 27 } 28 29 30 // Init 31 status_t 32 KFileSystem::Init() 33 { 34 status_t error = KDiskSystem::Init(); 35 if (error != B_OK) 36 return error; 37 error = Load(); 38 if (error != B_OK) 39 return error; 40 error = SetPrettyName(fModule->pretty_name); 41 SetFlags(fModule->flags | B_DISK_SYSTEM_IS_FILE_SYSTEM); 42 Unload(); 43 return error; 44 } 45 46 47 // Identify 48 float 49 KFileSystem::Identify(KPartition *partition, void **cookie) 50 { 51 if (!partition || !cookie || !fModule || !fModule->identify_partition) 52 return -1; 53 int fd = -1; 54 if (partition->Open(O_RDONLY, &fd) != B_OK) 55 return -1; 56 float result = fModule->identify_partition(fd, partition->PartitionData(), 57 cookie); 58 close(fd); 59 return result; 60 } 61 62 63 // Scan 64 status_t 65 KFileSystem::Scan(KPartition *partition, void *cookie) 66 { 67 if (!partition || !fModule || !fModule->scan_partition) 68 return B_ERROR; 69 int fd = -1; 70 status_t result = partition->Open(O_RDONLY, &fd); 71 if (result != B_OK) 72 return result; 73 result = fModule->scan_partition(fd, partition->PartitionData(), cookie); 74 close(fd); 75 return result; 76 } 77 78 79 // FreeIdentifyCookie 80 void 81 KFileSystem::FreeIdentifyCookie(KPartition *partition, void *cookie) 82 { 83 if (!partition || !fModule || !fModule->free_identify_partition_cookie) 84 return; 85 fModule->free_identify_partition_cookie(partition->PartitionData(), 86 cookie); 87 } 88 89 90 // FreeContentCookie 91 void 92 KFileSystem::FreeContentCookie(KPartition *partition) 93 { 94 if (!partition || !fModule || !fModule->free_partition_content_cookie) 95 return; 96 fModule->free_partition_content_cookie(partition->PartitionData()); 97 } 98 99 100 // GetSupportedOperations 101 uint32 102 KFileSystem::GetSupportedOperations(KPartition* partition, uint32 mask) 103 { 104 ASSERT(partition != NULL); 105 106 // Note, that for initialization, the partition's disk system does not 107 // need to be this disk system. 108 109 if (!fModule) 110 return 0; 111 112 if (!fModule->get_supported_operations) 113 return (Flags() & mask); 114 115 return fModule->get_supported_operations(partition->PartitionData(), mask) 116 & mask; 117 } 118 119 120 // ValidateResize 121 bool 122 KFileSystem::ValidateResize(KPartition *partition, off_t *size) 123 { 124 return (partition && size && partition->DiskSystem() == this && fModule 125 && fModule->validate_resize 126 && fModule->validate_resize(partition->PartitionData(), size)); 127 } 128 129 130 // ValidateMove 131 bool 132 KFileSystem::ValidateMove(KPartition *partition, off_t *start) 133 { 134 return (partition && start && partition->DiskSystem() == this && fModule 135 && fModule->validate_move 136 && fModule->validate_move(partition->PartitionData(), start)); 137 } 138 139 140 // ValidateSetContentName 141 bool 142 KFileSystem::ValidateSetContentName(KPartition *partition, char *name) 143 { 144 return (partition && name && partition->DiskSystem() == this 145 && fModule && fModule->validate_set_content_name 146 && fModule->validate_set_content_name(partition->PartitionData(), 147 name)); 148 } 149 150 151 // ValidateSetContentParameters 152 bool 153 KFileSystem::ValidateSetContentParameters(KPartition *partition, 154 const char *parameters) 155 { 156 return (partition && partition->DiskSystem() == this && fModule 157 && fModule->validate_set_content_parameters 158 && fModule->validate_set_content_parameters( 159 partition->PartitionData(), parameters)); 160 } 161 162 163 // ValidateInitialize 164 bool 165 KFileSystem::ValidateInitialize(KPartition *partition, char *name, 166 const char *parameters) 167 { 168 return (partition && fModule && fModule->validate_initialize 169 && fModule->validate_initialize(partition->PartitionData(), name, 170 parameters)); 171 } 172 173 174 // ShadowPartitionChanged 175 status_t 176 KFileSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child, 177 uint32 operation) 178 { 179 if (!partition) 180 return B_BAD_VALUE; 181 if (!fModule) 182 return B_ERROR; 183 // If not implemented, we assume, that the file system doesn't have to 184 // make any additional changes. 185 if (!fModule->shadow_changed) 186 return B_OK; 187 return fModule->shadow_changed(partition->PartitionData(), 188 child ? child->PartitionData() : NULL, operation); 189 } 190 191 192 // Defragment 193 status_t 194 KFileSystem::Defragment(KPartition *partition, KDiskDeviceJob *job) 195 { 196 // to be implemented 197 return B_ERROR; 198 } 199 200 201 // Repair 202 status_t 203 KFileSystem::Repair(KPartition *partition, bool checkOnly, KDiskDeviceJob *job) 204 { 205 // to be implemented 206 return B_ERROR; 207 } 208 209 210 // Resize 211 status_t 212 KFileSystem::Resize(KPartition *partition, off_t size, KDiskDeviceJob *job) 213 { 214 // to be implemented 215 return B_ERROR; 216 } 217 218 219 // Move 220 status_t 221 KFileSystem::Move(KPartition *partition, off_t offset, KDiskDeviceJob *job) 222 { 223 // to be implemented 224 return B_ERROR; 225 } 226 227 228 // SetContentName 229 status_t 230 KFileSystem::SetContentName(KPartition *partition, char *name, 231 KDiskDeviceJob *job) 232 { 233 // to be implemented 234 return B_ERROR; 235 } 236 237 238 status_t 239 KFileSystem::SetContentParameters(KPartition *partition, 240 const char *parameters, KDiskDeviceJob *job) 241 { 242 // to be implemented 243 return B_ERROR; 244 } 245 246 247 status_t 248 KFileSystem::Initialize(KPartition *partition, const char *name, 249 const char *parameters, KDiskDeviceJob *job) 250 { 251 // check parameters 252 if (!partition || !job || !fModule) 253 return B_BAD_VALUE; 254 if (!fModule->initialize) 255 return B_NOT_SUPPORTED; 256 257 // open partition device (we need a temporary read-lock) 258 KDiskDeviceManager *manager = KDiskDeviceManager::Default(); 259 if (!manager->ReadLockPartition(partition->ID())) 260 return B_ERROR; 261 DeviceReadLocker locker(partition->Device(), true); 262 263 int fd = -1; 264 status_t result = partition->Open(O_RDWR, &fd); 265 if (result != B_OK) 266 return result; 267 268 off_t partitionSize = partition->Size(); 269 270 locker.Unlock(); 271 272 // call the module hook 273 result = fModule->initialize(fd, partition->ID(), name, parameters, 274 partitionSize, job->ID()); 275 276 close(fd); 277 return result; 278 } 279 280 281 // LoadModule 282 status_t 283 KFileSystem::LoadModule() 284 { 285 if (fModule) // shouldn't happen 286 return B_OK; 287 288 return get_module(Name(), (module_info **)&fModule); 289 } 290 291 292 // UnloadModule 293 void 294 KFileSystem::UnloadModule() 295 { 296 if (fModule) { 297 put_module(fModule->info.name); 298 fModule = NULL; 299 } 300 } 301 302