* Reimplemented BDiskDevice::IsModified()/

{Prepare,Commit,Cancel}Modifications() using the userland add-on
  backend. IsModified() and CommitModifications() are little more than
  stubs ATM.
* Made BPartition::VisitEachChild()/VisitEachDescendant() const.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22602 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-10-17 21:50:20 +00:00
parent e4289a54e3
commit 27d7c36659
3 changed files with 132 additions and 31 deletions

View File

@ -76,9 +76,10 @@ public:
status_t GetPartitioningInfo(
BPartitioningInfo* info) const;
BPartition* VisitEachChild(BDiskDeviceVisitor* visitor);
BPartition* VisitEachChild(BDiskDeviceVisitor* visitor)
const;
virtual BPartition* VisitEachDescendant(
BDiskDeviceVisitor* visitor);
BDiskDeviceVisitor* visitor) const;
// Self Modification
@ -205,6 +206,11 @@ private:
bool _SupportsChildOperation(const BPartition* child,
uint32 flag) const;
status_t _CreateDelegates();
status_t _InitDelegates();
void _DeleteDelegates();
bool _IsModified() const;
friend class BDiskDevice;
friend class BDiskSystem;
friend class BMutablePartition;

View File

@ -188,8 +188,22 @@ BDiskDevice::GetPath(BPath* path) const
bool
BDiskDevice::IsModified() const
{
return (InitCheck() == B_OK && _IsShadow()
&& _kern_is_disk_device_modified(ID()));
if (InitCheck() != B_OK)
return false;
struct IsModifiedVisitor : public BDiskDeviceVisitor {
virtual bool Visit(BDiskDevice *device)
{
return Visit(device, 0);
}
virtual bool Visit(BPartition *partition, int32 level)
{
return partition->_IsModified();
}
} visitor;
return (VisitEachDescendant(&visitor) != NULL);
}
@ -209,20 +223,19 @@ BDiskDevice::PrepareModifications()
status_t error = InitCheck();
if (error != B_OK)
return error;
if (_IsShadow())
return B_ERROR;
if (fDelegate)
return B_BAD_VALUE;
// ask kernel to prepare for modifications
error = _kern_prepare_disk_device_modifications(ID());
// recursively create the delegates
error = _CreateDelegates();
// init them
if (error == B_OK)
error = _InitDelegates();
// delete all of them, if something went wrong
if (error != B_OK)
return error;
// update
error = _Update(true, NULL);
if (error != B_OK) {
// bad -- cancelling the modifications is all we can do
_kern_cancel_disk_device_modifications(ID());
}
_DeleteDelegates();
return error;
}
@ -242,15 +255,14 @@ BDiskDevice::CommitModifications(bool synchronously,
status_t error = InitCheck();
if (error != B_OK)
return error;
if (!_IsShadow())
if (!fDelegate)
return B_BAD_VALUE;
// TODO: Get port and token from the progressMessenger
// TODO: Respect "synchronously"!
port_id port = -1;
int32 token = -1;
error = _kern_commit_disk_device_modifications(ID(), port, token,
receiveCompleteProgressUpdates);
// TODO: Implement!
_DeleteDelegates();
if (error == B_OK)
error = _SetTo(ID(), true, false, 0);
@ -269,10 +281,12 @@ BDiskDevice::CancelModifications()
status_t error = InitCheck();
if (error != B_OK)
return error;
if (!_IsShadow())
if (!fDelegate)
return B_BAD_VALUE;
error = _kern_cancel_disk_device_modifications(ID());
_DeleteDelegates();
if (error == B_OK)
error = _SetTo(ID(), true, false, 0);
@ -317,8 +331,7 @@ BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow,
status_t error = B_OK;
do {
error = _kern_get_disk_device_data(id, deviceOnly, shadow,
(user_disk_device_data*)buffer,
bufferSize, &neededSize);
(user_disk_device_data*)buffer, bufferSize, &neededSize);
if (error == B_BUFFER_OVERFLOW) {
// buffer to small re-allocate it
if (buffer)
@ -346,7 +359,7 @@ BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow,
// _SetTo
status_t
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
size_t neededSize)
size_t neededSize)
{
Unset();

View File

@ -641,7 +641,7 @@ BPartition::GetPartitioningInfo(BPartitioningInfo* info) const
// VisitEachChild
BPartition*
BPartition::VisitEachChild(BDiskDeviceVisitor* visitor)
BPartition::VisitEachChild(BDiskDeviceVisitor* visitor) const
{
if (visitor) {
int32 level = _Level();
@ -656,10 +656,10 @@ BPartition::VisitEachChild(BDiskDeviceVisitor* visitor)
// VisitEachDescendant
BPartition*
BPartition::VisitEachDescendant(BDiskDeviceVisitor* visitor)
BPartition::VisitEachDescendant(BDiskDeviceVisitor* visitor) const
{
if (visitor)
return _VisitEachDescendant(visitor);
return const_cast<BPartition*>(this)->_VisitEachDescendant(visitor);
return NULL;
}
@ -1500,3 +1500,85 @@ BPartition::_SupportsChildOperation(const BPartition* child, uint32 flag) const
return supported & flag;
}
// _CreateDelegates
status_t
BPartition::_CreateDelegates()
{
if (fDelegate || !fPartitionData)
return B_BAD_VALUE;
// create and init delegate
fDelegate = new(nothrow) Delegate(this);
if (!fDelegate)
return B_NO_MEMORY;
status_t error = fDelegate->InitHierarchy(fPartitionData,
fParent ? fParent->fDelegate : NULL);
if (error != B_OK)
return error;
// create child delegates
int32 count = fPartitionData->child_count;
for (int32 i = 0; i < count; i++) {
BPartition* child = (BPartition*)fPartitionData->children[i]->user_data;
error = child->_CreateDelegates();
if (error != B_OK)
return error;
}
return B_OK;
}
// _InitDelegates
status_t
BPartition::_InitDelegates()
{
// init delegate
status_t error = fDelegate->InitAfterHierarchy();
if (error != B_OK)
return error;
// recursively init child delegates
int32 count = CountChildren();
for (int32 i = 0; i < count; i++) {
error = ChildAt(i)->_InitDelegates();
if (error != B_OK)
return error;
}
return B_OK;
}
// _DeleteDelegates
void
BPartition::_DeleteDelegates()
{
// recursively delete child delegates
int32 count = CountChildren();
for (int32 i = count - 1; i >= 0; i--)
ChildAt(i)->_DeleteDelegates();
// delete delegate
delete fDelegate;
fDelegate = NULL;
// Commit suicide, if the delegate was our only link to reality (i.e.
// there's no physically existing partition we represent).
if (fPartitionData == NULL)
delete this;
}
// _IsModified
bool
BPartition::_IsModified() const
{
if (!fDelegate)
return false;
// TODO: Implement!
return false;
}