partitioning: pass along reference to parent when uninitializing.

* Fixes problems with setting the partition name after uninitializing
  a partition in DriveSetup. Previously, UninitializeJob() was
  followed by SetStringJob(), but the kernel was updating the
  change counter for the parent partition when uninitializing a
  partition, leading to SetStringJob() having an incorrect change
  counter for the parent partition. Now the parent change counter
  will be correct when SetStringJob() runs.
This commit is contained in:
Jessica Hamilton
2016-12-23 18:53:15 +13:00
parent 9ba5f87313
commit 4419d699ec
9 changed files with 62 additions and 21 deletions
+2 -1
View File
@@ -397,7 +397,8 @@ extern status_t _kern_initialize_partition(partition_id partitionID,
const char *name, const char *parameters, const char *name, const char *parameters,
size_t parametersSize); size_t parametersSize);
extern status_t _kern_uninitialize_partition(partition_id partitionID, extern status_t _kern_uninitialize_partition(partition_id partitionID,
int32 changeCounter); int32 changeCounter, partition_id parentID,
int32 parentChangeCounter);
extern status_t _kern_create_child_partition(partition_id partitionID, extern status_t _kern_create_child_partition(partition_id partitionID,
int32 changeCounter, off_t offset, off_t size, const char *type, int32 changeCounter, off_t offset, off_t size, const char *type,
const char *parameters, size_t parametersSize, const char *parameters, size_t parametersSize,
@@ -109,12 +109,15 @@ class AutoLockerPartitionRegistration {
public: public:
inline bool Lock(KPartition *partition) inline bool Lock(KPartition *partition)
{ {
if (partition == NULL)
return true;
partition->Register(); partition->Register();
return true; return true;
} }
inline void Unlock(KPartition *partition) inline void Unlock(KPartition *partition)
{ {
if (partition != NULL)
partition->Unregister(); partition->Unregister();
} }
}; };
@@ -77,7 +77,8 @@ status_t _user_initialize_partition(partition_id partitionID,
int32* changeCounter, const char* diskSystemName, int32* changeCounter, const char* diskSystemName,
const char* name, const char* parameters); const char* name, const char* parameters);
status_t _user_uninitialize_partition(partition_id partitionID, status_t _user_uninitialize_partition(partition_id partitionID,
int32* changeCounter); int32* changeCounter, partition_id parentID,
int32* parentChangeCounter);
status_t _user_create_child_partition(partition_id partitionID, status_t _user_create_child_partition(partition_id partitionID,
int32* changeCounter, off_t offset, off_t size, int32* changeCounter, off_t offset, off_t size,
+2 -1
View File
@@ -617,7 +617,8 @@ extern status_t _kern_initialize_partition(partition_id partitionID,
int32* changeCounter, const char* diskSystemName, int32* changeCounter, const char* diskSystemName,
const char* name, const char* parameters); const char* name, const char* parameters);
extern status_t _kern_uninitialize_partition(partition_id partitionID, extern status_t _kern_uninitialize_partition(partition_id partitionID,
int32* changeCounter); int32* changeCounter, partition_id parentID,
int32* parentChangeCounter);
extern status_t _kern_create_child_partition(partition_id partitionID, extern status_t _kern_create_child_partition(partition_id partitionID,
int32* changeCounter, off_t offset, off_t size, int32* changeCounter, off_t offset, off_t size,
const char* type, const char* name, const char* type, const char* name,
+2 -1
View File
@@ -374,7 +374,8 @@ _kern_initialize_partition(partition_id partitionID, int32 changeCounter,
status_t status_t
_kern_uninitialize_partition(partition_id partitionID, int32 changeCounter) _kern_uninitialize_partition(partition_id partitionID, int32 changeCounter,
partition_id parentID, int32 parentChangeCounter)
{ {
return B_ERROR; return B_ERROR;
} }
@@ -523,7 +523,15 @@ DiskDeviceJobGenerator::_GenerateUninitializeJob(BPartition* partition)
if (error != B_OK) if (error != B_OK)
return error; return error;
return _AddJob(new(nothrow) UninitializeJob(reference)); BPartition* parent = partition->Parent();
PartitionReference* parentReference = NULL;
if (parent != NULL) {
error = _GetPartitionReference(parent, parentReference);
if (error != B_OK)
return error;
}
return _AddJob(new(nothrow) UninitializeJob(reference, parentReference));
} }
@@ -11,8 +11,9 @@
// constructor // constructor
UninitializeJob::UninitializeJob(PartitionReference* partition) UninitializeJob::UninitializeJob(PartitionReference* partition,
: DiskDeviceJob(partition) PartitionReference* parent)
: DiskDeviceJob(parent, partition)
{ {
} }
@@ -27,14 +28,20 @@ UninitializeJob::~UninitializeJob()
status_t status_t
UninitializeJob::Do() UninitializeJob::Do()
{ {
int32 changeCounter = fPartition->ChangeCounter(); bool haveParent = fPartition != NULL;
status_t error = _kern_uninitialize_partition(fPartition->PartitionID(), int32 changeCounter = fChild->ChangeCounter();
&changeCounter); int32 parentChangeCounter = haveParent ? fPartition->ChangeCounter() : 0;
partition_id parentID = haveParent ? fPartition->PartitionID() : -1;
status_t error = _kern_uninitialize_partition(fChild->PartitionID(),
&changeCounter, parentID, &parentChangeCounter);
if (error != B_OK) if (error != B_OK)
return error; return error;
fPartition->SetChangeCounter(changeCounter); fChild->SetChangeCounter(changeCounter);
if (haveParent)
fPartition->SetChangeCounter(parentChangeCounter);
return B_OK; return B_OK;
} }
@@ -14,7 +14,8 @@ namespace BPrivate {
class UninitializeJob : public DiskDeviceJob { class UninitializeJob : public DiskDeviceJob {
public: public:
UninitializeJob(PartitionReference* partition); UninitializeJob(PartitionReference* partition,
PartitionReference* parent = NULL);
virtual ~UninitializeJob(); virtual ~UninitializeJob();
virtual status_t Do(); virtual status_t Do();
@@ -1218,14 +1218,20 @@ _user_initialize_partition(partition_id partitionID, int32* _changeCounter,
status_t status_t
_user_uninitialize_partition(partition_id partitionID, int32* _changeCounter) _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter,
partition_id parentID, int32* _parentChangeCounter)
{ {
// copy parameters in // copy parameters in
int32 changeCounter; int32 changeCounter;
int32 parentChangeCounter;
bool haveParent = parentID >= 0;
status_t error; status_t error;
if ((error = copy_from_user_value(changeCounter, _changeCounter)) != B_OK) if ((error = copy_from_user_value(changeCounter, _changeCounter)) != B_OK)
return error; return error;
if (haveParent && (error = copy_from_user_value(parentChangeCounter,
_parentChangeCounter)) != B_OK)
return error;
// get the partition // get the partition
KDiskDeviceManager* manager = KDiskDeviceManager::Default(); KDiskDeviceManager* manager = KDiskDeviceManager::Default();
@@ -1237,9 +1243,18 @@ _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter)
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true);
// register parent
KPartition* parent = NULL;
if (haveParent)
parent = manager->RegisterPartition(parentID);
PartitionRegistrar registrar3(parent, true);
// check change counter // check change counter
if (changeCounter != partition->ChangeCounter()) if (changeCounter != partition->ChangeCounter())
return B_BAD_VALUE; return B_BAD_VALUE;
if (haveParent && parentChangeCounter != parent->ChangeCounter())
return B_BAD_VALUE;
// the partition must be initialized // the partition must be initialized
if (!partition->DiskSystem()) if (!partition->DiskSystem())
@@ -1275,6 +1290,9 @@ _user_uninitialize_partition(partition_id partitionID, int32* _changeCounter)
error = copy_to_user_value(_changeCounter, partition->ChangeCounter()); error = copy_to_user_value(_changeCounter, partition->ChangeCounter());
if (error != B_OK) if (error != B_OK)
return error; return error;
if (haveParent && (error = copy_to_user_value(_parentChangeCounter,
parent->ChangeCounter())) != B_OK)
return error;
return B_OK; return B_OK;
} }