* Added the partition size as parameter to the file and partitioning

system initialize() hooks. It's often the only info about the
  partition one needs and thus locking the partition just to get it is
  no longer necessary.
* intel partitioning system:
  - Removed passing around block sizes. We require 512 byte sectors
    anyway. In fact using the parent partition's block size was even
    wrong.
  - Simplified writing the partition map sector.
  - Simplified and corrected the partition map initialization.
  - We don't fail identifying a partition anymore, if the partition map
    contains no partitions. We would never identify a freshly
    initialized partition map before.
  - Made pm_identify() more intelligent: It determines the priority to
    return depending on whether the partition is the device itself and
    whether we have recognized child partitions.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22447 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-10-04 23:48:18 +00:00
parent 6748659272
commit db5c68ca46
17 changed files with 245 additions and 259 deletions
+1 -1
View File
@@ -235,7 +235,7 @@ typedef struct file_system_module_info {
status_t (*set_content_parameters)(int fd, partition_id partition, status_t (*set_content_parameters)(int fd, partition_id partition,
const char *parameters, disk_job_id job); const char *parameters, disk_job_id job);
status_t (*initialize)(int fd, partition_id partition, const char *name, status_t (*initialize)(int fd, partition_id partition, const char *name,
const char *parameters, disk_job_id job); const char *parameters, off_t partitionSize, disk_job_id job);
} file_system_module_info; } file_system_module_info;
+2 -1
View File
@@ -273,7 +273,8 @@ typedef struct fssh_file_system_module_info {
fssh_status_t (*set_content_parameters)(int fd, fssh_partition_id partition, fssh_status_t (*set_content_parameters)(int fd, fssh_partition_id partition,
const char *parameters, fssh_disk_job_id job); const char *parameters, fssh_disk_job_id job);
fssh_status_t (*initialize)(int fd, fssh_partition_id partition, fssh_status_t (*initialize)(int fd, fssh_partition_id partition,
const char *name, const char *parameters, fssh_disk_job_id job); const char *name, const char *parameters,
fssh_off_t partitionSize, fssh_disk_job_id job);
} fssh_file_system_module_info; } fssh_file_system_module_info;
@@ -94,7 +94,7 @@ typedef struct partition_module_info {
status_t (*set_content_parameters)(int fd, partition_id partition, status_t (*set_content_parameters)(int fd, partition_id partition,
const char* parameters, disk_job_id job); const char* parameters, disk_job_id job);
status_t (*initialize)(int fd, partition_id partition, const char* name, status_t (*initialize)(int fd, partition_id partition, const char* name,
const char *parameters, disk_job_id job); const char *parameters, off_t partitionSize, disk_job_id job);
status_t (*create_child)(int fd, partition_id partition, off_t offset, status_t (*create_child)(int fd, partition_id partition, off_t offset,
off_t size, const char* type, const char* parameters, off_t size, const char* type, const char* parameters,
disk_job_id job, partition_id* childID); disk_job_id job, partition_id* childID);
@@ -2092,7 +2092,7 @@ bfs_validate_initialize(partition_data *partition, char *name,
static status_t static status_t
bfs_initialize(int fd, partition_id partitionID, const char *name, bfs_initialize(int fd, partition_id partitionID, const char *name,
const char *parameterString, disk_job_id job) const char *parameterString, off_t /*partitionSize*/, disk_job_id job)
{ {
// parse parameters // parse parameters
initialize_parameters parameters; initialize_parameters parameters;
@@ -298,25 +298,25 @@ Partition::Partition()
// constructor // constructor
Partition::Partition(const partition_descriptor *descriptor,off_t ptsOffset, Partition::Partition(const partition_descriptor *descriptor,off_t ptsOffset,
off_t baseOffset, int32 blockSize) off_t baseOffset)
: fPTSOffset(0), : fPTSOffset(0),
fOffset(0), fOffset(0),
fSize(0), fSize(0),
fType(0), fType(0),
fActive(false) fActive(false)
{ {
SetTo(descriptor, ptsOffset, baseOffset, blockSize); SetTo(descriptor, ptsOffset, baseOffset);
} }
// SetTo // SetTo
void void
Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset, Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
off_t baseOffset, int32 blockSize) off_t baseOffset)
{ {
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active)); TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
fPTSOffset = ptsOffset; fPTSOffset = ptsOffset;
fOffset = baseOffset + (off_t)descriptor->start * blockSize; fOffset = baseOffset + (off_t)descriptor->start * SECTOR_SIZE;
fSize = (off_t)descriptor->size * blockSize; fSize = (off_t)descriptor->size * SECTOR_SIZE;
fType = descriptor->type; fType = descriptor->type;
fActive = descriptor->active; fActive = descriptor->active;
if (fSize == 0) if (fSize == 0)
@@ -337,10 +337,10 @@ Partition::Unset()
// GetPartitionDescriptor // GetPartitionDescriptor
void void
Partition::GetPartitionDescriptor(partition_descriptor *descriptor, Partition::GetPartitionDescriptor(partition_descriptor *descriptor,
off_t baseOffset, int32 blockSize) const off_t baseOffset) const
{ {
descriptor->start = (fOffset - baseOffset) / blockSize; descriptor->start = (fOffset - baseOffset) / SECTOR_SIZE;
descriptor->size = fSize / blockSize; descriptor->size = fSize / SECTOR_SIZE;
descriptor->type = fType; descriptor->type = fType;
descriptor->active = fActive ? 0x80 : 0x00; descriptor->active = fActive ? 0x80 : 0x00;
descriptor->begin.Unset(); descriptor->begin.Unset();
@@ -362,13 +362,13 @@ Partition::AdjustSize(off_t sessionSize)
bool bool
Partition::CheckLocation(off_t sessionSize, int32 blockSize) const Partition::CheckLocation(off_t sessionSize) const
{ {
// offsets and size must be block aligned, PTS and partition must lie // offsets and size must be block aligned, PTS and partition must lie
// within the session // within the session
return fPTSOffset % blockSize == 0 return fPTSOffset % SECTOR_SIZE == 0
&& fOffset % blockSize == 0 && fOffset % SECTOR_SIZE == 0
&& fSize % blockSize == 0 && fSize % SECTOR_SIZE == 0
&& fPTSOffset >= 0 && fPTSOffset < sessionSize && fPTSOffset >= 0 && fPTSOffset < sessionSize
&& fOffset >= 0 && fOffset + fSize <= sessionSize; && fOffset >= 0 && fOffset + fSize <= sessionSize;
} }
@@ -388,22 +388,21 @@ PrimaryPartition::PrimaryPartition()
// constructor // constructor
PrimaryPartition::PrimaryPartition(const partition_descriptor *descriptor, PrimaryPartition::PrimaryPartition(const partition_descriptor *descriptor,
off_t ptsOffset, int32 blockSize) off_t ptsOffset)
: Partition(), : Partition(),
fHead(NULL), fHead(NULL),
fTail(NULL), fTail(NULL),
fLogicalPartitionCount(0) fLogicalPartitionCount(0)
{ {
SetTo(descriptor, ptsOffset, blockSize); SetTo(descriptor, ptsOffset);
} }
// SetTo // SetTo
void void
PrimaryPartition::SetTo(const partition_descriptor *descriptor, PrimaryPartition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset)
off_t ptsOffset, int32 blockSize)
{ {
Unset(); Unset();
Partition::SetTo(descriptor, ptsOffset, 0, blockSize); Partition::SetTo(descriptor, ptsOffset, 0);
} }
// Unset // Unset
@@ -488,27 +487,25 @@ LogicalPartition::LogicalPartition()
// constructor // constructor
LogicalPartition::LogicalPartition(const partition_descriptor *descriptor, LogicalPartition::LogicalPartition(const partition_descriptor *descriptor,
off_t ptsOffset, int32 blockSize, off_t ptsOffset, PrimaryPartition *primary)
PrimaryPartition *primary)
: Partition(), : Partition(),
fPrimary(NULL), fPrimary(NULL),
fNext(NULL), fNext(NULL),
fPrevious(NULL) fPrevious(NULL)
{ {
SetTo(descriptor, ptsOffset, blockSize, primary); SetTo(descriptor, ptsOffset, primary);
} }
// SetTo // SetTo
void void
LogicalPartition::SetTo(const partition_descriptor *descriptor, LogicalPartition::SetTo(const partition_descriptor *descriptor,
off_t ptsOffset, int32 blockSize, off_t ptsOffset, PrimaryPartition *primary)
PrimaryPartition *primary)
{ {
Unset(); Unset();
if (descriptor && primary) { if (descriptor && primary) {
off_t baseOffset = (descriptor->is_extended() ? primary->Offset() off_t baseOffset = (descriptor->is_extended() ? primary->Offset()
: ptsOffset); : ptsOffset);
Partition::SetTo(descriptor, ptsOffset, baseOffset, blockSize); Partition::SetTo(descriptor, ptsOffset, baseOffset);
fPrimary = primary; fPrimary = primary;
} }
} }
@@ -619,12 +616,12 @@ PartitionMap::PartitionAt(int32 index) const
// Check // Check
bool bool
PartitionMap::Check(off_t sessionSize, int32 blockSize) const PartitionMap::Check(off_t sessionSize) const
{ {
int32 partitionCount = CountPartitions(); int32 partitionCount = CountPartitions();
// 1. check partition locations // 1. check partition locations
for (int32 i = 0; i < partitionCount; i++) { for (int32 i = 0; i < partitionCount; i++) {
if (!PartitionAt(i)->CheckLocation(sessionSize, blockSize)) if (!PartitionAt(i)->CheckLocation(sessionSize))
return false; return false;
} }
// 2. check overlapping of partitions and location of PTSs // 2. check overlapping of partitions and location of PTSs
@@ -1,9 +1,6 @@
/* /*
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved. * Copyright 2003-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold, bonefish@cs.tu-berlin.de
*/ */
/*! /*!
@@ -29,6 +26,9 @@
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition" #define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
#define BFS_NAME "BFS Filesystem" #define BFS_NAME "BFS Filesystem"
enum {
SECTOR_SIZE = 512
};
// is_empty_type // is_empty_type
static inline bool static inline bool
@@ -123,10 +123,10 @@ class Partition {
public: public:
Partition(); Partition();
Partition(const partition_descriptor *descriptor, off_t ptsOffset, Partition(const partition_descriptor *descriptor, off_t ptsOffset,
off_t baseOffset, int32 blockSize); off_t baseOffset);
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, void SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
off_t baseOffset, int32 blockSize); off_t baseOffset);
void Unset(); void Unset();
bool IsEmpty() const { return is_empty_type(fType); } bool IsEmpty() const { return is_empty_type(fType); }
@@ -140,7 +140,7 @@ public:
void GetTypeString(char *buffer) const void GetTypeString(char *buffer) const
{ get_partition_type_string(fType, buffer); } { get_partition_type_string(fType, buffer); }
void GetPartitionDescriptor(partition_descriptor *descriptor, void GetPartitionDescriptor(partition_descriptor *descriptor,
off_t baseOffset, int32 blockSize) const; off_t baseOffset) const;
void SetPTSOffset(off_t offset) { fPTSOffset = offset; } void SetPTSOffset(off_t offset) { fPTSOffset = offset; }
void SetOffset(off_t offset) { fOffset = offset; } void SetOffset(off_t offset) { fOffset = offset; }
@@ -148,7 +148,7 @@ public:
void SetType(uint8 type) { fType = type; } void SetType(uint8 type) { fType = type; }
void SetActive(bool active) { fActive = active; } void SetActive(bool active) { fActive = active; }
bool CheckLocation(off_t sessionSize, int32 blockSize) const; bool CheckLocation(off_t sessionSize) const;
#ifdef _BOOT_MODE #ifdef _BOOT_MODE
void AdjustSize(off_t sessionSize); void AdjustSize(off_t sessionSize);
#endif #endif
@@ -165,11 +165,9 @@ private:
class PrimaryPartition : public Partition { class PrimaryPartition : public Partition {
public: public:
PrimaryPartition(); PrimaryPartition();
PrimaryPartition(const partition_descriptor *descriptor, off_t ptsOffset, PrimaryPartition(const partition_descriptor *descriptor, off_t ptsOffset);
int32 blockSize);
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, void SetTo(const partition_descriptor *descriptor, off_t ptsOffset);
int32 blockSize);
void Unset(); void Unset();
// only if extended // only if extended
@@ -189,10 +187,10 @@ class LogicalPartition : public Partition {
public: public:
LogicalPartition(); LogicalPartition();
LogicalPartition(const partition_descriptor *descriptor, off_t ptsOffset, LogicalPartition(const partition_descriptor *descriptor, off_t ptsOffset,
int32 blockSize, PrimaryPartition *primary); PrimaryPartition *primary);
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, void SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
int32 blockSize, PrimaryPartition *primary); PrimaryPartition *primary);
void Unset(); void Unset();
void SetPrimaryPartition(PrimaryPartition *primary) { fPrimary = primary; } void SetPrimaryPartition(PrimaryPartition *primary) { fPrimary = primary; }
@@ -226,7 +224,7 @@ public:
Partition *PartitionAt(int32 index); Partition *PartitionAt(int32 index);
const Partition *PartitionAt(int32 index) const; const Partition *PartitionAt(int32 index) const;
bool Check(off_t sessionSize, int32 blockSize) const; bool Check(off_t sessionSize) const;
private: private:
PrimaryPartition fPrimaries[4]; PrimaryPartition fPrimaries[4];
@@ -38,11 +38,10 @@ static const int32 kMaxLogicalPartitionCount = 128;
// constructor // constructor
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset, PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
off_t sessionSize, int32 blockSize) off_t sessionSize)
: fDeviceFD(deviceFD), : fDeviceFD(deviceFD),
fSessionOffset(sessionOffset), fSessionOffset(sessionOffset),
fSessionSize(sessionSize), fSessionSize(sessionSize),
fBlockSize(blockSize),
fPTS(NULL), fPTS(NULL),
fMap(NULL) fMap(NULL)
{ {
@@ -72,13 +71,9 @@ PartitionMapParser::Parse(const uint8 *block, PartitionMap *map)
error = _ParsePrimary(&pts); error = _ParsePrimary(&pts);
} }
// If we don't have any partitions it might also just be an if (error == B_OK && !fMap->Check(fSessionSize))
// empty partition map, but we still can't do much with it
if (error == B_OK
&& (fMap->CountNonEmptyPartitions() == 0
|| !fMap->Check(fSessionSize, fBlockSize))) {
error = B_BAD_DATA; error = B_BAD_DATA;
}
fMap = NULL; fMap = NULL;
} }
return error; return error;
@@ -101,14 +96,14 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
for (int32 i = 0; i < 4; i++) { for (int32 i = 0; i < 4; i++) {
const partition_descriptor *descriptor = &pts->table[i]; const partition_descriptor *descriptor = &pts->table[i];
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i); PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
partition->SetTo(descriptor, 0, fBlockSize); partition->SetTo(descriptor, 0);
#ifdef _BOOT_MODE #ifdef _BOOT_MODE
// work-around potential BIOS problems // work-around potential BIOS problems
partition->AdjustSize(fSessionSize); partition->AdjustSize(fSessionSize);
#endif #endif
// ignore, if location is bad // ignore, if location is bad
if (!partition->CheckLocation(fSessionSize, fBlockSize)) { if (!partition->CheckLocation(fSessionSize)) {
TRACE(("intel: _ParsePrimary(): partition %ld: bad location, " TRACE(("intel: _ParsePrimary(): partition %ld: bad location, "
"ignoring\n", i)); "ignoring\n", i));
partition->Unset(); partition->Unset();
@@ -177,8 +172,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
if (!descriptor->is_empty()) { if (!descriptor->is_empty()) {
if (descriptor->is_extended()) { if (descriptor->is_extended()) {
if (extended.IsEmpty()) { if (extended.IsEmpty()) {
extended.SetTo(descriptor, offset, fBlockSize, extended.SetTo(descriptor, offset, primary);
primary);
partition = &extended; partition = &extended;
} else { } else {
// only one extended partition allowed // only one extended partition allowed
@@ -188,8 +182,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
} }
} else { } else {
if (nonExtended.IsEmpty()) { if (nonExtended.IsEmpty()) {
nonExtended.SetTo(descriptor, offset, fBlockSize, nonExtended.SetTo(descriptor, offset, primary);
primary);
partition = &nonExtended; partition = &nonExtended;
} else { } else {
// only one non-extended partition allowed // only one non-extended partition allowed
@@ -204,8 +197,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
partition->AdjustSize(fSessionSize); partition->AdjustSize(fSessionSize);
#endif #endif
// check the partition's location // check the partition's location
if (partition && !partition->CheckLocation(fSessionSize, if (partition && !partition->CheckLocation(fSessionSize)) {
fBlockSize)) {
error = B_BAD_DATA; error = B_BAD_DATA;
TRACE(("intel: _ParseExtended(): Invalid partition " TRACE(("intel: _ParseExtended(): Invalid partition "
"location: pts: %lld, offset: %lld, size: %lld\n", "location: pts: %lld, offset: %lld, size: %lld\n",
@@ -28,8 +28,8 @@ struct partition_table_sector;
class PartitionMapParser { class PartitionMapParser {
public: public:
PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize, PartitionMapParser(int deviceFD, off_t sessionOffset,
int32 blockSize); off_t sessionSize);
~PartitionMapParser(); ~PartitionMapParser();
status_t Parse(const uint8 *block, PartitionMap *map); status_t Parse(const uint8 *block, PartitionMap *map);
@@ -46,7 +46,6 @@ class PartitionMapParser {
int fDeviceFD; int fDeviceFD;
off_t fSessionOffset; off_t fSessionOffset;
off_t fSessionSize; off_t fSessionSize;
int32 fBlockSize;
partition_table_sector *fPTS; // while parsing partition_table_sector *fPTS; // while parsing
PartitionMap *fMap; PartitionMap *fMap;
}; };
@@ -39,14 +39,12 @@ using std::nothrow;
\param deviceFD File descriptor. \param deviceFD File descriptor.
\param sessionOffset Disk offset of the partition with partitioning system. \param sessionOffset Disk offset of the partition with partitioning system.
\param sessionSize Size of the partition with partitioning system. \param sessionSize Size of the partition with partitioning system.
\param blockSize Size of the sector on given disk.
*/ */
PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset, PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset,
off_t sessionSize, int32 blockSize) off_t sessionSize)
: fDeviceFD(deviceFD), : fDeviceFD(deviceFD),
fSessionOffset(sessionOffset), fSessionOffset(sessionOffset),
fSessionSize(sessionSize), fSessionSize(sessionSize),
fBlockSize(blockSize),
fPTS(NULL), fPTS(NULL),
fMap(NULL) fMap(NULL)
{ {
@@ -64,33 +62,43 @@ PartitionMapWriter::~PartitionMapWriter()
If a \a block is not specified, the sector is firstly read from the disk If a \a block is not specified, the sector is firstly read from the disk
and after changing relevant items it is written back to the disk. and after changing relevant items it is written back to the disk.
This allows to keep code area in MBR intact. This allows to keep code area in MBR intact.
\param block Pointer to \c partition_table_sector. \param pts Pointer to \c partition_table_sector.
\param map Pointer to the PartitionMap structure describing disk partitions. \param map Pointer to the PartitionMap structure describing disk partitions.
*/ */
status_t status_t
PartitionMapWriter::WriteMBR(uint8 *block, const PartitionMap *map) PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
{ {
status_t error = (map ? B_OK : B_BAD_VALUE); if (!map)
if (error == B_OK) { return B_BAD_VALUE;
fMap = map;
if (block) {
partition_table_sector *pts
= (partition_table_sector*)block;
error = _WritePrimary(pts);
if (error == B_OK)
error = _WritePTS(0, pts);
} else {
partition_table_sector pts;
error = _ReadPTS(0, &pts);
if (error == B_OK) {
error = _WritePrimary(&pts);
if (error == B_OK)
error = _WritePTS(0, &pts);
}
}
fMap = NULL; fMap = map;
uint8 sector[SECTOR_SIZE];
partition_table_sector* pts = (partition_table_sector*)sector;
// If we shall not clear the first two sectors, we need to read the first
// sector in, first.
status_t error = B_OK;
if (clearSectors)
memset(sector, 0, SECTOR_SIZE);
else
error = _ReadPTS(0, pts);
if (error == B_OK) {
error = _WritePrimary(pts);
if (error == B_OK)
error = _WriteSector(0, sector);
} }
// Clear the second sector, if desired. We do that to make the partition
// unrecognizable by BFS.
if (error == B_OK && clearSectors) {
memset(sector, 0, SECTOR_SIZE);
error = _WriteSector(SECTOR_SIZE, sector);
}
fMap = NULL;
return error; return error;
} }
@@ -104,28 +112,27 @@ PartitionMapWriter::WriteMBR(uint8 *block, const PartitionMap *map)
previous logical partitions (call this function on previous logical previous logical partitions (call this function on previous logical
partition to ensure it). partition to ensure it).
\param block Pointer to \c partition_table_sector. \param pts Pointer to \c partition_table_sector.
\param partition Pointer to the logical partition. \param partition Pointer to the logical partition.
*/ */
status_t status_t
PartitionMapWriter::WriteLogical(uint8 *block, PartitionMapWriter::WriteLogical(partition_table_sector *pts,
const LogicalPartition *partition) const LogicalPartition *partition)
{ {
status_t error = (partition ? B_OK : B_BAD_VALUE); status_t error = (partition ? B_OK : B_BAD_VALUE);
if (error == B_OK) { if (error == B_OK) {
if (block) { if (pts) {
partition_table_sector *pts
= (partition_table_sector*)block;
error = _WriteExtended(pts, partition, partition->Next()); error = _WriteExtended(pts, partition, partition->Next());
if (error == B_OK) if (error == B_OK)
error = _WritePTS(partition->PTSOffset(), pts); error = _WriteSector(partition->PTSOffset(), pts);
} else { } else {
partition_table_sector pts; partition_table_sector _pts;
error = _ReadPTS(partition->PTSOffset(), &pts); pts = &_pts;
error = _ReadPTS(partition->PTSOffset(), pts);
if (error == B_OK) { if (error == B_OK) {
error = _WriteExtended(&pts, partition, partition->Next()); error = _WriteExtended(pts, partition, partition->Next());
if (error == B_OK) if (error == B_OK)
error = _WritePTS(partition->PTSOffset(), &pts); error = _WriteSector(partition->PTSOffset(), pts);
} }
} }
} }
@@ -142,30 +149,29 @@ PartitionMapWriter::WriteLogical(uint8 *block,
If the \a first_partition is not specified, it only initializes EBR and the If the \a first_partition is not specified, it only initializes EBR and the
linked list contains no logical partitions. linked list contains no logical partitions.
\param block Pointer to \c partition_table_sector. \param pts Pointer to \c partition_table_sector.
\param first_partition Pointer to the first logical partition. \param first_partition Pointer to the first logical partition.
*/ */
status_t status_t
PartitionMapWriter::WriteExtendedHead(uint8 *block, PartitionMapWriter::WriteExtendedHead(partition_table_sector *pts,
const LogicalPartition *first_partition) const LogicalPartition *first_partition)
{ {
LogicalPartition partition; LogicalPartition partition;
if (first_partition) if (first_partition)
partition.SetPrimaryPartition(first_partition->GetPrimaryPartition()); partition.SetPrimaryPartition(first_partition->GetPrimaryPartition());
status_t error = B_OK; status_t error = B_OK;
if (block) { if (pts) {
partition_table_sector *pts
= (partition_table_sector*)block;
error = _WriteExtended(pts, &partition, first_partition); error = _WriteExtended(pts, &partition, first_partition);
if (error == B_OK) if (error == B_OK)
error = _WritePTS(0, pts); error = _WriteSector(0, pts);
} else { } else {
partition_table_sector pts; partition_table_sector _pts;
error = _ReadPTS(0, &pts); pts = &_pts;
error = _ReadPTS(0, pts);
if (error == B_OK) { if (error == B_OK) {
error = _WriteExtended(&pts, &partition, first_partition); error = _WriteExtended(pts, &partition, first_partition);
if (error == B_OK) if (error == B_OK)
error = _WritePTS(0, &pts); error = _WriteSector(0, pts);
} }
} }
return error; return error;
@@ -187,13 +193,13 @@ PartitionMapWriter::_WritePrimary(partition_table_sector *pts)
const PrimaryPartition *partition = fMap->PrimaryPartitionAt(i); const PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
// ignore, if location is bad // ignore, if location is bad
if (!partition->CheckLocation(fSessionSize, fBlockSize)) { if (!partition->CheckLocation(fSessionSize)) {
TRACE(("intel: _WritePrimary(): partition %ld: bad location, " TRACE(("intel: _WritePrimary(): partition %ld: bad location, "
"ignoring\n", i)); "ignoring\n", i));
return B_BAD_DATA; return B_BAD_DATA;
} }
partition->GetPartitionDescriptor(descriptor, 0, fBlockSize); partition->GetPartitionDescriptor(descriptor, 0);
} }
return B_OK; return B_OK;
@@ -211,7 +217,7 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
pts->signature = kPartitionTableSectorSignature; pts->signature = kPartitionTableSectorSignature;
// check the partition's location // check the partition's location
if (!partition->CheckLocation(fSessionSize, fBlockSize)) { if (!partition->CheckLocation(fSessionSize)) {
TRACE(("intel: _WriteExtended(): Invalid partition " TRACE(("intel: _WriteExtended(): Invalid partition "
"location: pts: %lld, offset: %lld, size: %lld, " "location: pts: %lld, offset: %lld, size: %lld, "
"fSessionSize: %lld\n", "fSessionSize: %lld\n",
@@ -222,8 +228,7 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
// write the table // write the table
partition_descriptor *descriptor = &(pts->table[0]); partition_descriptor *descriptor = &(pts->table[0]);
partition->GetPartitionDescriptor(descriptor, partition->PTSOffset(), partition->GetPartitionDescriptor(descriptor, partition->PTSOffset());
fBlockSize);
// setting offset and size of the next partition in the linked list // setting offset and size of the next partition in the linked list
descriptor = &(pts->table[1]); descriptor = &(pts->table[1]);
@@ -233,15 +238,15 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
extended.SetOffset(next->PTSOffset()); extended.SetOffset(next->PTSOffset());
extended.SetSize(next->Size() + next->Offset() - next->PTSOffset()); extended.SetSize(next->Size() + next->Offset() - next->PTSOffset());
extended.SetType(partition->GetPrimaryPartition()->Type()); extended.SetType(partition->GetPrimaryPartition()->Type());
extended.GetPartitionDescriptor(descriptor, 0, fBlockSize); extended.GetPartitionDescriptor(descriptor, 0);
extended.Unset(); extended.Unset();
} else } else
extended.GetPartitionDescriptor(descriptor, 0, fBlockSize); extended.GetPartitionDescriptor(descriptor, 0);
// last two descriptors are empty // last two descriptors are empty
for (int32 i = 2; i < 4; i++) { for (int32 i = 2; i < 4; i++) {
descriptor = &(pts->table[i]); descriptor = &(pts->table[i]);
extended.GetPartitionDescriptor(descriptor, 0, fBlockSize); extended.GetPartitionDescriptor(descriptor, 0);
} }
return B_OK; return B_OK;
@@ -276,31 +281,28 @@ PartitionMapWriter::_ReadPTS(off_t offset, partition_table_sector *pts)
return error; return error;
} }
// _WritePTS // _WriteSector
/*! \brief Writes the sector to the disk. /*! \brief Writes the sector to the disk.
*/ */
status_t status_t
PartitionMapWriter::_WritePTS(off_t offset, const partition_table_sector *pts) PartitionMapWriter::_WriteSector(off_t offset, const void* pts)
{ {
status_t error = B_OK; status_t error = B_OK;
if (!pts)
pts = fPTS; int32 toWrite = SECTOR_SIZE;
int32 toWrite = sizeof(partition_table_sector);
// check the offset // check the offset
if (offset < 0 || offset + toWrite > fSessionSize) { if (offset < 0 || offset + toWrite > fSessionSize) {
error = B_BAD_VALUE; error = B_BAD_VALUE;
TRACE(("intel: _WritePTS(): bad offset: %Ld\n", offset)); TRACE(("intel: _WriteSector(): bad offset: %Ld\n", offset));
// write // write
} else if (write_pos(fDeviceFD, fSessionOffset + offset, pts, toWrite) } else if (write_pos(fDeviceFD, fSessionOffset + offset, pts, toWrite)
!= toWrite) { != toWrite) {
#ifndef _BOOT_MODE
error = errno; error = errno;
if (error == B_OK) if (error == B_OK)
error = B_IO_ERROR; error = B_IO_ERROR;
#else
error = B_IO_ERROR; TRACE(("intel: _WriteSector(): writing the PTS failed: %lx\n", error));
#endif
TRACE(("intel: _WritePTS(): writing the PTS failed: %lx\n", error));
} }
return error; return error;
} }
@@ -35,13 +35,13 @@ struct partition_table_sector;
*/ */
class PartitionMapWriter { class PartitionMapWriter {
public: public:
PartitionMapWriter(int deviceFD, off_t sessionOffset, off_t sessionSize, PartitionMapWriter(int deviceFD, off_t sessionOffset, off_t sessionSize);
int32 blockSize);
~PartitionMapWriter(); ~PartitionMapWriter();
status_t WriteMBR(uint8 *block, const PartitionMap *map); status_t WriteMBR(const PartitionMap *map, bool clearSectors);
status_t WriteLogical(uint8 *block, const LogicalPartition *partition); status_t WriteLogical(partition_table_sector *pts,
status_t WriteExtendedHead(uint8 *block, const LogicalPartition *partition);
status_t WriteExtendedHead(partition_table_sector *pts,
const LogicalPartition *first_partition); const LogicalPartition *first_partition);
private: private:
@@ -49,13 +49,12 @@ private:
status_t _WriteExtended(partition_table_sector *pts, status_t _WriteExtended(partition_table_sector *pts,
const LogicalPartition *partition, const LogicalPartition *next); const LogicalPartition *partition, const LogicalPartition *next);
status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL); status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL);
status_t _WritePTS(off_t offset, const partition_table_sector *pts = NULL); status_t _WriteSector(off_t offset, const void* pts = NULL);
private: private:
int fDeviceFD; int fDeviceFD;
off_t fSessionOffset; off_t fSessionOffset;
off_t fSessionSize; off_t fSessionSize;
int32 fBlockSize;
partition_table_sector *fPTS; // while writing partition_table_sector *fPTS; // while writing
const PartitionMap *fMap; const PartitionMap *fMap;
}; };
@@ -127,14 +127,6 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
return -1; return -1;
} }
// check block size
uint32 blockSize = partition->block_size;
if (blockSize < sizeof(partition_table_sector)) {
TRACE(("intel: read_partition_map: bad block size: %ld, should be "
">= %ld\n", blockSize, sizeof(partition_table_sector)));
return -1;
}
// allocate a PartitionMap // allocate a PartitionMap
PartitionMapCookie *map = new(nothrow) PartitionMapCookie; PartitionMapCookie *map = new(nothrow) PartitionMapCookie;
if (!map) if (!map)
@@ -142,16 +134,40 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
map->ref_count = 1; map->ref_count = 1;
// read the partition structure // read the partition structure
PartitionMapParser parser(fd, 0, partition->size, blockSize); PartitionMapParser parser(fd, 0, partition->size);
status_t error = parser.Parse(NULL, map); status_t error = parser.Parse(NULL, map);
if (error == B_OK) { if (error != B_OK) {
*cookie = map; // cleanup, if not detected
delete map;
return -1;
}
*cookie = map;
// Depending on whether we actually have recognized child partitions and
// whether we are installed directly on a device (the by far most common
// setup), we determine the priority.
bool hasChildren = (map->CountNonEmptyPartitions() > 0);
bool hasParent = (get_parent_partition(partition->id) != NULL);
if (!hasParent) {
if (hasChildren) {
// This value overrides BFS.
return 0.81;
}
// No children -- might be a freshly initialized disk. But it could
// also be an image file. So we give BFS a chance to override us.
return 0.5; return 0.5;
} }
// cleanup, if not detected // We have a parent. That's a very unlikely setup.
delete map; if (hasChildren)
return -1; return 0.4;
// No children. Extremely unlikely, that this is a desired. But if no one
// else claims the partition, we take it anyway.
return 0.1;
} }
// pm_scan_partition // pm_scan_partition
@@ -173,6 +189,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
partition->content_size = partition->size; partition->content_size = partition->size;
// (no content_name and content_parameters) // (no content_name and content_parameters)
// (content_type is set by the system) // (content_type is set by the system)
partition->block_size = SECTOR_SIZE;
partition->content_cookie = map; partition->content_cookie = map;
// children // children
@@ -192,7 +209,7 @@ pm_scan_partition(int fd, partition_data *partition, void *cookie)
child->offset = partition->offset + primary->Offset(); child->offset = partition->offset + primary->Offset();
child->size = primary->Size(); child->size = primary->Size();
child->block_size = partition->block_size; child->block_size = SECTOR_SIZE;
// (no name) // (no name)
char type[B_FILE_NAME_LENGTH]; char type[B_FILE_NAME_LENGTH];
primary->GetTypeString(type); primary->GetTypeString(type);
@@ -320,6 +337,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
partition->content_size = partition->size; partition->content_size = partition->size;
// (no content_name and content_parameters) // (no content_name and content_parameters)
// (content_type is set by the system) // (content_type is set by the system)
partition->block_size = SECTOR_SIZE;
partition->content_cookie = primary; partition->content_cookie = primary;
// children // children
@@ -339,7 +357,7 @@ ep_scan_partition(int fd, partition_data *partition, void *cookie)
} }
child->offset = parent->offset + logical->Offset(); child->offset = parent->offset + logical->Offset();
child->size = logical->Size(); child->size = logical->Size();
child->block_size = partition->block_size; child->block_size = SECTOR_SIZE;
// (no name) // (no name)
char type[B_FILE_NAME_LENGTH]; char type[B_FILE_NAME_LENGTH];
logical->GetTypeString(type); logical->GetTypeString(type);
@@ -110,20 +110,20 @@ pm_is_sub_system_for(partition_data *partition)
// #pragma mark - Intel Partition Map - validate functions // #pragma mark - Intel Partition Map - validate functions
// block_align (auxiliary function) // sector_align (auxiliary function)
static inline static inline
off_t off_t
block_align(off_t offset, uint32 block_size) sector_align(off_t offset)
{ {
return offset / block_size * block_size; return offset / SECTOR_SIZE * SECTOR_SIZE;
} }
// block_align_up (auxiliary function) // sector_align_up (auxiliary function)
static inline static inline
off_t off_t
block_align_up(off_t offset, uint32 block_size) sector_align_up(off_t offset)
{ {
return (offset + block_size - 1) / block_size * block_size; return (offset + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE;
} }
// validate_resize (auxiliary function) // validate_resize (auxiliary function)
@@ -138,7 +138,7 @@ validate_resize(partition_data *partition, off_t *size)
if (new_size < 0) if (new_size < 0)
new_size = 0; new_size = 0;
else else
new_size = block_align(new_size, partition->block_size); new_size = sector_align(new_size);
// grow partition? // grow partition?
if (new_size > partition->size) { if (new_size > partition->size) {
@@ -157,7 +157,7 @@ validate_resize(partition_data *partition, off_t *size)
} }
new_size = current_end - partition->offset; new_size = current_end - partition->offset;
// make the size a multiple of the block size (greater one) // make the size a multiple of the block size (greater one)
new_size = block_align_up(new_size, partition->block_size); new_size = sector_align_up(new_size);
*size = new_size; *size = new_size;
return true; return true;
} }
@@ -285,7 +285,7 @@ validate_resize_child(partition_data *partition, partition_data *child,
if (*size < 0) if (*size < 0)
*size = 0; *size = 0;
// make the size a multiple of the block size // make the size a multiple of the block size
*size = block_align(*size, partition->block_size); *size = sector_align(*size);
return true; return true;
} }
// grow partition // grow partition
@@ -304,7 +304,7 @@ validate_resize_child(partition_data *partition, partition_data *child,
if (nextSibling && (nextOffset < childOffset + *size)) if (nextSibling && (nextOffset < childOffset + *size))
*size = nextOffset - childOffset; *size = nextOffset - childOffset;
*size = block_align(*size, partition->block_size); *size = sector_align(*size);
return true; return true;
} }
@@ -347,7 +347,7 @@ validate_move_child(partition_data *partition, partition_data *child,
else if (start + childSize > partition->size) else if (start + childSize > partition->size)
start = partition->size - childSize; start = partition->size - childSize;
start = block_align(start, partition->block_size); start = sector_align(start);
// finding out sibling partitions // finding out sibling partitions
partition_data *previousSibling = NULL; partition_data *previousSibling = NULL;
@@ -362,13 +362,13 @@ validate_move_child(partition_data *partition, partition_data *child,
// moving left // moving left
if (previousSibling && previousOffset + previousSize > start) { if (previousSibling && previousOffset + previousSize > start) {
start = previousOffset + previousSize; start = previousOffset + previousSize;
start = block_align_up(start, partition->block_size); start = sector_align_up(start);
} }
} else { } else {
// moving right // moving right
if (nextSibling && nextOffset < start + childSize) { if (nextSibling && nextOffset < start + childSize) {
start = nextOffset - childSize; start = nextOffset - childSize;
start = block_align(start, partition->block_size); start = sector_align(start);
} }
} }
*_start = start; *_start = start;
@@ -453,9 +453,13 @@ pm_validate_initialize(partition_data *partition, char *name,
& B_DISK_SYSTEM_SUPPORTS_INITIALIZING)) { & B_DISK_SYSTEM_SUPPORTS_INITIALIZING)) {
return false; return false;
} }
// name is ignored - we cannot set it to the intel partitioning map
// TODO: check parameters - don't know whether any parameters could be set // name is ignored
// to the intel partition map if (name)
name[0] = '\0';
// parameters are ignored, too
return true; return true;
} }
@@ -465,11 +469,11 @@ validate_create_child_partition(partition_data *partition, off_t *start,
off_t *size, fc_get_sibling_partitions getSiblingPartitions) off_t *size, fc_get_sibling_partitions getSiblingPartitions)
{ {
// make the start and size a multiple of the block size // make the start and size a multiple of the block size
*start = block_align(*start, partition->block_size); *start = sector_align(*start);
if (*size < 0) if (*size < 0)
*size = 0; *size = 0;
else else
*size = block_align(*size, partition->block_size); *size = sector_align(*size);
// child must completely lie within the parent partition // child must completely lie within the parent partition
if (*start >= partition->offset + partition->size) if (*start >= partition->offset + partition->size)
@@ -489,12 +493,12 @@ validate_create_child_partition(partition_data *partition, off_t *start,
// position check of the new partition // position check of the new partition
if (previousSibling && (previousOffset + previousSize > *start)) { if (previousSibling && (previousOffset + previousSize > *start)) {
*start = previousOffset + previousSize; *start = previousOffset + previousSize;
*start = block_align_up(*start, partition->block_size); *start = sector_align_up(*start);
} }
if (nextSibling && (nextOffset < *start + *size)) if (nextSibling && (nextOffset < *start + *size))
*size = nextOffset - *start; *size = nextOffset - *start;
*size = block_align(*size, partition->block_size); *size = sector_align(*size);
if (*size == 0) if (*size == 0)
return false; return false;
@@ -540,9 +544,9 @@ pm_validate_create_child(partition_data *partition, off_t *start, off_t *size,
return false; return false;
*index = newIndex; *index = newIndex;
if (*start < partition->offset + MBR_OFFSET * partition->block_size) { if (*start < partition->offset + MBR_OFFSET * SECTOR_SIZE) {
*start = partition->offset + MBR_OFFSET * partition->block_size; *start = partition->offset + MBR_OFFSET * SECTOR_SIZE;
*start = block_align_up(*start, partition->block_size); *start = sector_align_up(*start);
} }
return validate_create_child_partition(partition, start, size, return validate_create_child_partition(partition, start, size,
@@ -626,12 +630,12 @@ get_partitionable_spaces(partition_data *partition,
int32 actualCount = 0; int32 actualCount = 0;
// offset alignment (to upper bound) // offset alignment (to upper bound)
offset = block_align_up(offset, partition->block_size); offset = sector_align_up(offset);
// finding out all partitionable spaces // finding out all partitionable spaces
for (int32 i = 0; i < partition_count; i++) { for (int32 i = 0; i < partition_count; i++) {
size = positions[i].offset - offset; size = positions[i].offset - offset;
size = block_align(size, partition->block_size); size = sector_align(size);
if (size > limitSize) { if (size > limitSize) {
if (actualCount < count) { if (actualCount < count) {
buffer[actualCount].offset = offset; buffer[actualCount].offset = offset;
@@ -640,11 +644,11 @@ get_partitionable_spaces(partition_data *partition,
actualCount++; actualCount++;
} }
offset = positions[i].offset + positions[i].size + headerSize; offset = positions[i].offset + positions[i].size + headerSize;
offset = block_align_up(offset, partition->block_size); offset = sector_align_up(offset);
} }
// space in the end of partition // space in the end of partition
size = partition->offset + partition->size - offset; size = partition->offset + partition->size - offset;
size = block_align(size, partition->block_size); size = sector_align(size);
if (size > 0) { if (size > 0) {
if (actualCount < count) { if (actualCount < count) {
buffer[actualCount].offset = offset; buffer[actualCount].offset = offset;
@@ -678,7 +682,7 @@ pm_get_partitionable_spaces(partition_data *partition,
return B_BAD_VALUE; return B_BAD_VALUE;
return get_partitionable_spaces(partition, buffer, count, actualCount, return get_partitionable_spaces(partition, buffer, count, actualCount,
fill_partitionable_spaces_buffer_pm, MBR_OFFSET * partition->block_size, fill_partitionable_spaces_buffer_pm, MBR_OFFSET * SECTOR_SIZE,
0, 0); 0, 0);
} }
@@ -809,8 +813,8 @@ pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
primary->SetSize(validatedSize); primary->SetSize(validatedSize);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); PartitionMapWriter writer(fd, 0, partition->size);
status_t error = writer.WriteMBR(NULL, map); status_t error = writer.WriteMBR(map, false);
if (error != B_OK) { if (error != B_OK) {
// putting into previous state // putting into previous state
primary->SetSize(child->size); primary->SetSize(child->size);
@@ -959,7 +963,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
// buffer allocation // buffer allocation
int32 allocated; int32 allocated;
uint8 *buffer = allocate_buffer(partition->block_size, MAX_MOVE_BUFFER, uint8 *buffer = allocate_buffer(SECTOR_SIZE, MAX_MOVE_BUFFER,
&allocated); &allocated);
if (!buffer) if (!buffer)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -969,7 +973,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
update_disk_device_job_progress(job, 0.0); update_disk_device_job_progress(job, 0.0);
status_t error = B_OK; status_t error = B_OK;
error = move_partition(fd, child->offset, validatedOffset, child->size, error = move_partition(fd, child->offset, validatedOffset, child->size,
buffer, allocated * partition->block_size, job); buffer, allocated * SECTOR_SIZE, job);
delete[] buffer; delete[] buffer;
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -979,8 +983,8 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
child->offset = validatedOffset; child->offset = validatedOffset;
primary->SetOffset(validatedOffset); primary->SetOffset(validatedOffset);
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); PartitionMapWriter writer(fd, 0, partition->size);
error = writer.WriteMBR(NULL, map); error = writer.WriteMBR(map, false);
if (error != B_OK) if (error != B_OK)
// something went wrong - this is fatal (partition has been moved) // something went wrong - this is fatal (partition has been moved)
// but MBR is not updated // but MBR is not updated
@@ -1036,8 +1040,8 @@ pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
primary->SetType(ptype.Type()); primary->SetType(ptype.Type());
// TODO: The partition is not supposed to be locked at this point! // TODO: The partition is not supposed to be locked at this point!
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); PartitionMapWriter writer(fd, 0, partition->size);
status_t error = writer.WriteMBR(NULL, map); status_t error = writer.WriteMBR(map, false);
if (error != B_OK) { if (error != B_OK) {
// something went wrong - putting into previous state // something went wrong - putting into previous state
primary->SetType(oldType); primary->SetType(oldType);
@@ -1059,61 +1063,33 @@ pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
// pm_initialize // pm_initialize
status_t status_t
pm_initialize(int fd, partition_id partitionID, const char *name, pm_initialize(int fd, partition_id partitionID, const char *name,
const char *parameters, disk_job_id job) const char *parameters, off_t partitionSize, disk_job_id job)
{ {
TRACE(("intel: pm_initialize\n")); TRACE(("intel: pm_initialize\n"));
if (fd < 0) if (fd < 0)
return B_ERROR; return B_ERROR;
PartitionWriteLocker locker(partitionID);
if (!locker.IsLocked())
return B_ERROR;
// get partition and partition map structure
partition_data *partition = get_partition(partitionID);
if (!partition)
return B_BAD_VALUE;
// name is ignored - we cannot set it to the intel partitioning map
// TODO: The parameter has already been checked and must not be altered!
if (!pm_validate_initialize(partition, NULL, parameters))
return B_BAD_VALUE;
// partition init
update_disk_device_job_progress(job, 0.0); update_disk_device_job_progress(job, 0.0);
// allocate a PartitionMap
PartitionMapCookie *map = new(nothrow) PartitionMapCookie;
if (!map)
return B_NO_MEMORY;
map->ref_count = 1;
// fill in the partition_data structure
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM;
partition->content_size = partition->size;
// (no content_name and content_parameters)
// (content_type is set by the system)
partition->content_cookie = map;
for (int32 i = 0; i < 4; i++) { // we will write an empty partition map
PrimaryPartition *primary = map->PrimaryPartitionAt(i); PartitionMap map;
primary->Unset();
}
// we delete code area in MBR, if there is any
// TODO: Huh?!
partition_table_sector pts;
pts.clear_code_area();
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); // write the sector to disk
// TODO: The partition is not supposed to be locked at this point! PartitionMapWriter writer(fd, 0, partitionSize);
status_t error = writer.WriteMBR((uint8*)&pts, map); status_t error = writer.WriteMBR(&map, true);
if (error != B_OK)
return error;
// rescan partition
error = scan_partition(partitionID);
if (error != B_OK) if (error != B_OK)
return error; return error;
// all changes applied // all changes applied
update_disk_device_job_progress(job, 1.0); update_disk_device_job_progress(job, 1.0);
partition_modified(partitionID); partition_modified(partitionID);
return B_OK; return B_OK;
} }
@@ -1177,9 +1153,9 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
primary->SetActive(false); primary->SetActive(false);
// write changes to disk // write changes to disk
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); PartitionMapWriter writer(fd, 0, partition->size);
// TODO: The partition is not supposed to be locked at this point! // TODO: The partition is not supposed to be locked at this point!
status_t error = writer.WriteMBR(NULL, map); status_t error = writer.WriteMBR(map, false);
if (error != B_OK) { if (error != B_OK) {
// putting into previous state // putting into previous state
primary->Unset(); primary->Unset();
@@ -1191,7 +1167,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
child->offset = partition->offset + primary->Offset(); child->offset = partition->offset + primary->Offset();
child->size = primary->Size(); child->size = primary->Size();
child->block_size = partition->block_size; child->block_size = SECTOR_SIZE;
// (no name) // (no name)
child->type = strdup(type); child->type = strdup(type);
// parameters // parameters
@@ -1238,9 +1214,9 @@ pm_delete_child(int fd, partition_id partitionID, partition_id childID,
primary->Unset(); primary->Unset();
// write changes to disk // write changes to disk
PartitionMapWriter writer(fd, 0, partition->size, partition->block_size); PartitionMapWriter writer(fd, 0, partition->size);
// TODO: The partition is not supposed to be locked at this point! // TODO: The partition is not supposed to be locked at this point!
status_t error = writer.WriteMBR(NULL, map); status_t error = writer.WriteMBR(map, false);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1442,12 +1418,12 @@ ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
*index = partition->child_count; *index = partition->child_count;
// validate position // validate position
off_t diffOffset = PTS_OFFSET * partition->block_size; off_t diffOffset = PTS_OFFSET * SECTOR_SIZE;
off_t start = *_start - diffOffset; off_t start = *_start - diffOffset;
off_t size = *_size + diffOffset; off_t size = *_size + diffOffset;
if (start < partition->offset + PTS_OFFSET * partition->block_size) { if (start < partition->offset + PTS_OFFSET * SECTOR_SIZE) {
start = partition->offset + PTS_OFFSET * partition->block_size; start = partition->offset + PTS_OFFSET * SECTOR_SIZE;
start = block_align_up(start, partition->block_size); start = sector_align_up(start);
} }
if (!validate_create_child_partition(partition, &start, &size, if (!validate_create_child_partition(partition, &start, &size,
get_sibling_partitions_ep)) { get_sibling_partitions_ep)) {
@@ -1477,9 +1453,9 @@ ep_get_partitionable_spaces(partition_data *partition,
return get_partitionable_spaces(partition, buffer, count, actualCount, return get_partitionable_spaces(partition, buffer, count, actualCount,
fill_partitionable_spaces_buffer_ep, fill_partitionable_spaces_buffer_ep,
partition->offset + PTS_OFFSET * partition->block_size, partition->offset + PTS_OFFSET * SECTOR_SIZE,
PTS_OFFSET * partition->block_size, PTS_OFFSET * SECTOR_SIZE,
PTS_OFFSET * partition->block_size); PTS_OFFSET * SECTOR_SIZE);
} }
// ep_get_next_supported_type // ep_get_next_supported_type
@@ -1610,7 +1586,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
update_disk_device_job_progress(job, 0.0); update_disk_device_job_progress(job, 0.0);
logical->SetSize(validatedSize); logical->SetSize(validatedSize);
PartitionMapWriter writer(fd, partition->offset, partition->size, partition->block_size); PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(NULL, logical); status_t error = writer.WriteLogical(NULL, logical);
if (error != B_OK) { if (error != B_OK) {
@@ -1696,7 +1672,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
// buffer allocation // buffer allocation
int32 allocated; int32 allocated;
uint8 *buffer = allocate_buffer(partition->block_size, MAX_MOVE_BUFFER, &allocated); uint8 *buffer = allocate_buffer(SECTOR_SIZE, MAX_MOVE_BUFFER, &allocated);
if (!buffer) if (!buffer)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -1707,7 +1683,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
off_t pts_offset = logical->Offset() - logical->PTSOffset(); off_t pts_offset = logical->Offset() - logical->PTSOffset();
error = move_partition(fd, child->offset - pts_offset, validatedOffset - pts_offset, error = move_partition(fd, child->offset - pts_offset, validatedOffset - pts_offset,
child->size + pts_offset, buffer, child->size + pts_offset, buffer,
allocated * partition->block_size, job); allocated * SECTOR_SIZE, job);
delete[] buffer; delete[] buffer;
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1718,7 +1694,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
logical->SetOffset(logical->Offset() + diffOffset); logical->SetOffset(logical->Offset() + diffOffset);
logical->SetPTSOffset(logical->PTSOffset() + diffOffset); logical->SetPTSOffset(logical->PTSOffset() + diffOffset);
PartitionMapWriter writer(fd, partition->offset, partition->size, partition->block_size); PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
error = writer.WriteLogical(NULL, logical); error = writer.WriteLogical(NULL, logical);
if (error != B_OK) if (error != B_OK)
@@ -1779,8 +1755,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
uint8 oldType = logical->Type(); uint8 oldType = logical->Type();
logical->SetType(ptype.Type()); logical->SetType(ptype.Type());
PartitionMapWriter writer(fd, partition->offset, partition->size, PartitionMapWriter writer(fd, partition->offset, partition->size);
partition->block_size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(NULL, logical); status_t error = writer.WriteLogical(NULL, logical);
if (error != B_OK) { if (error != B_OK) {
@@ -1803,7 +1778,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
// ep_initialize // ep_initialize
status_t status_t
ep_initialize(int fd, partition_id partitionID, const char *name, ep_initialize(int fd, partition_id partitionID, const char *name,
const char *parameters, disk_job_id job) const char *parameters, off_t partitionSize, disk_job_id job)
{ {
TRACE(("intel: ep_initialize\n")); TRACE(("intel: ep_initialize\n"));
@@ -1839,9 +1814,9 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
partition_table_sector pts; partition_table_sector pts;
pts.clear_code_area(); pts.clear_code_area();
PartitionMapWriter writer(fd, partition->offset, partition->size, partition->block_size); PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteExtendedHead((uint8*)&pts, NULL); status_t error = writer.WriteExtendedHead(&pts, NULL);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1904,7 +1879,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
PartitionType ptype; PartitionType ptype;
ptype.SetType(type); ptype.SetType(type);
logical->SetPTSOffset(validatedOffset - PTS_OFFSET * partition->block_size logical->SetPTSOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
- partition->offset); - partition->offset);
logical->SetOffset(validatedOffset - partition->offset); logical->SetOffset(validatedOffset - partition->offset);
logical->SetSize(validatedSize); logical->SetSize(validatedSize);
@@ -1917,10 +1892,9 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
pts.clear_code_area(); pts.clear_code_area();
// write changes to disk // write changes to disk
PartitionMapWriter writer(fd, partition->offset, partition->size, PartitionMapWriter writer(fd, partition->offset, partition->size);
partition->block_size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical((uint8*)&pts, logical); status_t error = writer.WriteLogical(&pts, logical);
if (error != B_OK) { if (error != B_OK) {
// putting into previous state // putting into previous state
delete_partition(child->id); delete_partition(child->id);
@@ -1944,7 +1918,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
child->offset = partition->offset + logical->Offset(); child->offset = partition->offset + logical->Offset();
child->size = logical->Size(); child->size = logical->Size();
child->block_size = partition->block_size; child->block_size = SECTOR_SIZE;
// (no name) // (no name)
child->type = strdup(type); child->type = strdup(type);
// parameters // parameters
@@ -1995,7 +1969,7 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
delete logical; delete logical;
// write changes to disk // write changes to disk
PartitionMapWriter writer(fd, partition->offset, partition->size, partition->block_size); PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here! // TODO: The partition is not supposed to be locked here!
status_t error = prev_logical ? writer.WriteLogical(NULL, prev_logical) status_t error = prev_logical ? writer.WriteLogical(NULL, prev_logical)
: writer.WriteExtendedHead(NULL, next_logical); : writer.WriteExtendedHead(NULL, next_logical);
@@ -46,7 +46,7 @@ status_t pm_move_child(int fd, partition_id partitionID,
status_t pm_set_type(int fd, partition_id partitionID, const char *type, status_t pm_set_type(int fd, partition_id partitionID, const char *type,
disk_job_id job); disk_job_id job);
status_t pm_initialize(int fd, partition_id partitionID, const char *name, status_t pm_initialize(int fd, partition_id partitionID, const char *name,
const char *parameters, disk_job_id job); const char *parameters, off_t partitionSize, disk_job_id job);
status_t pm_create_child(int fd, partition_id partitionID, off_t offset, status_t pm_create_child(int fd, partition_id partitionID, off_t offset,
off_t size, const char *type, const char *parameters, off_t size, const char *type, const char *parameters,
disk_job_id job, partition_id *childID); disk_job_id job, partition_id *childID);
@@ -90,7 +90,7 @@ status_t ep_move_child(int fd, partition_id partitionID,
status_t ep_set_type(int fd, partition_id partitionID, const char *type, status_t ep_set_type(int fd, partition_id partitionID, const char *type,
disk_job_id job); disk_job_id job);
status_t ep_initialize(int fd, partition_id partitionID, const char *name, status_t ep_initialize(int fd, partition_id partitionID, const char *name,
const char *parameters, disk_job_id job); const char *parameters, off_t partitionSize, disk_job_id job);
status_t ep_create_child(int fd, partition_id partitionID, off_t offset, status_t ep_create_child(int fd, partition_id partitionID, off_t offset,
off_t size, const char *type, const char *parameters, off_t size, const char *type, const char *parameters,
disk_job_id job, partition_id *childID); disk_job_id job, partition_id *childID);
@@ -326,7 +326,7 @@ main(int argc, const char *const *argv)
* geometry.cylinders * 512; * geometry.cylinders * 512;
// parse the partition map // parse the partition map
PartitionMapParser parser(baseFD, 0, deviceSize, 512); PartitionMapParser parser(baseFD, 0, deviceSize);
PartitionMap map; PartitionMap map;
error = parser.Parse(NULL, &map); error = parser.Parse(NULL, &map);
if (error != B_OK) { if (error != B_OK) {
@@ -263,11 +263,13 @@ KFileSystem::Initialize(KPartition *partition, const char *name,
if (result != B_OK) if (result != B_OK)
return result; return result;
off_t partitionSize = partition->Size();
locker.Unlock(); locker.Unlock();
// call the module hook // call the module hook
result = fModule->initialize(fd, partition->ID(), name, parameters, result = fModule->initialize(fd, partition->ID(), name, parameters,
job->ID()); partitionSize, job->ID());
close(fd); close(fd);
return result; return result;
@@ -795,10 +795,12 @@ KPartitioningSystem::Initialize(KPartition *partition, const char *name,
// lock partition and open partition device // lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// TODO: This looks overly complicated.
KPartition *_partition = manager->WriteLockPartition(partition->ID()); KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition) if (!_partition)
return B_ERROR; return B_ERROR;
int fd = -1; int fd = -1;
off_t partitionSize;
{ {
PartitionRegistrar registrar(_partition, true); PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true); PartitionRegistrar deviceRegistrar(_partition->Device(), true);
@@ -808,12 +810,13 @@ KPartitioningSystem::Initialize(KPartition *partition, const char *name,
status_t result = partition->Open(O_RDWR, &fd); status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK) if (result != B_OK)
return result; return result;
partitionSize = partition->Size();
} }
// let the module do its job // let the module do its job
// TODO: The partition must not be locked at this point!
status_t result = fModule->initialize(fd, partition->ID(), name, parameters, status_t result = fModule->initialize(fd, partition->ID(), name, parameters,
job->ID()); partitionSize, job->ID());
// cleanup and return // cleanup and return
close(fd); close(fd);
+2 -1
View File
@@ -5200,9 +5200,10 @@ _kern_initialize_volume(const char* fsName, const char *partition,
// initialize // initialize
fssh_status_t status; fssh_status_t status;
if (fsModule->initialize) { if (fsModule->initialize) {
status = (*fsModule->initialize)(fd, -1, name, parameters, -1); status = (*fsModule->initialize)(fd, -1, name, parameters, 0, -1);
// We've got no partition or job IDs -- the FS will hopefully // We've got no partition or job IDs -- the FS will hopefully
// ignore that. // ignore that.
// TODO: Get the actual size!
} else } else
status = FSSH_B_NOT_SUPPORTED; status = FSSH_B_NOT_SUPPORTED;