diff --git a/headers/private/kernel/boot/partitions.h b/headers/private/kernel/boot/partitions.h index 7b226e36d4..81651fb3f3 100644 --- a/headers/private/kernel/boot/partitions.h +++ b/headers/private/kernel/boot/partitions.h @@ -88,6 +88,7 @@ extern partition_module_info gIntelExtendedPartitionModule; struct file_system_module_info { const char *module_name; const char *pretty_name; + float (*identify_file_system)(boot::Partition *device); status_t (*get_file_system)(boot::Partition *device, Directory **_root); }; diff --git a/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp b/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp index ee9c3c1558..4d1cd26e31 100644 --- a/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp +++ b/src/system/boot/loader/file_systems/amiga_ffs/Volume.cpp @@ -100,6 +100,15 @@ Volume::InitCheck() // #pragma mark - +float +amiga_ffs_identify_file_system(boot::Partition *partition) +{ + Volume volume(partition); + + return volume.InitCheck() < B_OK ? 0 : 0.8; +} + + static status_t amiga_ffs_get_file_system(boot::Partition *partition, ::Directory **_root) { @@ -120,6 +129,7 @@ amiga_ffs_get_file_system(boot::Partition *partition, ::Directory **_root) file_system_module_info gAmigaFFSFileSystemModule = { "file_systems/amiga_ffs/v1", kPartitionTypeAmigaFFS, + amiga_ffs_identify_file_system, amiga_ffs_get_file_system }; diff --git a/src/system/boot/loader/file_systems/bfs/bfs.cpp b/src/system/boot/loader/file_systems/bfs/bfs.cpp index 70acf33a58..9b50897ede 100644 --- a/src/system/boot/loader/file_systems/bfs/bfs.cpp +++ b/src/system/boot/loader/file_systems/bfs/bfs.cpp @@ -132,6 +132,15 @@ Volume::ToBlockRun(off_t block) const // #pragma mark - +float +bfs_identify_file_system(boot::Partition *partition) +{ + Volume volume(partition); + + return volume.InitCheck() < B_OK ? 0 : 0.8; +} + + static status_t bfs_get_file_system(boot::Partition *partition, ::Directory **_root) { @@ -152,6 +161,7 @@ bfs_get_file_system(boot::Partition *partition, ::Directory **_root) file_system_module_info gBFSFileSystemModule = { "file_systems/bfs/v1", kPartitionTypeBFS, + bfs_identify_file_system, bfs_get_file_system }; diff --git a/src/system/boot/loader/file_systems/hfs_plus/hfs_plus.cpp b/src/system/boot/loader/file_systems/hfs_plus/hfs_plus.cpp index 9b1a7b0763..c44cc1a227 100644 --- a/src/system/boot/loader/file_systems/hfs_plus/hfs_plus.cpp +++ b/src/system/boot/loader/file_systems/hfs_plus/hfs_plus.cpp @@ -55,6 +55,7 @@ hfs_plus_get_file_system(boot::Partition *partition, ::Directory **_root) file_system_module_info gAmigaFFSFileSystemModule = { "file_systems/hfs_plus/v1", kPartitionTypeHFSPlus, + NULL, hfs_plus_get_file_system }; diff --git a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp index 84a3b88858..835ac4d988 100644 --- a/src/system/boot/loader/file_systems/tarfs/tarfs.cpp +++ b/src/system/boot/loader/file_systems/tarfs/tarfs.cpp @@ -813,6 +813,7 @@ tarfs_get_file_system(boot::Partition *partition, ::Directory **_root) file_system_module_info gTarFileSystemModule = { "file_systems/tarfs/v1", kPartitionTypeTarFS, + NULL, // identify_file_system tarfs_get_file_system }; diff --git a/src/system/boot/loader/partitions.cpp b/src/system/boot/loader/partitions.cpp index 465f21165f..9126bc7499 100644 --- a/src/system/boot/loader/partitions.cpp +++ b/src/system/boot/loader/partitions.cpp @@ -271,8 +271,26 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) bestPriority = priority; } + + // find the best FS module + const file_system_module_info *bestFSModule = NULL; + float bestFSPriority = -1; + for (int32 i = 0; i < sNumFileSystemModules; i++) { + if (sFileSystemModules[i]->identify_file_system == NULL) + continue; + + float priority = sFileSystemModules[i]->identify_file_system(this); + if (priority <= 0) + continue; + + if (priority > bestFSPriority) { + bestFSModule = sFileSystemModules[i]; + bestFSPriority = priority; + } + } + // now let the best matching disk system scan the partition - if (bestModule) { + if (bestModule && bestPriority >= bestFSPriority) { NodeOpener opener(this, O_RDONLY); status_t status = bestModule->scan_partition(opener.Descriptor(), this, bestCookie); @@ -323,8 +341,11 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) // scan for file systems - if (mountFileSystems) + if (mountFileSystems) { + // TODO: Use the FS module we've got, if any. Requires to implement the + // identify_file_system() hook in every FS. return Mount(); + } return B_ENTRY_NOT_FOUND; }