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:
@@ -194,7 +194,7 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// extern status_t _kern_set_timezone(int32 timezoneOffset, bool daylightSavingTime);
|
// extern status_t _kern_set_timezone(int32 timezoneOffset, bool daylightSavingTime);
|
||||||
// extern status_t _kern_set_tzfilename(const char *filename, size_t length, bool isGMT);
|
// extern status_t _kern_set_tzfilename(const char *filename, size_t length, bool isGMT);
|
||||||
// extern status_t _kern_get_tzfilename(char *filename, size_t length, bool *_isGMT);
|
// extern status_t _kern_get_tzfilename(char *filename, size_t length, bool *_isGMT);
|
||||||
//
|
//
|
||||||
// extern bigtime_t _kern_system_time();
|
// extern bigtime_t _kern_system_time();
|
||||||
// extern status_t _kern_snooze_etc(bigtime_t time, int timebase, int32 flags);
|
// extern status_t _kern_snooze_etc(bigtime_t time, int timebase, int32 flags);
|
||||||
|
|
||||||
@@ -210,10 +210,10 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// extern area_id _kern_transfer_area(area_id area, void **_address, uint32 addressSpec,
|
// extern area_id _kern_transfer_area(area_id area, void **_address, uint32 addressSpec,
|
||||||
// team_id target);
|
// team_id target);
|
||||||
// extern status_t _kern_set_area_protection(area_id area, uint32 newProtection);
|
// extern status_t _kern_set_area_protection(area_id area, uint32 newProtection);
|
||||||
// extern area_id _kern_clone_area(const char *name, void **_address, uint32 addressSpec,
|
// extern area_id _kern_clone_area(const char *name, void **_address, uint32 addressSpec,
|
||||||
// uint32 protection, area_id sourceArea);
|
// uint32 protection, area_id sourceArea);
|
||||||
// extern status_t _kern_init_heap_address_range(addr_t base, addr_t size);
|
// extern status_t _kern_init_heap_address_range(addr_t base, addr_t size);
|
||||||
//
|
//
|
||||||
// area_id sys_vm_map_file(const char *name, void **address, int addr_type,
|
// area_id sys_vm_map_file(const char *name, void **address, int addr_type,
|
||||||
// addr_t size, int lock, int mapping, const char *path, off_t offset);
|
// addr_t size, int lock, int mapping, const char *path, off_t offset);
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// debug support functions
|
// debug support functions
|
||||||
// extern void _kern_debugger(const char *message);
|
// extern void _kern_debugger(const char *message);
|
||||||
// extern int _kern_disable_debugger(int state);
|
// extern int _kern_disable_debugger(int state);
|
||||||
//
|
//
|
||||||
// extern status_t _kern_install_default_debugger(port_id debuggerPort);
|
// extern status_t _kern_install_default_debugger(port_id debuggerPort);
|
||||||
// extern port_id _kern_install_team_debugger(team_id team,
|
// extern port_id _kern_install_team_debugger(team_id team,
|
||||||
// port_id debuggerPort);
|
// port_id debuggerPort);
|
||||||
@@ -252,7 +252,7 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// extern int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst);
|
// extern int32 _kern_atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst);
|
||||||
// extern int32 _kern_atomic_add(vint32 *value, int32 addValue);
|
// extern int32 _kern_atomic_add(vint32 *value, int32 addValue);
|
||||||
// extern int32 _kern_atomic_and(vint32 *value, int32 andValue);
|
// extern int32 _kern_atomic_and(vint32 *value, int32 andValue);
|
||||||
// extern int32 _kern_atomic_or(vint32 *value, int32 orValue);
|
// extern int32 _kern_atomic_or(vint32 *value, int32 orValue);
|
||||||
// extern int32 _kern_atomic_get(vint32 *value);
|
// extern int32 _kern_atomic_get(vint32 *value);
|
||||||
// #endif // ATOMIC_FUNCS_ARE_SYSCALLS
|
// #endif // ATOMIC_FUNCS_ARE_SYSCALLS
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// extern int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst);
|
// extern int64 _kern_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst);
|
||||||
// extern int64 _kern_atomic_add64(vint64 *value, int64 addValue);
|
// extern int64 _kern_atomic_add64(vint64 *value, int64 addValue);
|
||||||
// extern int64 _kern_atomic_and64(vint64 *value, int64 andValue);
|
// extern int64 _kern_atomic_and64(vint64 *value, int64 andValue);
|
||||||
// extern int64 _kern_atomic_or64(vint64 *value, int64 orValue);
|
// extern int64 _kern_atomic_or64(vint64 *value, int64 orValue);
|
||||||
// extern int64 _kern_atomic_get64(vint64 *value);
|
// extern int64 _kern_atomic_get64(vint64 *value);
|
||||||
// #endif // ATOMIC64_FUNCS_ARE_SYSCALLS
|
// #endif // ATOMIC64_FUNCS_ARE_SYSCALLS
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ extern status_t _kern_unlock_node(int fd);
|
|||||||
// extern area_id _kern_register_messaging_service(sem_id lockingSem,
|
// extern area_id _kern_register_messaging_service(sem_id lockingSem,
|
||||||
// sem_id counterSem);
|
// sem_id counterSem);
|
||||||
// extern status_t _kern_unregister_messaging_service();
|
// extern status_t _kern_unregister_messaging_service();
|
||||||
//
|
//
|
||||||
// extern void _kern_clear_caches(void *address, size_t length, uint32 flags);
|
// extern void _kern_clear_caches(void *address, size_t length, uint32 flags);
|
||||||
|
|
||||||
// #ifdef __INTEL__
|
// #ifdef __INTEL__
|
||||||
@@ -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,13 +109,16 @@ 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)
|
||||||
{
|
{
|
||||||
partition->Unregister();
|
if (partition != NULL)
|
||||||
|
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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user