Implemented disk device updating. Some changes due to syscall changes.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4050 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e627d686c3
commit
426b44c60b
@ -40,9 +40,17 @@ private:
|
||||
friend class BDiskDeviceList;
|
||||
friend class BDiskDeviceRoster;
|
||||
|
||||
BDiskDevice::BDiskDevice(const BDiskDevice &);
|
||||
BDiskDevice &BDiskDevice::operator=(const BDiskDevice &);
|
||||
|
||||
static status_t _GetData(partition_id id, bool deviceOnly, bool shadow,
|
||||
size_t neededSize, user_disk_device_data **data);
|
||||
|
||||
status_t _SetTo(partition_id id, bool deviceOnly, bool shadow,
|
||||
size_t neededSize);
|
||||
status_t _SetTo(user_disk_device_data *data);
|
||||
status_t _Update(bool shadow, bool *updated);
|
||||
status_t _Update(user_disk_device_data *data, bool *updated);
|
||||
|
||||
virtual bool _AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level);
|
||||
|
||||
|
@ -139,10 +139,15 @@ private:
|
||||
status_t _SetTo(BDiskDevice *device, BPartition *parent,
|
||||
user_partition_data *data);
|
||||
void _Unset();
|
||||
status_t _RemoveObsoleteDescendants(user_partition_data *data,
|
||||
bool *updated);
|
||||
status_t _Update(user_partition_data *data, bool *updated);
|
||||
void _RemoveChild(int32 index);
|
||||
|
||||
bool _IsShadow() const;
|
||||
partition_id _ShadowID() const;
|
||||
disk_system_id _DiskSystem() const;
|
||||
int32 _ChangeCounter() const;
|
||||
|
||||
int32 _CountDescendants() const;
|
||||
int32 _Level() const;
|
||||
|
@ -140,51 +140,7 @@ BDiskDevice::SetTo(partition_id id)
|
||||
status_t
|
||||
BDiskDevice::Update(bool *updated)
|
||||
{
|
||||
/*
|
||||
// get a messenger for the disk device manager
|
||||
// TODO: Cache the messenger? Maybe add a global variable?
|
||||
BMessenger manager;
|
||||
status_t error = get_disk_device_messenger(&manager);
|
||||
// compose request message
|
||||
BMessage request(B_REG_UPDATE_DISK_DEVICE);
|
||||
if (error == B_OK)
|
||||
error = request.AddInt32("device_id", fUniqueID);
|
||||
if (error == B_OK)
|
||||
error = request.AddInt32("change_counter", fChangeCounter);
|
||||
if (error == B_OK)
|
||||
error = request.AddInt32("update_policy", B_REG_DEVICE_UPDATE_CHANGED);
|
||||
// send request
|
||||
BMessage reply;
|
||||
if (error == B_OK)
|
||||
error = manager.SendMessage(&request, &reply);
|
||||
// analyze reply
|
||||
bool upToDate = true;
|
||||
if (error == B_OK) {
|
||||
// result
|
||||
status_t result = B_OK;
|
||||
error = reply.FindInt32("result", &result);
|
||||
if (error == B_OK)
|
||||
error = result;
|
||||
if (error == B_OK)
|
||||
error = reply.FindBool("up_to_date", &upToDate);
|
||||
}
|
||||
// get the archived device, if not up to date
|
||||
if (error == B_OK && !upToDate) {
|
||||
BMessage archive;
|
||||
error = reply.FindMessage("device", &archive);
|
||||
if (error == B_OK)
|
||||
error = _Update(&archive);
|
||||
}
|
||||
// set result / cleanup on error
|
||||
if (error == B_OK) {
|
||||
if (updated)
|
||||
*updated = !upToDate;
|
||||
} else
|
||||
Unset();
|
||||
return error;
|
||||
*/
|
||||
// not implemented
|
||||
return B_ERROR;
|
||||
return _Update(_IsShadow(), updated);
|
||||
}
|
||||
|
||||
// Unset
|
||||
@ -235,8 +191,12 @@ BDiskDevice::PrepareModifications()
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// update
|
||||
// TODO: Add an _Update(bool shadow)?
|
||||
return _SetTo(ID(), true, true, 0);
|
||||
error = _Update(true, NULL);
|
||||
if (error != B_OK) {
|
||||
// bad -- cancelling the modifications is all we can do
|
||||
_kern_cancel_disk_device_modifications(ID());
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// CommitModifications
|
||||
@ -264,12 +224,27 @@ BDiskDevice::CancelModifications()
|
||||
return error;
|
||||
}
|
||||
|
||||
// _SetTo
|
||||
status_t
|
||||
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
||||
size_t neededSize)
|
||||
// copy constructor
|
||||
/*! \brief Privatized copy constructor to avoid usage.
|
||||
*/
|
||||
BDiskDevice::BDiskDevice(const BDiskDevice &)
|
||||
{
|
||||
}
|
||||
|
||||
// =
|
||||
/*! \brief Privatized assignment operator to avoid usage.
|
||||
*/
|
||||
BDiskDevice &
|
||||
BDiskDevice::operator=(const BDiskDevice &)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// _GetData
|
||||
status_t
|
||||
BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow,
|
||||
size_t neededSize, user_disk_device_data **data)
|
||||
{
|
||||
Unset();
|
||||
// get the device data
|
||||
void *buffer = NULL;
|
||||
size_t bufferSize = 0;
|
||||
@ -296,12 +271,29 @@ BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
||||
error = B_NO_MEMORY;
|
||||
}
|
||||
} while (error == B_BUFFER_OVERFLOW);
|
||||
// set result / cleanup on error
|
||||
if (error == B_OK)
|
||||
*data = (user_disk_device_data*)buffer;
|
||||
else if (buffer)
|
||||
free(buffer);
|
||||
return error;
|
||||
}
|
||||
|
||||
// _SetTo
|
||||
status_t
|
||||
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
||||
size_t neededSize)
|
||||
{
|
||||
Unset();
|
||||
// get the device data
|
||||
user_disk_device_data *data = NULL;
|
||||
status_t error = _GetData(id, deviceOnly, shadow, neededSize, &data);
|
||||
// set the data
|
||||
if (error == B_OK)
|
||||
error = _SetTo((user_disk_device_data*)buffer);
|
||||
error = _SetTo(data);
|
||||
// cleanup on error
|
||||
if (error != B_OK)
|
||||
free(buffer);
|
||||
if (error != B_OK && data)
|
||||
free(data);
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -324,6 +316,54 @@ BDiskDevice::_SetTo(user_disk_device_data *data)
|
||||
return error;
|
||||
}
|
||||
|
||||
// _Update
|
||||
status_t
|
||||
BDiskDevice::_Update(bool shadow, bool *updated)
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
// get the device data
|
||||
user_disk_device_data *data = NULL;
|
||||
status_t error = _GetData(ID(), true, shadow, 0, &data);
|
||||
// set the data
|
||||
if (error == B_OK)
|
||||
error = _Update(data, updated);
|
||||
// cleanup on error
|
||||
if (error != B_OK && data)
|
||||
free(data);
|
||||
return error;
|
||||
}
|
||||
|
||||
// _Update
|
||||
status_t
|
||||
BDiskDevice::_Update(user_disk_device_data *data, bool *updated)
|
||||
{
|
||||
if (!data || !fDeviceData || ID() != data->device_partition_data.id)
|
||||
return B_BAD_VALUE;
|
||||
bool _updated;
|
||||
if (!updated)
|
||||
updated = &_updated;
|
||||
*updated = false;
|
||||
// remove obsolete partitions
|
||||
status_t error = _RemoveObsoleteDescendants(&data->device_partition_data,
|
||||
updated);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// update existing partitions and add new ones
|
||||
error = BPartition::_Update(&data->device_partition_data, updated);
|
||||
if (error == B_OK) {
|
||||
user_disk_device_data *oldData = fDeviceData;
|
||||
fDeviceData = data;
|
||||
// check for changes
|
||||
if (data->device_flags != oldData->device_flags
|
||||
|| strcmp(data->path, oldData->path)) {
|
||||
*updated = true;
|
||||
}
|
||||
free(oldData);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// _AcceptVisitor
|
||||
bool
|
||||
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
||||
@ -331,518 +371,3 @@ BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
||||
return visitor->Visit(this);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// Path
|
||||
/*! \brief Returns the path to the device.
|
||||
\return The path to the device.
|
||||
*/
|
||||
const char *
|
||||
BDiskDevice::Path() const
|
||||
{
|
||||
return (fPath[0] != '\0' ? fPath : NULL);
|
||||
}
|
||||
|
||||
// skip_string_component
|
||||
static
|
||||
const char *
|
||||
skip_string_component(const char *str, const char *component)
|
||||
{
|
||||
const char *remainder = NULL;
|
||||
if (str && component) {
|
||||
size_t len = strlen(component);
|
||||
if (!strncmp(str, component, len))
|
||||
remainder = str + len;
|
||||
}
|
||||
return remainder;
|
||||
}
|
||||
|
||||
// GetName
|
||||
/*! \brief Returns a human readable name for the device.
|
||||
|
||||
The method tries to interpret the device path, which it can do only for
|
||||
floppy, IDE and SCSI devices, for others the device path is returned.
|
||||
|
||||
\param name Pointer to a pre-allocated BString to be set to the device
|
||||
name.
|
||||
\param includeBusID \c true, if the bus ID shall be included in the name
|
||||
to be returned (of interest for SCSI devices).
|
||||
\param includeLUN \c true, if the LUN shall be included in the name
|
||||
to be returned (of interest for SCSI devices).
|
||||
\return
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_BAD_VALUE: \c NULL \a name.
|
||||
- \c B_NO_INIT: The device is not properly initialized.
|
||||
*/
|
||||
status_t
|
||||
BDiskDevice::GetName(BString *name, bool includeBusID, bool includeLUN) const
|
||||
{
|
||||
// check params and initialization
|
||||
status_t error = (name ? B_OK : B_BAD_VALUE);
|
||||
const char *path = Path();
|
||||
if (error == B_OK && !path)
|
||||
error = B_BAD_VALUE;
|
||||
// analyze the device path
|
||||
if (error == B_OK) {
|
||||
bool recognized = false;
|
||||
const char *prefix = "/dev/disk/";
|
||||
size_t prefixLen = strlen(prefix);
|
||||
if (!strncmp(path, prefix, prefixLen)) {
|
||||
path = path + prefixLen;
|
||||
// check first component
|
||||
const char *tail = NULL;
|
||||
// floppy
|
||||
if (skip_string_component(path, "floppy/")) {
|
||||
name->SetTo("floppy");
|
||||
recognized = true;
|
||||
// ide
|
||||
} else if ((tail = skip_string_component(path, "ide/"))) {
|
||||
int controller = 0;
|
||||
bool master = false;
|
||||
const char *_tail = tail;
|
||||
if ((((tail = skip_string_component(_tail, "atapi/")))
|
||||
|| ((tail = skip_string_component(_tail, "ata/"))))
|
||||
&& isdigit(*tail)) {
|
||||
controller = atoi(tail);
|
||||
master = false;
|
||||
if ((tail = strchr(tail, '/'))) {
|
||||
tail++;
|
||||
if (skip_string_component(tail, "master/")) {
|
||||
master = true;
|
||||
recognized = true;
|
||||
} else if (skip_string_component(tail, "slave/"))
|
||||
recognized = true;
|
||||
}
|
||||
}
|
||||
if (recognized) {
|
||||
name->SetTo("IDE ");
|
||||
*name << (master ? "master" : "slave") << " bus:"
|
||||
<< controller;
|
||||
}
|
||||
// scsi
|
||||
} else if ((tail = skip_string_component(path, "scsi/"))) {
|
||||
int bus = 0;
|
||||
int id = 0;
|
||||
int lun = 0;
|
||||
if (sscanf(tail, "%d/%d/%d/raw", &bus, &id, &lun) == 3) {
|
||||
recognized = true;
|
||||
name->SetTo("SCSI");
|
||||
if (includeBusID)
|
||||
*name << " bus:" << bus;
|
||||
*name << " id:" << id;
|
||||
if (includeLUN)
|
||||
*name << " lun:" << lun;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!recognized)
|
||||
name->SetTo(path);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// GetName
|
||||
/*! \brief Returns a human readable name for the device.
|
||||
|
||||
The method tries to interpret the device path, which it can do only for
|
||||
floppy, IDE and SCSI devices, for others the device path is returned.
|
||||
|
||||
\param name Pointer to a pre-allocated char buffer into which the device
|
||||
name shall be copied.
|
||||
\param includeBusID \c true, if the bus ID shall be included in the name
|
||||
to be returned (of interest for SCSI devices).
|
||||
\param includeLUN \c true, if the LUN shall be included in the name
|
||||
to be returned (of interest for SCSI devices).
|
||||
- \c B_OK: Everything went fine.
|
||||
- \c B_BAD_VALUE: \c NULL \a name.
|
||||
- \c B_NO_INIT: The device is not properly initialized.
|
||||
*/
|
||||
status_t
|
||||
BDiskDevice::GetName(char *name, bool includeBusID, bool includeLUN) const
|
||||
{
|
||||
status_t error = (name ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
BString _name;
|
||||
error = GetName(&_name, includeBusID, includeLUN);
|
||||
if (error == B_OK)
|
||||
strcpy(name, _name.String());
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// IsReadOnly
|
||||
/*! \brief Returns whether the device is read-only.
|
||||
\return \c true, if the device is read-only, \c false otherwise.
|
||||
*/
|
||||
bool
|
||||
BDiskDevice::IsReadOnly() const
|
||||
{
|
||||
return fReadOnly;
|
||||
}
|
||||
|
||||
// IsFloppy
|
||||
/*! \brief Returns whether the device is a floppy device.
|
||||
\return \c true, if the device is a floppy device, \c false otherwise.
|
||||
*/
|
||||
bool
|
||||
BDiskDevice::IsFloppy() const
|
||||
{
|
||||
return !strcmp(fPath, "/dev/disk/floppy/raw");
|
||||
}
|
||||
|
||||
// Type
|
||||
/*! \brief Returns the type of the device.
|
||||
|
||||
The type may be one of the following (note, that not all types make sense
|
||||
for storage device, but they are listed anyway):
|
||||
- \c B_DISK: Hard disks, floppy disks, etc.
|
||||
- \c B_TAPE: Tape drives.
|
||||
- \c B_PRINTER: Printers.
|
||||
- \c B_CPU: CPU devices.
|
||||
- \c B_WORM: Write-once, read-many devives.
|
||||
- \c B_CD: CD ROMs.
|
||||
- \c B_SCANNER: Scanners.
|
||||
- \c B_OPTICAL: Optical devices.
|
||||
- \c B_JUKEBOX: Jukeboxes.
|
||||
- \c B_NETWORK: Network devices.
|
||||
\return The type of the device.
|
||||
*/
|
||||
uint8
|
||||
BDiskDevice::Type() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
// UniqueID
|
||||
/*! \brief Returns a unique identifier for this device.
|
||||
|
||||
The ID is not persistent, i.e. in general won't be the same after
|
||||
rebooting.
|
||||
|
||||
\see BDiskDeviceRoster::GetDeviceWithID().
|
||||
|
||||
\return A unique identifier for this device.
|
||||
*/
|
||||
int32
|
||||
BDiskDevice::UniqueID() const
|
||||
{
|
||||
return fUniqueID;
|
||||
}
|
||||
|
||||
// LowLevelFormat
|
||||
/*! \brief Low level formats the device.
|
||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
||||
*/
|
||||
status_t
|
||||
BDiskDevice::LowLevelFormat()
|
||||
{
|
||||
return B_ERROR; // not implemented
|
||||
}
|
||||
|
||||
// VisitEachSession
|
||||
/*! \brief Iterates through the device's sessions.
|
||||
|
||||
The supplied visitor's Visit(BSession*) is invoked for each session.
|
||||
If Visit() returns \c true, the iteration is terminated and the BSession
|
||||
object just visited is returned.
|
||||
|
||||
\param visitor The visitor.
|
||||
\return The BSession object at which the iteration was terminated, or
|
||||
\c NULL, if the iteration has not been terminated.
|
||||
*/
|
||||
BSession *
|
||||
BDiskDevice::VisitEachSession(BDiskDeviceVisitor *visitor)
|
||||
{
|
||||
if (visitor) {
|
||||
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
|
||||
if (visitor->Visit(session))
|
||||
return session;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// VisitEachPartition
|
||||
/*! \brief Iterates through the device's partitions.
|
||||
|
||||
The supplied visitor's Visit(BPartition*) is invoked for each partition.
|
||||
If Visit() returns \c true, the iteration is terminated and the BPartition
|
||||
object just visited is returned.
|
||||
|
||||
\param visitor The visitor.
|
||||
\return The BPartition object at which the iteration was terminated, or
|
||||
\c NULL, if the iteration has not been terminated.
|
||||
*/
|
||||
BPartition *
|
||||
BDiskDevice::VisitEachPartition(BDiskDeviceVisitor *visitor)
|
||||
{
|
||||
if (visitor) {
|
||||
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
|
||||
if (BPartition *partition = session->VisitEachPartition(visitor))
|
||||
return partition;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Traverse
|
||||
/*! \brief Pre-order traverses the tree of the spanned by the BDiskDevice and
|
||||
its subobjects.
|
||||
|
||||
The supplied visitor's Visit() is invoked for the device object itself,
|
||||
for each session and for each partition.
|
||||
If Visit() returns \c true, the iteration is terminated and this method
|
||||
returns \c true as well.
|
||||
|
||||
\param visitor The visitor.
|
||||
\return \c true, if the iteration was terminated, \c false otherwise.
|
||||
*/
|
||||
bool
|
||||
BDiskDevice::Traverse(BDiskDeviceVisitor *visitor)
|
||||
{
|
||||
if (visitor) {
|
||||
// visit the device itself
|
||||
if (visitor->Visit(this))
|
||||
return true;
|
||||
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
|
||||
// visit the session
|
||||
if (visitor->Visit(session))
|
||||
return true;
|
||||
// visit all partitions on the session
|
||||
if (session->VisitEachPartition(visitor))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// SessionWithID
|
||||
/*! \brief Returns the session on the device, that has a certain ID.
|
||||
\param id The ID of the session to be returned.
|
||||
\return The session with ID \a id, or \c NULL, if a session with that
|
||||
ID does not exist on this device.
|
||||
*/
|
||||
BSession *
|
||||
BDiskDevice::SessionWithID(int32 id)
|
||||
{
|
||||
IDFinderVisitor visitor(id);
|
||||
return VisitEachSession(&visitor);
|
||||
}
|
||||
|
||||
// PartitionWithID
|
||||
/*! \brief Returns the partition on the device, that has a certain ID.
|
||||
\param id The ID of the partition to be returned.
|
||||
\return The partition with ID \a id, or \c NULL, if a partition with that
|
||||
ID does not exist on this device.
|
||||
*/
|
||||
BPartition *
|
||||
BDiskDevice::PartitionWithID(int32 id)
|
||||
{
|
||||
IDFinderVisitor visitor(id);
|
||||
return VisitEachPartition(&visitor);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
/*! \brief Privatized copy constructor to avoid usage.
|
||||
*/
|
||||
BDiskDevice::BDiskDevice(const BDiskDevice &)
|
||||
{
|
||||
}
|
||||
|
||||
// =
|
||||
/*! \brief Privatized assignment operator to avoid usage.
|
||||
*/
|
||||
BDiskDevice &
|
||||
BDiskDevice::operator=(const BDiskDevice &)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
// find_string
|
||||
static
|
||||
status_t
|
||||
find_string(BMessage *message, const char *name, char *buffer)
|
||||
{
|
||||
const char *str;
|
||||
status_t error = message->FindString(name, &str);
|
||||
if (error == B_OK)
|
||||
strcpy(buffer, str);
|
||||
return error;
|
||||
}
|
||||
|
||||
// _Unarchive
|
||||
status_t
|
||||
BDiskDevice::_Unarchive(BMessage *archive)
|
||||
{
|
||||
//printf("BDiskDevice::_Unarchive()\n");
|
||||
//archive->PrintToStream();
|
||||
Unset();
|
||||
status_t error = (archive ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
// ID and change counter
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("id", &fUniqueID);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("change_counter", &fChangeCounter);
|
||||
// geometry
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt64("size", &fSize);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("block_size", &fBlockSize);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt8("type", (int8*)&fType);
|
||||
if (error == B_OK)
|
||||
error = archive->FindBool("removable", &fRemovable);
|
||||
if (error == B_OK)
|
||||
error = archive->FindBool("read_only", &fReadOnly);
|
||||
// other data
|
||||
if (error == B_OK)
|
||||
error = find_string(archive, "path", fPath);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("media_status", &fMediaStatus);
|
||||
// sessions
|
||||
type_code fieldType;
|
||||
int32 count = 0;
|
||||
if (error == B_OK) {
|
||||
if (archive->GetInfo("sessions", &fieldType, &count) != B_OK)
|
||||
count = 0;
|
||||
}
|
||||
for (int32 i = 0; error == B_OK && i < count; i++) {
|
||||
// get the archived session
|
||||
BMessage sessionArchive;
|
||||
error = archive->FindMessage("sessions", i, &sessionArchive);
|
||||
// allocate a session object
|
||||
BSession *session = NULL;
|
||||
if (error == B_OK) {
|
||||
session = new(nothrow) BSession;
|
||||
if (!session)
|
||||
error = B_NO_MEMORY;
|
||||
}
|
||||
// unarchive the session
|
||||
if (error == B_OK)
|
||||
error = session->_Unarchive(&sessionArchive);
|
||||
// add the session
|
||||
if (error == B_OK && !_AddSession(session))
|
||||
error = B_NO_MEMORY;
|
||||
// cleanup on error
|
||||
if (error != B_OK && session)
|
||||
delete session;
|
||||
}
|
||||
}
|
||||
// cleanup on error
|
||||
if (error != B_OK)
|
||||
Unset();
|
||||
//printf("BDiskDevice::_Unarchive() done: %s\n", strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// _Update
|
||||
status_t
|
||||
BDiskDevice::_Update(BMessage *archive)
|
||||
{
|
||||
status_t error = (archive ? B_OK : B_BAD_VALUE);
|
||||
bool upToDate = false;
|
||||
if (error == B_OK) {
|
||||
// ID and change counter
|
||||
int32 id;
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("id", &id);
|
||||
if (error == B_OK && id != fUniqueID)
|
||||
error = B_ERROR;
|
||||
int32 changeCounter;
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("change_counter", &changeCounter);
|
||||
upToDate = (fChangeCounter == changeCounter);
|
||||
fChangeCounter = changeCounter;
|
||||
}
|
||||
if (error == B_OK && !upToDate) {
|
||||
// geometry
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt64("size", &fSize);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("block_size", &fBlockSize);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt8("type", (int8*)&fType);
|
||||
if (error == B_OK)
|
||||
error = archive->FindBool("removable", &fRemovable);
|
||||
if (error == B_OK)
|
||||
error = archive->FindBool("read_only", &fReadOnly);
|
||||
// other data
|
||||
if (error == B_OK)
|
||||
error = find_string(archive, "path", fPath);
|
||||
if (error == B_OK)
|
||||
error = archive->FindInt32("media_status", &fMediaStatus);
|
||||
// sessions
|
||||
// copy old session list and empty it
|
||||
BObjectList<BSession> sessions;
|
||||
for (int32 i = 0; BSession *session = fSessions.ItemAt(i); i++)
|
||||
sessions.AddItem(session);
|
||||
for (int32 i = fSessions.CountItems() - 1; i >= 0; i--)
|
||||
fSessions.RemoveItemAt(i);
|
||||
// get the session count
|
||||
type_code fieldType;
|
||||
int32 count = 0;
|
||||
if (error == B_OK) {
|
||||
if (archive->GetInfo("sessions", &fieldType, &count) != B_OK)
|
||||
count = 0;
|
||||
}
|
||||
for (int32 i = 0; error == B_OK && i < count; i++) {
|
||||
// get the archived session
|
||||
BMessage sessionArchive;
|
||||
error = archive->FindMessage("sessions", i, &sessionArchive);
|
||||
// check, whether we do already know that session
|
||||
int32 sessionID;
|
||||
if (error == B_OK)
|
||||
error = sessionArchive.FindInt32("id", &sessionID);
|
||||
BSession *session = NULL;
|
||||
for (int32 k = 0; k < sessions.CountItems(); k++) {
|
||||
BSession *oldSession = sessions.ItemAt(i);
|
||||
if (oldSession->UniqueID() == sessionID) {
|
||||
session = oldSession;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (error == B_OK) {
|
||||
if (session) {
|
||||
// the session is known: just update it
|
||||
error = session->_Update(&sessionArchive);
|
||||
} else {
|
||||
// the session is unknown
|
||||
// allocate a session object
|
||||
session = new(nothrow) BSession;
|
||||
if (!session)
|
||||
error = B_NO_MEMORY;
|
||||
// unarchive the session
|
||||
if (error == B_OK)
|
||||
error = session->_Unarchive(&sessionArchive);
|
||||
}
|
||||
}
|
||||
// add the session
|
||||
if (error == B_OK && !_AddSession(session))
|
||||
error = B_NO_MEMORY;
|
||||
// cleanup on error
|
||||
if (error != B_OK && session)
|
||||
delete session;
|
||||
}
|
||||
// delete all obsolete sessions
|
||||
for (int32 i = sessions.CountItems() - 1; i >= 0; i--)
|
||||
delete sessions.RemoveItemAt(i);
|
||||
}
|
||||
// cleanup on error
|
||||
if (error != B_OK)
|
||||
Unset();
|
||||
return error;
|
||||
}
|
||||
|
||||
// _AddSession
|
||||
bool
|
||||
BDiskDevice::_AddSession(BSession *session)
|
||||
{
|
||||
bool result = fSessions.AddItem(session);
|
||||
if (result)
|
||||
session->_SetDevice(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif //0
|
||||
|
@ -405,7 +405,7 @@ BPartition::GetPartitioningInfo(BPartitioningInfo *info) const
|
||||
{
|
||||
if (!info || !fPartitionData || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
return info->_SetTo(_ShadowID());
|
||||
return info->_SetTo(_ShadowID(), _ChangeCounter());
|
||||
}
|
||||
|
||||
// VisitEachChild
|
||||
@ -437,6 +437,7 @@ BPartition::CanDefragment(bool *whileMounted) const
|
||||
{
|
||||
return (fPartitionData && _IsShadow()
|
||||
&& _kern_supports_defragmenting_partition(_ShadowID(),
|
||||
_ChangeCounter(),
|
||||
whileMounted));
|
||||
}
|
||||
|
||||
@ -446,7 +447,7 @@ BPartition::Defragment() const
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_defragment_partition(_ShadowID());
|
||||
status_t error = _kern_defragment_partition(_ShadowID(), _ChangeCounter());
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -457,8 +458,8 @@ bool
|
||||
BPartition::CanRepair(bool checkOnly, bool *whileMounted) const
|
||||
{
|
||||
return (fPartitionData && _IsShadow()
|
||||
&& _kern_supports_repairing_partition(_ShadowID(), checkOnly,
|
||||
whileMounted));
|
||||
&& _kern_supports_repairing_partition(_ShadowID(), _ChangeCounter(),
|
||||
checkOnly, whileMounted));
|
||||
}
|
||||
|
||||
// Repair
|
||||
@ -467,7 +468,8 @@ BPartition::Repair(bool checkOnly) const
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_repair_partition(_ShadowID(), checkOnly);
|
||||
status_t error = _kern_repair_partition(_ShadowID(), _ChangeCounter(),
|
||||
checkOnly);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -478,7 +480,7 @@ bool
|
||||
BPartition::CanResize(bool *canResizeContents, bool *whileMounted) const
|
||||
{
|
||||
return (fPartitionData && !IsDevice() && Parent() && _IsShadow()
|
||||
&& _kern_supports_resizing_partition(_ShadowID(),
|
||||
&& _kern_supports_resizing_partition(_ShadowID(), _ChangeCounter(),
|
||||
canResizeContents, whileMounted));
|
||||
}
|
||||
|
||||
@ -488,7 +490,8 @@ BPartition::ValidateResize(off_t *size, bool resizeContents) const
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !size)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_resize_partition(_ShadowID(), size, resizeContents);
|
||||
return _kern_validate_resize_partition(_ShadowID(), _ChangeCounter(), size,
|
||||
resizeContents);
|
||||
}
|
||||
|
||||
// Resize
|
||||
@ -497,7 +500,8 @@ BPartition::Resize(off_t size, bool resizeContents)
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_resize_partition(_ShadowID(), size, resizeContents);
|
||||
status_t error = _kern_resize_partition(_ShadowID(), _ChangeCounter(),
|
||||
size, resizeContents);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -534,8 +538,9 @@ BPartition::CanMove(BObjectList<BPartition> *unmovableDescendants,
|
||||
}
|
||||
}
|
||||
// get the info
|
||||
bool result = _kern_supports_moving_partition(_ShadowID(), unmovableIDs,
|
||||
needUnmountingIDs, descendantCount);
|
||||
bool result = _kern_supports_moving_partition(_ShadowID(),
|
||||
_ChangeCounter(), unmovableIDs, needUnmountingIDs,
|
||||
descendantCount);
|
||||
if (result) {
|
||||
// find unmovable BPartition objects for returned IDs
|
||||
for (int32 i = 0; i < descendantCount && unmovableIDs[i] != -1; i++) {
|
||||
@ -562,7 +567,8 @@ BPartition::ValidateMove(off_t *newOffset, bool force) const
|
||||
|| !newOffset) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
return _kern_validate_move_partition(_ShadowID(), newOffset, force);
|
||||
return _kern_validate_move_partition(_ShadowID(), _ChangeCounter(),
|
||||
newOffset, force);
|
||||
}
|
||||
|
||||
// Move
|
||||
@ -571,7 +577,8 @@ BPartition::Move(off_t newOffset, bool force)
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_resize_partition(_ShadowID(), newOffset, force);
|
||||
status_t error = _kern_resize_partition(_ShadowID(), _ChangeCounter(),
|
||||
newOffset, force);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -582,7 +589,8 @@ bool
|
||||
BPartition::CanSetName() const
|
||||
{
|
||||
return (fPartitionData && Parent() && _IsShadow()
|
||||
&& _kern_supports_setting_partition_name(_ShadowID()));
|
||||
&& _kern_supports_setting_partition_name(_ShadowID(),
|
||||
_ChangeCounter()));
|
||||
}
|
||||
|
||||
// ValidateSetName
|
||||
@ -591,7 +599,8 @@ BPartition::ValidateSetName(char *name) const
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_set_partition_name(_ShadowID(), name);
|
||||
return _kern_validate_set_partition_name(_ShadowID(), _ChangeCounter(),
|
||||
name);
|
||||
}
|
||||
|
||||
// SetName
|
||||
@ -600,7 +609,8 @@ BPartition::SetName(const char *name)
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_set_partition_name(_ShadowID(), name);
|
||||
status_t error = _kern_set_partition_name(_ShadowID(), _ChangeCounter(),
|
||||
name);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -612,6 +622,7 @@ BPartition::CanSetContentName(bool *whileMounted) const
|
||||
{
|
||||
return (fPartitionData && _IsShadow()
|
||||
&& _kern_supports_setting_partition_content_name(_ShadowID(),
|
||||
_ChangeCounter(),
|
||||
whileMounted));
|
||||
}
|
||||
|
||||
@ -621,7 +632,8 @@ BPartition::ValidateSetContentName(char *name) const
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow() || !name)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_set_partition_content_name(_ShadowID(), name);
|
||||
return _kern_validate_set_partition_content_name(_ShadowID(),
|
||||
_ChangeCounter(), name);
|
||||
}
|
||||
|
||||
// SetContentName
|
||||
@ -630,7 +642,8 @@ BPartition::SetContentName(const char *name)
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow() || !name)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_set_partition_content_name(_ShadowID(), name);
|
||||
status_t error = _kern_set_partition_content_name(_ShadowID(),
|
||||
_ChangeCounter(), name);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -641,7 +654,8 @@ bool
|
||||
BPartition::CanSetType() const
|
||||
{
|
||||
return (fPartitionData && Parent() && _IsShadow()
|
||||
&& _kern_supports_setting_partition_type(_ShadowID()));
|
||||
&& _kern_supports_setting_partition_type(_ShadowID(),
|
||||
_ChangeCounter()));
|
||||
}
|
||||
|
||||
// ValidateSetType
|
||||
@ -650,7 +664,8 @@ BPartition::ValidateSetType(const char *type) const
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_set_partition_type(_ShadowID(), type);
|
||||
return _kern_validate_set_partition_type(_ShadowID(), _ChangeCounter(),
|
||||
type);
|
||||
}
|
||||
|
||||
// SetType
|
||||
@ -659,7 +674,8 @@ BPartition::SetType(const char *type)
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_set_partition_type(_ShadowID(), type);
|
||||
status_t error = _kern_set_partition_type(_ShadowID(), _ChangeCounter(),
|
||||
type);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -670,7 +686,8 @@ bool
|
||||
BPartition::CanEditParameters() const
|
||||
{
|
||||
return (fPartitionData && Parent() && _IsShadow()
|
||||
&& _kern_supports_setting_partition_parameters(_ShadowID()));
|
||||
&& _kern_supports_setting_partition_parameters(_ShadowID(),
|
||||
_ChangeCounter()));
|
||||
}
|
||||
|
||||
// GetParameterEditor
|
||||
@ -687,7 +704,9 @@ BPartition::SetParameters(const char *parameters)
|
||||
{
|
||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_set_partition_parameters(_ShadowID(), parameters);
|
||||
status_t error = _kern_set_partition_parameters(_ShadowID(),
|
||||
_ChangeCounter(),
|
||||
parameters);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -699,7 +718,7 @@ BPartition::CanEditContentParameters(bool *whileMounted) const
|
||||
{
|
||||
return (fPartitionData && _IsShadow()
|
||||
&& _kern_supports_setting_partition_content_parameters(
|
||||
_ShadowID(), whileMounted));
|
||||
_ShadowID(), _ChangeCounter(), whileMounted));
|
||||
}
|
||||
|
||||
// GetContentParameterEditor
|
||||
@ -717,6 +736,7 @@ BPartition::SetContentParameters(const char *parameters)
|
||||
if (!fPartitionData || !_IsShadow())
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_set_partition_content_parameters(_ShadowID(),
|
||||
_ChangeCounter(),
|
||||
parameters);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
@ -728,7 +748,9 @@ bool
|
||||
BPartition::CanInitialize(const char *diskSystem) const
|
||||
{
|
||||
return (fPartitionData && diskSystem && _IsShadow()
|
||||
&& _kern_supports_initializing_partition(_ShadowID(), diskSystem));
|
||||
&& _kern_supports_initializing_partition(_ShadowID(),
|
||||
_ChangeCounter(),
|
||||
diskSystem));
|
||||
}
|
||||
|
||||
// GetInitializationParameterEditor
|
||||
@ -747,8 +769,8 @@ BPartition::ValidateInitialize(const char *diskSystem, char *name,
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_initialize_partition(_ShadowID(), diskSystem, name,
|
||||
parameters);
|
||||
return _kern_validate_initialize_partition(_ShadowID(), _ChangeCounter(),
|
||||
diskSystem, name, parameters);
|
||||
}
|
||||
|
||||
// Initialize
|
||||
@ -758,8 +780,8 @@ BPartition::Initialize(const char *diskSystem, const char *name,
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _kern_initialize_partition(_ShadowID(), diskSystem, name,
|
||||
parameters);
|
||||
status_t error = _kern_initialize_partition(_ShadowID(), _ChangeCounter(),
|
||||
diskSystem, name, parameters);
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
return error;
|
||||
@ -770,7 +792,8 @@ bool
|
||||
BPartition::CanCreateChild() const
|
||||
{
|
||||
return (fPartitionData && _IsShadow()
|
||||
&& _kern_supports_creating_child_partition(_ShadowID()));
|
||||
&& _kern_supports_creating_child_partition(_ShadowID(),
|
||||
_ChangeCounter()));
|
||||
}
|
||||
|
||||
// GetChildCreationParameterEditor
|
||||
@ -789,8 +812,9 @@ BPartition::ValidateCreateChild(off_t *offset, off_t *size, const char *type,
|
||||
{
|
||||
if (!fPartitionData || !_IsShadow() || !offset || !size || !type)
|
||||
return B_BAD_VALUE;
|
||||
return _kern_validate_create_child_partition(_ShadowID(), offset, size,
|
||||
type, parameters);
|
||||
return _kern_validate_create_child_partition(_ShadowID(), _ChangeCounter(),
|
||||
offset, size, type,
|
||||
parameters);
|
||||
}
|
||||
|
||||
// CreateChild
|
||||
@ -802,8 +826,9 @@ BPartition::CreateChild(off_t offset, off_t size, const char *type,
|
||||
return B_BAD_VALUE;
|
||||
// send the request
|
||||
partition_id childID = -1;
|
||||
status_t error = _kern_create_child_partition(_ShadowID(), offset, size,
|
||||
type, parameters, &childID);
|
||||
status_t error = _kern_create_child_partition(_ShadowID(),
|
||||
_ChangeCounter(), offset, size, type, parameters,
|
||||
&childID);
|
||||
// update the device
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
@ -822,7 +847,8 @@ BPartition::CanDeleteChild(int32 index) const
|
||||
{
|
||||
BPartition *child = ChildAt(index);
|
||||
return (child && child->_IsShadow()
|
||||
&& _kern_supports_deleting_child_partition(child->_ShadowID()));
|
||||
&& _kern_supports_deleting_child_partition(child->_ShadowID(),
|
||||
child->_ChangeCounter()));
|
||||
}
|
||||
|
||||
// DeleteChild
|
||||
@ -833,7 +859,8 @@ BPartition::DeleteChild(int32 index)
|
||||
if (!fPartitionData || !_IsShadow() || !child)
|
||||
return B_BAD_VALUE;
|
||||
// send the request
|
||||
status_t error = _kern_delete_partition(child->_ShadowID());
|
||||
status_t error = _kern_delete_partition(child->_ShadowID(),
|
||||
child->_ChangeCounter());
|
||||
// update the device
|
||||
if (error == B_OK)
|
||||
error = Device()->Update();
|
||||
@ -902,6 +929,121 @@ BPartition::_Unset()
|
||||
fPartitionData = NULL;
|
||||
}
|
||||
|
||||
// _RemoveObsoleteDescendants
|
||||
status_t
|
||||
BPartition::_RemoveObsoleteDescendants(user_partition_data *data,
|
||||
bool *updated)
|
||||
{
|
||||
// remove all children not longer persistent
|
||||
// Not exactly efficient: O(n^2), considering BList::RemoveItem()
|
||||
// O(1). We could do better (O(n*log(n))), when sorting the arrays before,
|
||||
// but then the list access is more random and we had to find the
|
||||
// BPartition to remove, which makes the list operation definitely O(n).
|
||||
int32 count = CountChildren();
|
||||
for (int32 i = count - 1; i >= 0; i--) {
|
||||
BPartition *child = ChildAt(i);
|
||||
bool found = false;
|
||||
for (int32 k = data->child_count - 1; k >= 0; k--) {
|
||||
if (data->children[k]->id == child->ID()) {
|
||||
// found partition: ask it to remove its obsolete descendants
|
||||
found = true;
|
||||
status_t error = child->_RemoveObsoleteDescendants(
|
||||
data->children[k], updated);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// set the user data to the BPartition object to find it
|
||||
// quicker later
|
||||
data->children[k]->user_data = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if partition is obsolete, remove it
|
||||
if (!found) {
|
||||
*updated = true;
|
||||
_RemoveChild(i);
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// compare_string
|
||||
static
|
||||
int
|
||||
compare_string(const char *str1, const char *str2)
|
||||
{
|
||||
if (str1 == NULL) {
|
||||
if (str2 == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
} else if (str2 == NULL)
|
||||
return -1;
|
||||
return strcmp(str1, str2);
|
||||
}
|
||||
|
||||
// _Update
|
||||
status_t
|
||||
BPartition::_Update(user_partition_data *data, bool *updated)
|
||||
{
|
||||
user_partition_data *oldData = fPartitionData;
|
||||
fPartitionData = data;
|
||||
// check for changes
|
||||
if (data->offset != oldData->offset
|
||||
|| data->size != oldData->size
|
||||
|| data->block_size != oldData->block_size
|
||||
|| data->status != oldData->status
|
||||
|| data->flags != oldData->flags
|
||||
|| data->volume != oldData->volume
|
||||
|| data->disk_system != oldData->disk_system // not needed
|
||||
|| compare_string(data->name, oldData->name)
|
||||
|| compare_string(data->content_name, oldData->content_name)
|
||||
|| compare_string(data->type, oldData->type)
|
||||
|| compare_string(data->content_type, oldData->content_type)
|
||||
|| compare_string(data->parameters, oldData->parameters)
|
||||
|| compare_string(data->content_parameters,
|
||||
oldData->content_parameters)) {
|
||||
*updated = true;
|
||||
}
|
||||
// add new children and update existing ones
|
||||
status_t error = B_OK;
|
||||
for (int32 i = 0; i < data->child_count; i++) {
|
||||
user_partition_data *childData = data->children[i];
|
||||
BPartition *child = (BPartition*)childData->user_data;
|
||||
if (child) {
|
||||
// old partition
|
||||
error = child->_Update(childData, updated);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
} else {
|
||||
// new partition
|
||||
*updated = true;
|
||||
child = new(nothrow) BPartition;
|
||||
if (child) {
|
||||
error = child->_SetTo(fDevice, this, data->children[i]);
|
||||
if (error != B_OK)
|
||||
delete child;
|
||||
} else
|
||||
return B_NO_MEMORY;
|
||||
childData->user_data = child;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// _RemoveChild
|
||||
void
|
||||
BPartition::_RemoveChild(int32 index)
|
||||
{
|
||||
int32 count = CountChildren();
|
||||
if (!fPartitionData || index < 0 || index >= count)
|
||||
return;
|
||||
// delete the BPartition and its children
|
||||
delete ChildAt(index);
|
||||
// compact the children array
|
||||
for (int32 i = index + 1; i < count; i++)
|
||||
fPartitionData->children[i - 1] = fPartitionData->children[i];
|
||||
fPartitionData->child_count--;
|
||||
}
|
||||
|
||||
// _IsShadow
|
||||
bool
|
||||
BPartition::_IsShadow() const
|
||||
@ -923,6 +1065,13 @@ BPartition::_DiskSystem() const
|
||||
return (fPartitionData ? fPartitionData->disk_system : -1);
|
||||
}
|
||||
|
||||
// _ChangeCounter
|
||||
int32
|
||||
BPartition::_ChangeCounter() const
|
||||
{
|
||||
return (fPartitionData ? fPartitionData->change_counter : -1);
|
||||
}
|
||||
|
||||
// _CountDescendants
|
||||
int32
|
||||
BPartition::_CountDescendants() const
|
||||
|
Loading…
x
Reference in New Issue
Block a user