* More debug output.
* We apparently cannot use constants like kPartitionTypeIntelExtended in static array initializers in the kernel. * Fixed misunderstanding between Axel (boot loader) and me (Intel partitioning system module) how to deal with the cookie the identify() hook returns. We switch to a someone cleaner method by always invoking free_identify_cookie() for it, even if it were passed to scan(). Since we want to keep the cookie, we add a reference counter to it. This should fix a couple of issues with recognizing the boot partition. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12185 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8e6163ac4d
commit
f2162522b0
@ -40,13 +40,13 @@ static const struct partition_type kPartitionTypes[] = {
|
||||
{ 0x02, "Xenix root" },
|
||||
{ 0x03, "Xenix user" },
|
||||
{ 0x04, "FAT 16-bit (dos 3.0)" },
|
||||
{ 0x05, /*"Extended Partition"*/kPartitionTypeIntelExtended },
|
||||
{ 0x05, /*"Extended Partition"*/INTEL_EXTENDED_PARTITION_NAME },
|
||||
{ 0x06, "FAT 16-bit (dos 3.31)" },
|
||||
{ 0x07, "OS/2 IFS, Windows NT, Advanced Unix" },
|
||||
{ 0x0b, "FAT 32-bit" },
|
||||
{ 0x0c, "FAT 32-bit, LBA-mapped" },
|
||||
{ 0x0d, "FAT 16-bit, LBA-mapped" },
|
||||
{ 0x0f, /*"Extended Partition, LBA-mapped"*/kPartitionTypeIntelExtended },
|
||||
{ 0x0f, /*"Extended Partition, LBA-mapped"*/INTEL_EXTENDED_PARTITION_NAME },
|
||||
{ 0x42, "Windows 2000 marker (switches to a proprietary partition table)" },
|
||||
{ 0x4d, "QNX 4" },
|
||||
{ 0x4e, "QNX 4 2nd part" },
|
||||
@ -54,7 +54,7 @@ static const struct partition_type kPartitionTypes[] = {
|
||||
{ 0x78, "XOSL boot loader" },
|
||||
{ 0x82, "Linux swapfile" },
|
||||
{ 0x83, "Linux native" },
|
||||
{ 0x85, /*"Linux extendend partition"*/kPartitionTypeIntelExtended },
|
||||
{ 0x85, /*"Linux extendend partition"*/INTEL_EXTENDED_PARTITION_NAME },
|
||||
{ 0xa5, "FreeBSD" },
|
||||
{ 0xa6, "OpenBSD" },
|
||||
{ 0xa7, "NextSTEP" },
|
||||
@ -62,7 +62,7 @@ static const struct partition_type kPartitionTypes[] = {
|
||||
{ 0xa9, "NetBSD" },
|
||||
{ 0xab, "MacOS X boot" },
|
||||
{ 0xbe, "Solaris 8 boot" },
|
||||
{ 0xeb, /*"BeOS"*/ kPartitionTypeBFS },
|
||||
{ 0xeb, /*"BeOS"*/ BFS_NAME },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,12 @@
|
||||
#include <SupportDefs.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
// These match those in DiskDeviceTypes.cpp and *must* be kept in sync.
|
||||
#define INTEL_PARTITION_NAME "Intel Partition Map"
|
||||
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
|
||||
#define BFS_NAME "BFS Filesystem"
|
||||
|
||||
|
||||
// is_empty_type
|
||||
static inline
|
||||
bool
|
||||
|
@ -118,21 +118,25 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||
"partitions for extended partition reached. Cycle?\n"));
|
||||
error = B_BAD_DATA;
|
||||
}
|
||||
|
||||
// read the PTS
|
||||
if (error == B_OK)
|
||||
error = _ReadPTS(offset);
|
||||
|
||||
// check the signature
|
||||
if (error == B_OK
|
||||
&& fPTS->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParseExtended(): invalid PTS signature\n"));
|
||||
error = B_BAD_DATA;
|
||||
}
|
||||
|
||||
// ignore the PTS, if any error occured till now
|
||||
if (error != B_OK) {
|
||||
TRACE(("intel: _ParseExtended(): ignoring this PTS\n"));
|
||||
error = B_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
// examine the table
|
||||
LogicalPartition extended;
|
||||
LogicalPartition nonExtended;
|
||||
@ -168,10 +172,15 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||
if (partition && !partition->CheckLocation(fSessionSize,
|
||||
fBlockSize)) {
|
||||
error = B_BAD_DATA;
|
||||
TRACE(("intel: _ParseExtended(): Invalid partition "
|
||||
"location: pts: %lld, offset: %lld, size: %lld\n",
|
||||
partition->PTSOffset(), partition->Offset(),
|
||||
partition->Size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add non-extended partition to list
|
||||
if (error == B_OK && !nonExtended.IsEmpty()) {
|
||||
LogicalPartition *partition
|
||||
@ -181,12 +190,14 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||
else
|
||||
error = B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// prepare to parse next extended partition
|
||||
if (error == B_OK && !extended.IsEmpty())
|
||||
offset = extended.Offset();
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -212,8 +223,7 @@ PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
|
||||
#else
|
||||
error = B_IO_ERROR;
|
||||
#endif
|
||||
TRACE(("intel: _ReadPTS(): reading the PTS failed: %s\n",
|
||||
strerror(error)));
|
||||
TRACE(("intel: _ReadPTS(): reading the PTS failed: %lx\n", error));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
@ -38,9 +38,24 @@
|
||||
#define INTEL_PARTITION_MODULE_NAME "partitioning_systems/intel/map/v1"
|
||||
#define INTEL_EXTENDED_PARTITION_MODULE_NAME "partitioning_systems/intel/extended/v1"
|
||||
|
||||
// these match those in DiskDeviceTypes.cpp
|
||||
#define INTEL_PARTITION_NAME "Intel Partition Map"
|
||||
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
|
||||
// no atomic_add() in the boot loader
|
||||
#ifdef _BOOT_MODE
|
||||
|
||||
inline int32
|
||||
atomic_add(int32 *a, int32 num)
|
||||
{
|
||||
int32 oldA = *a;
|
||||
*a += num;
|
||||
return oldA;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// A PartitionMap with reference count.
|
||||
struct PartitionMapCookie : PartitionMap {
|
||||
int32 ref_count;
|
||||
};
|
||||
|
||||
|
||||
// intel partition map module
|
||||
@ -275,14 +290,17 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
// check parameters
|
||||
if (fd < 0 || !partition || !cookie)
|
||||
return -1;
|
||||
|
||||
TRACE(("intel: pm_identify_partition(%d, %ld: %lld, %lld, %ld)\n", fd,
|
||||
partition->id, partition->offset, partition->size,
|
||||
partition->block_size));
|
||||
|
||||
// reject extended partitions
|
||||
if (partition->type
|
||||
&& !strcmp(partition->type, kPartitionTypeIntelExtended)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check block size
|
||||
uint32 blockSize = partition->block_size;
|
||||
if (blockSize < sizeof(partition_table_sector)) {
|
||||
@ -290,10 +308,13 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
">= %ld\n", blockSize, sizeof(partition_table_sector)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// allocate a PartitionMap
|
||||
PartitionMap *map = new(nothrow) PartitionMap;
|
||||
PartitionMapCookie *map = new(nothrow) PartitionMapCookie;
|
||||
if (!map)
|
||||
return -1;
|
||||
map->ref_count = 1;
|
||||
|
||||
// read the partition structure
|
||||
PartitionMapParser parser(fd, 0, partition->size, blockSize);
|
||||
status_t error = parser.Parse(NULL, map);
|
||||
@ -301,6 +322,7 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
*cookie = map;
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
// cleanup, if not detected
|
||||
delete map;
|
||||
return -1;
|
||||
@ -311,14 +333,15 @@ static
|
||||
status_t
|
||||
pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
{
|
||||
ObjectDeleter<PartitionMap> deleter((PartitionMap*)cookie);
|
||||
// check parameters
|
||||
if (fd < 0 || !partition || !cookie)
|
||||
return B_ERROR;
|
||||
|
||||
TRACE(("intel: pm_scan_partition(%d, %ld: %lld, %lld, %ld)\n", fd,
|
||||
partition->id, partition->offset, partition->size,
|
||||
partition->block_size));
|
||||
PartitionMap *map = (PartitionMap*)cookie;
|
||||
|
||||
PartitionMapCookie *map = (PartitionMapCookie*)cookie;
|
||||
// fill in the partition_data structure
|
||||
partition->status = B_PARTITION_VALID;
|
||||
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
|
||||
@ -339,7 +362,6 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
index, -1);
|
||||
index++;
|
||||
if (!child) {
|
||||
TRACE(("Creating child at index %ld failed\n", index - 1));
|
||||
// something went wrong
|
||||
error = B_ERROR;
|
||||
break;
|
||||
@ -364,9 +386,10 @@ TRACE(("Creating child at index %ld failed\n", index - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keep map on success or cleanup on error
|
||||
if (error == B_OK) {
|
||||
deleter.Detach();
|
||||
atomic_add(&map->ref_count, 1);
|
||||
} else {
|
||||
partition->content_cookie = NULL;
|
||||
for (int32 i = 0; i < partition->child_count; i++) {
|
||||
@ -382,8 +405,11 @@ static
|
||||
void
|
||||
pm_free_identify_partition_cookie(partition_data */*partition*/, void *cookie)
|
||||
{
|
||||
if (cookie)
|
||||
delete (PartitionMap*)cookie;
|
||||
if (cookie) {
|
||||
PartitionMapCookie *map = (PartitionMapCookie*)cookie;
|
||||
if (atomic_add(&map->ref_count, -1) == 1)
|
||||
delete map;
|
||||
}
|
||||
}
|
||||
|
||||
// pm_free_partition_cookie
|
||||
@ -403,7 +429,7 @@ void
|
||||
pm_free_partition_content_cookie(partition_data *partition)
|
||||
{
|
||||
if (partition && partition->content_cookie) {
|
||||
delete (PartitionMap*)partition->content_cookie;
|
||||
pm_free_identify_partition_cookie(partition, partition->content_cookie);
|
||||
partition->content_cookie = NULL;
|
||||
}
|
||||
}
|
||||
@ -518,8 +544,10 @@ ep_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
// check parameters
|
||||
if (fd < 0 || !partition || !cookie || !partition->cookie)
|
||||
return -1;
|
||||
|
||||
TRACE(("intel: ep_identify_partition(%d, %lld, %lld, %ld)\n", fd,
|
||||
partition->offset, partition->size, partition->block_size));
|
||||
|
||||
// our parent must be a intel partition map partition and we must have
|
||||
// extended partition type
|
||||
if (!partition->type
|
||||
@ -531,6 +559,7 @@ ep_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
|| strcmp(parent->content_type, kPartitionTypeIntel)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// things seem to be in order
|
||||
return 0.5;
|
||||
}
|
||||
@ -543,6 +572,10 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
// check parameters
|
||||
if (fd < 0 || !partition || !partition->cookie)
|
||||
return B_ERROR;
|
||||
|
||||
TRACE(("intel: ep_scan_partition(%d, %lld, %lld, %ld)\n", fd,
|
||||
partition->offset, partition->size, partition->block_size));
|
||||
|
||||
partition_data *parent = get_parent_partition(partition->id);
|
||||
if (!parent)
|
||||
return B_ERROR;
|
||||
@ -566,6 +599,8 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
index++;
|
||||
if (!child) {
|
||||
// something went wrong
|
||||
TRACE(("intel: ep_scan_partition(): failed to create child "
|
||||
"partition\n"));
|
||||
error = B_ERROR;
|
||||
break;
|
||||
}
|
||||
@ -576,6 +611,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
char type[B_FILE_NAME_LENGTH];
|
||||
logical->GetTypeString(type);
|
||||
child->type = strdup(type);
|
||||
|
||||
// parameters
|
||||
char buffer[128];
|
||||
sprintf(buffer, "type = %u ; active = %d", logical->Type(),
|
||||
@ -584,6 +620,8 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||
child->cookie = logical;
|
||||
// check for allocation problems
|
||||
if (!child->type || !child->parameters) {
|
||||
TRACE(("intel: ep_scan_partition(): failed to allocation type "
|
||||
"or parameters\n"));
|
||||
error = B_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user