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 BDiskDeviceList;
|
||||||
friend class BDiskDeviceRoster;
|
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,
|
status_t _SetTo(partition_id id, bool deviceOnly, bool shadow,
|
||||||
size_t neededSize);
|
size_t neededSize);
|
||||||
status_t _SetTo(user_disk_device_data *data);
|
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);
|
virtual bool _AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level);
|
||||||
|
|
||||||
|
@ -139,10 +139,15 @@ private:
|
|||||||
status_t _SetTo(BDiskDevice *device, BPartition *parent,
|
status_t _SetTo(BDiskDevice *device, BPartition *parent,
|
||||||
user_partition_data *data);
|
user_partition_data *data);
|
||||||
void _Unset();
|
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;
|
bool _IsShadow() const;
|
||||||
partition_id _ShadowID() const;
|
partition_id _ShadowID() const;
|
||||||
disk_system_id _DiskSystem() const;
|
disk_system_id _DiskSystem() const;
|
||||||
|
int32 _ChangeCounter() const;
|
||||||
|
|
||||||
int32 _CountDescendants() const;
|
int32 _CountDescendants() const;
|
||||||
int32 _Level() const;
|
int32 _Level() const;
|
||||||
|
@ -140,51 +140,7 @@ BDiskDevice::SetTo(partition_id id)
|
|||||||
status_t
|
status_t
|
||||||
BDiskDevice::Update(bool *updated)
|
BDiskDevice::Update(bool *updated)
|
||||||
{
|
{
|
||||||
/*
|
return _Update(_IsShadow(), 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset
|
// Unset
|
||||||
@ -235,8 +191,12 @@ BDiskDevice::PrepareModifications()
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
// update
|
// update
|
||||||
// TODO: Add an _Update(bool shadow)?
|
error = _Update(true, NULL);
|
||||||
return _SetTo(ID(), true, true, 0);
|
if (error != B_OK) {
|
||||||
|
// bad -- cancelling the modifications is all we can do
|
||||||
|
_kern_cancel_disk_device_modifications(ID());
|
||||||
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitModifications
|
// CommitModifications
|
||||||
@ -264,12 +224,27 @@ BDiskDevice::CancelModifications()
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _SetTo
|
// copy constructor
|
||||||
status_t
|
/*! \brief Privatized copy constructor to avoid usage.
|
||||||
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
*/
|
||||||
size_t neededSize)
|
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
|
// get the device data
|
||||||
void *buffer = NULL;
|
void *buffer = NULL;
|
||||||
size_t bufferSize = 0;
|
size_t bufferSize = 0;
|
||||||
@ -296,12 +271,29 @@ BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
|||||||
error = B_NO_MEMORY;
|
error = B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
} while (error == B_BUFFER_OVERFLOW);
|
} 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
|
// set the data
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = _SetTo((user_disk_device_data*)buffer);
|
error = _SetTo(data);
|
||||||
// cleanup on error
|
// cleanup on error
|
||||||
if (error != B_OK)
|
if (error != B_OK && data)
|
||||||
free(buffer);
|
free(data);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,6 +316,54 @@ BDiskDevice::_SetTo(user_disk_device_data *data)
|
|||||||
return error;
|
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
|
// _AcceptVisitor
|
||||||
bool
|
bool
|
||||||
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
||||||
@ -331,518 +371,3 @@ BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
|||||||
return visitor->Visit(this);
|
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())
|
if (!info || !fPartitionData || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return info->_SetTo(_ShadowID());
|
return info->_SetTo(_ShadowID(), _ChangeCounter());
|
||||||
}
|
}
|
||||||
|
|
||||||
// VisitEachChild
|
// VisitEachChild
|
||||||
@ -437,6 +437,7 @@ BPartition::CanDefragment(bool *whileMounted) const
|
|||||||
{
|
{
|
||||||
return (fPartitionData && _IsShadow()
|
return (fPartitionData && _IsShadow()
|
||||||
&& _kern_supports_defragmenting_partition(_ShadowID(),
|
&& _kern_supports_defragmenting_partition(_ShadowID(),
|
||||||
|
_ChangeCounter(),
|
||||||
whileMounted));
|
whileMounted));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +447,7 @@ BPartition::Defragment() const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow())
|
if (!fPartitionData || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
status_t error = _kern_defragment_partition(_ShadowID());
|
status_t error = _kern_defragment_partition(_ShadowID(), _ChangeCounter());
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -457,8 +458,8 @@ bool
|
|||||||
BPartition::CanRepair(bool checkOnly, bool *whileMounted) const
|
BPartition::CanRepair(bool checkOnly, bool *whileMounted) const
|
||||||
{
|
{
|
||||||
return (fPartitionData && _IsShadow()
|
return (fPartitionData && _IsShadow()
|
||||||
&& _kern_supports_repairing_partition(_ShadowID(), checkOnly,
|
&& _kern_supports_repairing_partition(_ShadowID(), _ChangeCounter(),
|
||||||
whileMounted));
|
checkOnly, whileMounted));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repair
|
// Repair
|
||||||
@ -467,7 +468,8 @@ BPartition::Repair(bool checkOnly) const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow())
|
if (!fPartitionData || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -478,7 +480,7 @@ bool
|
|||||||
BPartition::CanResize(bool *canResizeContents, bool *whileMounted) const
|
BPartition::CanResize(bool *canResizeContents, bool *whileMounted) const
|
||||||
{
|
{
|
||||||
return (fPartitionData && !IsDevice() && Parent() && _IsShadow()
|
return (fPartitionData && !IsDevice() && Parent() && _IsShadow()
|
||||||
&& _kern_supports_resizing_partition(_ShadowID(),
|
&& _kern_supports_resizing_partition(_ShadowID(), _ChangeCounter(),
|
||||||
canResizeContents, whileMounted));
|
canResizeContents, whileMounted));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +490,8 @@ BPartition::ValidateResize(off_t *size, bool resizeContents) const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !size)
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !size)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_resize_partition(_ShadowID(), size, resizeContents);
|
return _kern_validate_resize_partition(_ShadowID(), _ChangeCounter(), size,
|
||||||
|
resizeContents);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize
|
// Resize
|
||||||
@ -497,7 +500,8 @@ BPartition::Resize(off_t size, bool resizeContents)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -534,8 +538,9 @@ BPartition::CanMove(BObjectList<BPartition> *unmovableDescendants,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// get the info
|
// get the info
|
||||||
bool result = _kern_supports_moving_partition(_ShadowID(), unmovableIDs,
|
bool result = _kern_supports_moving_partition(_ShadowID(),
|
||||||
needUnmountingIDs, descendantCount);
|
_ChangeCounter(), unmovableIDs, needUnmountingIDs,
|
||||||
|
descendantCount);
|
||||||
if (result) {
|
if (result) {
|
||||||
// find unmovable BPartition objects for returned IDs
|
// find unmovable BPartition objects for returned IDs
|
||||||
for (int32 i = 0; i < descendantCount && unmovableIDs[i] != -1; i++) {
|
for (int32 i = 0; i < descendantCount && unmovableIDs[i] != -1; i++) {
|
||||||
@ -562,7 +567,8 @@ BPartition::ValidateMove(off_t *newOffset, bool force) const
|
|||||||
|| !newOffset) {
|
|| !newOffset) {
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
return _kern_validate_move_partition(_ShadowID(), newOffset, force);
|
return _kern_validate_move_partition(_ShadowID(), _ChangeCounter(),
|
||||||
|
newOffset, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move
|
// Move
|
||||||
@ -571,7 +577,8 @@ BPartition::Move(off_t newOffset, bool force)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -582,7 +589,8 @@ bool
|
|||||||
BPartition::CanSetName() const
|
BPartition::CanSetName() const
|
||||||
{
|
{
|
||||||
return (fPartitionData && Parent() && _IsShadow()
|
return (fPartitionData && Parent() && _IsShadow()
|
||||||
&& _kern_supports_setting_partition_name(_ShadowID()));
|
&& _kern_supports_setting_partition_name(_ShadowID(),
|
||||||
|
_ChangeCounter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateSetName
|
// ValidateSetName
|
||||||
@ -591,7 +599,8 @@ BPartition::ValidateSetName(char *name) const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_set_partition_name(_ShadowID(), name);
|
return _kern_validate_set_partition_name(_ShadowID(), _ChangeCounter(),
|
||||||
|
name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetName
|
// SetName
|
||||||
@ -600,7 +609,8 @@ BPartition::SetName(const char *name)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !name)
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -612,6 +622,7 @@ BPartition::CanSetContentName(bool *whileMounted) const
|
|||||||
{
|
{
|
||||||
return (fPartitionData && _IsShadow()
|
return (fPartitionData && _IsShadow()
|
||||||
&& _kern_supports_setting_partition_content_name(_ShadowID(),
|
&& _kern_supports_setting_partition_content_name(_ShadowID(),
|
||||||
|
_ChangeCounter(),
|
||||||
whileMounted));
|
whileMounted));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +632,8 @@ BPartition::ValidateSetContentName(char *name) const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow() || !name)
|
if (!fPartitionData || !_IsShadow() || !name)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_set_partition_content_name(_ShadowID(), name);
|
return _kern_validate_set_partition_content_name(_ShadowID(),
|
||||||
|
_ChangeCounter(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContentName
|
// SetContentName
|
||||||
@ -630,7 +642,8 @@ BPartition::SetContentName(const char *name)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow() || !name)
|
if (!fPartitionData || !_IsShadow() || !name)
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -641,7 +654,8 @@ bool
|
|||||||
BPartition::CanSetType() const
|
BPartition::CanSetType() const
|
||||||
{
|
{
|
||||||
return (fPartitionData && Parent() && _IsShadow()
|
return (fPartitionData && Parent() && _IsShadow()
|
||||||
&& _kern_supports_setting_partition_type(_ShadowID()));
|
&& _kern_supports_setting_partition_type(_ShadowID(),
|
||||||
|
_ChangeCounter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateSetType
|
// ValidateSetType
|
||||||
@ -650,7 +664,8 @@ BPartition::ValidateSetType(const char *type) const
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_set_partition_type(_ShadowID(), type);
|
return _kern_validate_set_partition_type(_ShadowID(), _ChangeCounter(),
|
||||||
|
type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetType
|
// SetType
|
||||||
@ -659,7 +674,8 @@ BPartition::SetType(const char *type)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow() || !type)
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -670,7 +686,8 @@ bool
|
|||||||
BPartition::CanEditParameters() const
|
BPartition::CanEditParameters() const
|
||||||
{
|
{
|
||||||
return (fPartitionData && Parent() && _IsShadow()
|
return (fPartitionData && Parent() && _IsShadow()
|
||||||
&& _kern_supports_setting_partition_parameters(_ShadowID()));
|
&& _kern_supports_setting_partition_parameters(_ShadowID(),
|
||||||
|
_ChangeCounter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParameterEditor
|
// GetParameterEditor
|
||||||
@ -687,7 +704,9 @@ BPartition::SetParameters(const char *parameters)
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
if (!fPartitionData || IsDevice() || !Parent() || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
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)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -699,7 +718,7 @@ BPartition::CanEditContentParameters(bool *whileMounted) const
|
|||||||
{
|
{
|
||||||
return (fPartitionData && _IsShadow()
|
return (fPartitionData && _IsShadow()
|
||||||
&& _kern_supports_setting_partition_content_parameters(
|
&& _kern_supports_setting_partition_content_parameters(
|
||||||
_ShadowID(), whileMounted));
|
_ShadowID(), _ChangeCounter(), whileMounted));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContentParameterEditor
|
// GetContentParameterEditor
|
||||||
@ -717,6 +736,7 @@ BPartition::SetContentParameters(const char *parameters)
|
|||||||
if (!fPartitionData || !_IsShadow())
|
if (!fPartitionData || !_IsShadow())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
status_t error = _kern_set_partition_content_parameters(_ShadowID(),
|
status_t error = _kern_set_partition_content_parameters(_ShadowID(),
|
||||||
|
_ChangeCounter(),
|
||||||
parameters);
|
parameters);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
@ -728,7 +748,9 @@ bool
|
|||||||
BPartition::CanInitialize(const char *diskSystem) const
|
BPartition::CanInitialize(const char *diskSystem) const
|
||||||
{
|
{
|
||||||
return (fPartitionData && diskSystem && _IsShadow()
|
return (fPartitionData && diskSystem && _IsShadow()
|
||||||
&& _kern_supports_initializing_partition(_ShadowID(), diskSystem));
|
&& _kern_supports_initializing_partition(_ShadowID(),
|
||||||
|
_ChangeCounter(),
|
||||||
|
diskSystem));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInitializationParameterEditor
|
// GetInitializationParameterEditor
|
||||||
@ -747,8 +769,8 @@ BPartition::ValidateInitialize(const char *diskSystem, char *name,
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_initialize_partition(_ShadowID(), diskSystem, name,
|
return _kern_validate_initialize_partition(_ShadowID(), _ChangeCounter(),
|
||||||
parameters);
|
diskSystem, name, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
@ -758,8 +780,8 @@ BPartition::Initialize(const char *diskSystem, const char *name,
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
if (!fPartitionData || !_IsShadow() || !diskSystem || !name)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
status_t error = _kern_initialize_partition(_ShadowID(), diskSystem, name,
|
status_t error = _kern_initialize_partition(_ShadowID(), _ChangeCounter(),
|
||||||
parameters);
|
diskSystem, name, parameters);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
return error;
|
return error;
|
||||||
@ -770,7 +792,8 @@ bool
|
|||||||
BPartition::CanCreateChild() const
|
BPartition::CanCreateChild() const
|
||||||
{
|
{
|
||||||
return (fPartitionData && _IsShadow()
|
return (fPartitionData && _IsShadow()
|
||||||
&& _kern_supports_creating_child_partition(_ShadowID()));
|
&& _kern_supports_creating_child_partition(_ShadowID(),
|
||||||
|
_ChangeCounter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChildCreationParameterEditor
|
// GetChildCreationParameterEditor
|
||||||
@ -789,8 +812,9 @@ BPartition::ValidateCreateChild(off_t *offset, off_t *size, const char *type,
|
|||||||
{
|
{
|
||||||
if (!fPartitionData || !_IsShadow() || !offset || !size || !type)
|
if (!fPartitionData || !_IsShadow() || !offset || !size || !type)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
return _kern_validate_create_child_partition(_ShadowID(), offset, size,
|
return _kern_validate_create_child_partition(_ShadowID(), _ChangeCounter(),
|
||||||
type, parameters);
|
offset, size, type,
|
||||||
|
parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateChild
|
// CreateChild
|
||||||
@ -802,8 +826,9 @@ BPartition::CreateChild(off_t offset, off_t size, const char *type,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
// send the request
|
// send the request
|
||||||
partition_id childID = -1;
|
partition_id childID = -1;
|
||||||
status_t error = _kern_create_child_partition(_ShadowID(), offset, size,
|
status_t error = _kern_create_child_partition(_ShadowID(),
|
||||||
type, parameters, &childID);
|
_ChangeCounter(), offset, size, type, parameters,
|
||||||
|
&childID);
|
||||||
// update the device
|
// update the device
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
@ -822,7 +847,8 @@ BPartition::CanDeleteChild(int32 index) const
|
|||||||
{
|
{
|
||||||
BPartition *child = ChildAt(index);
|
BPartition *child = ChildAt(index);
|
||||||
return (child && child->_IsShadow()
|
return (child && child->_IsShadow()
|
||||||
&& _kern_supports_deleting_child_partition(child->_ShadowID()));
|
&& _kern_supports_deleting_child_partition(child->_ShadowID(),
|
||||||
|
child->_ChangeCounter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteChild
|
// DeleteChild
|
||||||
@ -833,7 +859,8 @@ BPartition::DeleteChild(int32 index)
|
|||||||
if (!fPartitionData || !_IsShadow() || !child)
|
if (!fPartitionData || !_IsShadow() || !child)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
// send the request
|
// send the request
|
||||||
status_t error = _kern_delete_partition(child->_ShadowID());
|
status_t error = _kern_delete_partition(child->_ShadowID(),
|
||||||
|
child->_ChangeCounter());
|
||||||
// update the device
|
// update the device
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = Device()->Update();
|
error = Device()->Update();
|
||||||
@ -902,6 +929,121 @@ BPartition::_Unset()
|
|||||||
fPartitionData = NULL;
|
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
|
// _IsShadow
|
||||||
bool
|
bool
|
||||||
BPartition::_IsShadow() const
|
BPartition::_IsShadow() const
|
||||||
@ -923,6 +1065,13 @@ BPartition::_DiskSystem() const
|
|||||||
return (fPartitionData ? fPartitionData->disk_system : -1);
|
return (fPartitionData ? fPartitionData->disk_system : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _ChangeCounter
|
||||||
|
int32
|
||||||
|
BPartition::_ChangeCounter() const
|
||||||
|
{
|
||||||
|
return (fPartitionData ? fPartitionData->change_counter : -1);
|
||||||
|
}
|
||||||
|
|
||||||
// _CountDescendants
|
// _CountDescendants
|
||||||
int32
|
int32
|
||||||
BPartition::_CountDescendants() const
|
BPartition::_CountDescendants() const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user