Finished up most of remaining kernel-saftey stuff, and fixed previously "safe" code that accessed userland memory directly.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5133 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Tyler Dauwalder
2003-10-24 09:37:20 +00:00
parent 0d2558589a
commit 27b54f4499
@@ -66,7 +66,8 @@ _kern_get_next_disk_device_id(int32 *_cookie, size_t *neededSize)
{ {
if (!_cookie) if (!_cookie)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 cookie = *_cookie; int32 cookie;
user_memcpy(&cookie, _cookie, sizeof(cookie));
partition_id id = B_ENTRY_NOT_FOUND; partition_id id = B_ENTRY_NOT_FOUND;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
@@ -85,7 +86,7 @@ _kern_get_next_disk_device_id(int32 *_cookie, size_t *neededSize)
} }
} }
} }
*_cookie = cookie; user_memcpy(_cookie, &cookie, sizeof(cookie));
return id; return id;
} }
@@ -284,7 +285,7 @@ _kern_get_partitionable_spaces(partition_id partitionID, int32 changeCounter,
error = diskSystem->GetPartitionableSpaces(partition, buffer, error = diskSystem->GetPartitionableSpaces(partition, buffer,
count, &actualCount); count, &actualCount);
if (!error && _actualCount) if (!error && _actualCount)
*_actualCount = actualCount; user_memcpy(_actualCount, &actualCount, sizeof(actualCount));
} }
} }
} }
@@ -355,7 +356,8 @@ _kern_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info)
{ {
if (!_cookie || !_info) if (!_cookie || !_info)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 cookie = *_cookie; int32 cookie;
user_memcpy(&cookie, _cookie, sizeof(cookie));
status_t result = B_ENTRY_NOT_FOUND; status_t result = B_ENTRY_NOT_FOUND;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
if (ManagerLocker locker = manager) { if (ManagerLocker locker = manager) {
@@ -367,7 +369,7 @@ _kern_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info)
result = B_OK; result = B_OK;
} }
} }
*_cookie = cookie; user_memcpy(_cookie, &cookie, sizeof(cookie));
return result; return result;
} }
@@ -410,7 +412,7 @@ _kern_supports_defragmenting_partition(partition_id partitionID,
bool result = validate_defragment_partition(partition, changeCounter, bool result = validate_defragment_partition(partition, changeCounter,
&whileMounted) == B_OK; &whileMounted) == B_OK;
if (result && _whileMounted) if (result && _whileMounted)
*_whileMounted = whileMounted; user_memcpy(_whileMounted, &whileMounted, sizeof(whileMounted));
return result; return result;
} }
@@ -432,14 +434,14 @@ _kern_supports_repairing_partition(partition_id partitionID,
bool result = validate_repair_partition(partition, changeCounter, checkOnly, bool result = validate_repair_partition(partition, changeCounter, checkOnly,
&whileMounted) == B_OK; &whileMounted) == B_OK;
if (result && _whileMounted) if (result && _whileMounted)
*_whileMounted = whileMounted; user_memcpy(_whileMounted, &whileMounted, sizeof(whileMounted));
return result; return result;
} }
// _kern_supports_resizing_partition // _kern_supports_resizing_partition
bool bool
_kern_supports_resizing_partition(partition_id partitionID, _kern_supports_resizing_partition(partition_id partitionID,
int32 changeCounter, bool *canResizeContents, int32 changeCounter, bool *_canResizeContents,
bool *_whileMounted) bool *_whileMounted)
{ {
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
@@ -467,12 +469,13 @@ _kern_supports_resizing_partition(partition_id partitionID,
return false; return false;
// get the child disk system // get the child disk system
KDiskSystem *childDiskSystem = partition->DiskSystem(); KDiskSystem *childDiskSystem = partition->DiskSystem();
if (canResizeContents) { if (_canResizeContents) {
bool whileMounted; bool whileMounted;
*canResizeContents = (childDiskSystem bool canResizeContents = (childDiskSystem
&& childDiskSystem->SupportsResizing(partition, &whileMounted)); && childDiskSystem->SupportsResizing(partition, &whileMounted));
user_memcpy(_canResizeContents, &canResizeContents, sizeof(canResizeContents));
if (_whileMounted) if (_whileMounted)
*_whileMounted = whileMounted; user_memcpy(_whileMounted, &whileMounted, sizeof(whileMounted));
} }
// TODO: Currently we report that we cannot resize the contents, if the // TODO: Currently we report that we cannot resize the contents, if the
// partition's disk system is unknown. I found this more logical. It doesn't // partition's disk system is unknown. I found this more logical. It doesn't
@@ -578,7 +581,7 @@ _kern_supports_setting_partition_content_name(partition_id partitionID,
bool whileMounted; bool whileMounted;
bool result = diskSystem->SupportsSettingContentName(partition, &whileMounted); bool result = diskSystem->SupportsSettingContentName(partition, &whileMounted);
if (result && _whileMounted) if (result && _whileMounted)
*_whileMounted = whileMounted; user_memcpy(_whileMounted, &whileMounted, sizeof(whileMounted));
return result; return result;
} }
@@ -667,7 +670,7 @@ _kern_supports_setting_partition_content_parameters(partition_id partitionID,
bool result = diskSystem->SupportsSettingContentParameters(partition, bool result = diskSystem->SupportsSettingContentParameters(partition,
&whileMounted); &whileMounted);
if (result && _whileMounted) if (result && _whileMounted)
*_whileMounted = whileMounted; user_memcpy(_whileMounted, &whileMounted, sizeof(whileMounted));
return result; return result;
} }
@@ -775,7 +778,8 @@ _kern_validate_resize_partition(partition_id partitionID, int32 changeCounter,
{ {
if (!_size) if (!_size)
return B_BAD_VALUE; return B_BAD_VALUE;
off_t size = *_size; off_t size;
user_memcpy(&size, _size, sizeof(size));
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
@@ -788,17 +792,19 @@ _kern_validate_resize_partition(partition_id partitionID, int32 changeCounter,
bool result = validate_resize_partition(partition, changeCounter, &size, bool result = validate_resize_partition(partition, changeCounter, &size,
&contentSize); &contentSize);
if (result) if (result)
*_size = size; user_memcpy(_size, &size, sizeof(size));
return result; return result;
} }
// _kern_validate_move_partition // _kern_validate_move_partition
status_t status_t
_kern_validate_move_partition(partition_id partitionID, int32 changeCounter, _kern_validate_move_partition(partition_id partitionID, int32 changeCounter,
off_t *newOffset) off_t *_newOffset)
{ {
if (!newOffset) if (!_newOffset)
return B_BAD_VALUE; return B_BAD_VALUE;
off_t newOffset;
user_memcpy(&newOffset, _newOffset, sizeof(newOffset));
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
@@ -807,16 +813,22 @@ _kern_validate_move_partition(partition_id partitionID, int32 changeCounter,
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceReadLocker locker(partition->Device(), true); DeviceReadLocker locker(partition->Device(), true);
return validate_move_partition(partition, changeCounter, newOffset); status_t result = validate_move_partition(partition, changeCounter, &newOffset);
if (result)
user_memcpy(_newOffset, &newOffset, sizeof(newOffset));
return result;
} }
// _kern_validate_set_partition_name // _kern_validate_set_partition_name
status_t status_t
_kern_validate_set_partition_name(partition_id partitionID, _kern_validate_set_partition_name(partition_id partitionID,
int32 changeCounter, char *name) int32 changeCounter, char *_name)
{ {
if (!name) if (!_name)
return B_BAD_VALUE; return B_BAD_VALUE;
char name[B_OS_NAME_LENGTH];
if (user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
@@ -831,10 +843,13 @@ _kern_validate_set_partition_name(partition_id partitionID,
// _kern_validate_set_partition_content_name // _kern_validate_set_partition_content_name
status_t status_t
_kern_validate_set_partition_content_name(partition_id partitionID, _kern_validate_set_partition_content_name(partition_id partitionID,
int32 changeCounter, char *name) int32 changeCounter, char *_name)
{ {
if (!name) if (!_name)
return B_BAD_VALUE; return B_BAD_VALUE;
char name[B_OS_NAME_LENGTH];
if (user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
@@ -849,11 +864,12 @@ _kern_validate_set_partition_content_name(partition_id partitionID,
// _kern_validate_set_partition_type // _kern_validate_set_partition_type
status_t status_t
_kern_validate_set_partition_type(partition_id partitionID, _kern_validate_set_partition_type(partition_id partitionID,
int32 changeCounter, const char *type) int32 changeCounter, const char *_type)
{ {
if (!type) if (!_type)
return B_BAD_VALUE; return B_BAD_VALUE;
if (strnlen(type, B_OS_NAME_LENGTH) == B_OS_NAME_LENGTH) char type[B_OS_NAME_LENGTH];
if (user_strlcpy(type, _type, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
@@ -870,79 +886,131 @@ _kern_validate_set_partition_type(partition_id partitionID,
status_t status_t
_kern_validate_initialize_partition(partition_id partitionID, _kern_validate_initialize_partition(partition_id partitionID,
int32 changeCounter, int32 changeCounter,
const char *diskSystemName, char *name, const char *_diskSystemName, char *_name,
const char *parameters) const char *_parameters)
{ {
if (!diskSystemName || !name) if (!_diskSystemName || !_name)
return B_BAD_VALUE; return B_BAD_VALUE;
char diskSystemName[B_OS_NAME_LENGTH];
char name[B_OS_NAME_LENGTH];
char *parameters = NULL;
if (user_strlcpy(diskSystemName, _diskSystemName, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH
|| user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceReadLocker locker(partition->Device(), true); DeviceReadLocker locker(partition->Device(), true);
return validate_initialize_partition(partition, changeCounter, error = validate_initialize_partition(partition, changeCounter,
diskSystemName, name, parameters); diskSystemName, name, parameters);
} }
free(parameters);
return error;
}
// _kern_validate_create_child_partition // _kern_validate_create_child_partition
status_t status_t
_kern_validate_create_child_partition(partition_id partitionID, _kern_validate_create_child_partition(partition_id partitionID,
int32 changeCounter, off_t *offset, int32 changeCounter, off_t *_offset,
off_t *size, const char *type, off_t *_size, const char *_type,
const char *parameters) const char *_parameters)
{ {
if (!offset || !size || !type) if (!_offset || !_size || !_type)
return B_BAD_VALUE; return B_BAD_VALUE;
off_t offset;
off_t size;
char type[B_OS_NAME_LENGTH];
char *parameters = NULL;
user_memcpy(&offset, _offset, sizeof(offset));
user_memcpy(&size, _size, sizeof(size));
if (user_strlcpy(type, _type, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceReadLocker locker(partition->Device(), true); DeviceReadLocker locker(partition->Device(), true);
return validate_create_child_partition(partition, changeCounter, offset, error = validate_create_child_partition(partition, changeCounter, &offset,
size, type, parameters); &size, type, parameters);
}
if (!error) {
user_memcpy(_offset, &offset, sizeof(offset));
user_memcpy(_size, &size, sizeof(size));
}
free(parameters);
return error;
} }
// _kern_get_next_supported_partition_type // _kern_get_next_supported_partition_type
status_t status_t
_kern_get_next_supported_partition_type(partition_id partitionID, _kern_get_next_supported_partition_type(partition_id partitionID,
int32 changeCounter, int32 *cookie, int32 changeCounter, int32 *_cookie,
char *type) char *_type)
{ {
if (!cookie || !type) if (!_cookie || !_type)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 cookie;
user_memcpy(&cookie, _cookie, sizeof(cookie));
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->ReadLockPartition(partitionID); KPartition *partition = manager->ReadLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceReadLocker locker(partition->Device(), true); DeviceReadLocker locker(partition->Device(), true);
if (!check_shadow_partition(partition, changeCounter)) error = check_shadow_partition(partition, changeCounter) ? B_OK : B_BAD_VALUE;
return B_BAD_VALUE; if (!error) {
// get the disk system // get the disk system
KDiskSystem *diskSystem = partition->DiskSystem(); KDiskSystem *diskSystem = partition->DiskSystem();
if (!diskSystem) error = diskSystem ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
// get the info // get the info
if (diskSystem->GetNextSupportedType(partition, cookie, type)) char type[B_OS_NAME_LENGTH];
return B_OK; error = diskSystem->GetNextSupportedType(partition, &cookie, type);
return B_ERROR; if (!error) {
error = user_strlcpy(_type, type, B_OS_NAME_LENGTH) < B_OS_NAME_LENGTH
? B_OK : B_NAME_TOO_LONG;
}
}
}
}
if (!error)
user_memcpy(_cookie, &cookie, sizeof(cookie));
return error;
} }
// _kern_get_partition_type_for_content_type // _kern_get_partition_type_for_content_type
status_t status_t
_kern_get_partition_type_for_content_type(disk_system_id diskSystemID, _kern_get_partition_type_for_content_type(disk_system_id diskSystemID,
const char *contentType, char *type) const char *_contentType, char *_type)
{ {
if (!contentType || !type) if (!_contentType || !_type)
return B_BAD_VALUE; return B_BAD_VALUE;
char contentType[B_OS_NAME_LENGTH];
if (user_strlcpy(contentType, _contentType, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the disk system // get the disk system
KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemID); KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemID);
@@ -950,8 +1018,11 @@ _kern_get_partition_type_for_content_type(disk_system_id diskSystemID,
return false; return false;
DiskSystemLoader loader(diskSystem, true); DiskSystemLoader loader(diskSystem, true);
// get the info // get the info
if (diskSystem->GetTypeForContentType(contentType, type)) char type[B_OS_NAME_LENGTH];
if (diskSystem->GetTypeForContentType(contentType, type)) {
user_strlcpy(_type, type, B_OS_NAME_LENGTH);
return B_OK; return B_OK;
}
return B_ERROR; return B_ERROR;
} }
@@ -1168,11 +1239,12 @@ _kern_move_partition(partition_id partitionID, int32 changeCounter,
// _kern_set_partition_name // _kern_set_partition_name
status_t status_t
_kern_set_partition_name(partition_id partitionID, int32 changeCounter, _kern_set_partition_name(partition_id partitionID, int32 changeCounter,
const char *name) const char *_name)
{ {
if (!name) if (!_name)
return B_BAD_VALUE; return B_BAD_VALUE;
if (strnlen(name, B_OS_NAME_LENGTH) == B_OS_NAME_LENGTH) char name[B_OS_NAME_LENGTH];
if (user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
@@ -1204,11 +1276,12 @@ _kern_set_partition_name(partition_id partitionID, int32 changeCounter,
// _kern_set_partition_content_name // _kern_set_partition_content_name
status_t status_t
_kern_set_partition_content_name(partition_id partitionID, int32 changeCounter, _kern_set_partition_content_name(partition_id partitionID, int32 changeCounter,
const char *name) const char *_name)
{ {
if (!name) if (!_name)
return B_BAD_VALUE; return B_BAD_VALUE;
if (strnlen(name, B_OS_NAME_LENGTH) == B_OS_NAME_LENGTH) char name[B_OS_NAME_LENGTH];
if (user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
@@ -1240,11 +1313,12 @@ _kern_set_partition_content_name(partition_id partitionID, int32 changeCounter,
// _kern_set_partition_type // _kern_set_partition_type
status_t status_t
_kern_set_partition_type(partition_id partitionID, int32 changeCounter, _kern_set_partition_type(partition_id partitionID, int32 changeCounter,
const char *type) const char *_type)
{ {
if (!type) if (!_type)
return B_BAD_VALUE; return B_BAD_VALUE;
if (strnlen(type, B_OS_NAME_LENGTH) == B_OS_NAME_LENGTH) char type[B_OS_NAME_LENGTH];
if (user_strlcpy(type, _type, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
@@ -1272,111 +1346,151 @@ _kern_set_partition_type(partition_id partitionID, int32 changeCounter,
// _kern_set_partition_parameters // _kern_set_partition_parameters
status_t status_t
_kern_set_partition_parameters(partition_id partitionID, int32 changeCounter, _kern_set_partition_parameters(partition_id partitionID, int32 changeCounter,
const char *parameters) const char *_parameters)
{ {
if (!parameters) if (!_parameters)
return B_BAD_VALUE; return B_BAD_VALUE;
char *parameters = NULL;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->WriteLockPartition(partitionID); KPartition *partition = manager->WriteLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true);
// check parameters // check parameters
status_t error = validate_set_partition_parameters(partition, error = validate_set_partition_parameters(partition,
changeCounter, parameters); changeCounter, parameters);
if (error != B_OK) if (!error) {
return error;
// set type // set type
error = partition->SetParameters(parameters); error = partition->SetParameters(parameters);
if (error != B_OK) if (!error) {
return error;
partition->Changed(B_PARTITION_CHANGED_PARAMETERS); partition->Changed(B_PARTITION_CHANGED_PARAMETERS);
// implicit partitioning system changes // implicit partitioning system changes
return partition->Parent()->DiskSystem()->ShadowPartitionChanged( error = partition->Parent()->DiskSystem()->ShadowPartitionChanged(
partition, B_PARTITION_SET_PARAMETERS); partition, B_PARTITION_SET_PARAMETERS);
} }
}
}
free(parameters);
return error;
}
// _kern_set_partition_content_parameters // _kern_set_partition_content_parameters
status_t status_t
_kern_set_partition_content_parameters(partition_id partitionID, _kern_set_partition_content_parameters(partition_id partitionID,
int32 changeCounter, int32 changeCounter,
const char *parameters) const char *_parameters)
{ {
if (!_parameters)
return B_BAD_VALUE;
char *parameters = NULL;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->WriteLockPartition(partitionID); KPartition *partition = manager->WriteLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true);
// check parameters // check parameters
status_t error = validate_set_partition_content_parameters(partition, error = validate_set_partition_content_parameters(partition,
changeCounter, parameters); changeCounter, parameters);
if (error != B_OK) if (!error) {
return error;
// set name // set name
error = partition->SetContentParameters(parameters); error = partition->SetContentParameters(parameters);
if (error != B_OK) if (!error) {
return error;
partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS); partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
// implicit content disk system changes // implicit content disk system changes
return partition->DiskSystem()->ShadowPartitionChanged( error = partition->DiskSystem()->ShadowPartitionChanged(
partition, B_PARTITION_SET_CONTENT_PARAMETERS); partition, B_PARTITION_SET_CONTENT_PARAMETERS);
} }
}
}
free(partition);
return error;
}
// _kern_initialize_partition // _kern_initialize_partition
status_t status_t
_kern_initialize_partition(partition_id partitionID, int32 changeCounter, _kern_initialize_partition(partition_id partitionID, int32 changeCounter,
const char *diskSystemName, const char *name, const char *_diskSystemName, const char *_name,
const char *parameters) const char *_parameters)
{ {
if (!diskSystemName || !name) if (!_diskSystemName || !_name)
return B_BAD_VALUE; return B_BAD_VALUE;
if (strnlen(name, B_OS_NAME_LENGTH) == B_OS_NAME_LENGTH) char diskSystemName[B_OS_NAME_LENGTH];
char name[B_OS_NAME_LENGTH];
char *parameters = NULL;
if (user_strlcpy(diskSystemName, _diskSystemName, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH
|| user_strlcpy(name, _name, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG; return B_NAME_TOO_LONG;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->WriteLockPartition(partitionID); KPartition *partition = manager->WriteLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true);
// get the disk system // get the disk system
KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemName); KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemName);
if (!diskSystem) error = diskSystem ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
DiskSystemLoader loader(diskSystem, true); DiskSystemLoader loader(diskSystem, true);
// check parameters // check parameters
char proposedName[B_OS_NAME_LENGTH]; char proposedName[B_OS_NAME_LENGTH];
strcpy(proposedName, name); strcpy(proposedName, name);
status_t error = validate_initialize_partition(partition, changeCounter, error = validate_initialize_partition(partition, changeCounter,
diskSystemName, proposedName, parameters); diskSystemName, proposedName, parameters);
if (error != B_OK) if (!error) {
return error; error = !strcmp(name, proposedName) ? B_OK : B_BAD_VALUE;
if (strcmp(name, proposedName)) }
return B_BAD_VALUE; if (!error) {
// unitialize the partition's contents and set the new parameters // unitialize the partition's contents and set the new parameters
error = partition->UninitializeContents(true); error = partition->UninitializeContents(true);
if (error != B_OK) }
return error; if (!error) {
partition->SetDiskSystem(diskSystem); partition->SetDiskSystem(diskSystem);
error = partition->SetContentName(name); error = partition->SetContentName(name);
if (error != B_OK) }
return error; if (!error) {
partition->Changed(B_PARTITION_CHANGED_CONTENT_NAME); partition->Changed(B_PARTITION_CHANGED_CONTENT_NAME);
error = partition->SetContentParameters(parameters); error = partition->SetContentParameters(parameters);
if (error != B_OK) }
return error; if (!error) {
partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS); partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
// implicit content disk system changes // implicit content disk system changes
return partition->DiskSystem()->ShadowPartitionChanged( error = partition->DiskSystem()->ShadowPartitionChanged(
partition, B_PARTITION_INITIALIZE); partition, B_PARTITION_INITIALIZE);
} }
}
}
free(parameters);
return error;
}
// _kern_uninitialize_partition // _kern_uninitialize_partition
status_t status_t
@@ -1397,16 +1511,27 @@ _kern_uninitialize_partition(partition_id partitionID, int32 changeCounter)
// _kern_create_child_partition // _kern_create_child_partition
status_t status_t
_kern_create_child_partition(partition_id partitionID, int32 changeCounter, _kern_create_child_partition(partition_id partitionID, int32 changeCounter,
off_t offset, off_t size, const char *type, off_t offset, off_t size, const char *_type,
const char *parameters, partition_id *childID) const char *_parameters, partition_id *_childID)
{ {
if (!type) if (!_type)
return B_BAD_VALUE; return B_BAD_VALUE;
char type[B_OS_NAME_LENGTH];
char *parameters = NULL;
if (user_strlcpy(type, _type, B_OS_NAME_LENGTH) >= B_OS_NAME_LENGTH)
return B_NAME_TOO_LONG;
if (_parameters) {
parameters = static_cast<char*>(malloc(strlen(_parameters)+1));
if (parameters)
user_strcpy(parameters, _parameters);
else
return B_NO_MEMORY;
}
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// get the partition // get the partition
KPartition *partition = manager->WriteLockPartition(partitionID); KPartition *partition = manager->WriteLockPartition(partitionID);
if (!partition) status_t error = partition ? B_OK : B_ENTRY_NOT_FOUND;
return B_ENTRY_NOT_FOUND; if (!error) {
PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar1(partition, true);
PartitionRegistrar registrar2(partition->Device(), true); PartitionRegistrar registrar2(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true); DeviceWriteLocker locker(partition->Device(), true);
@@ -1414,33 +1539,40 @@ _kern_create_child_partition(partition_id partitionID, int32 changeCounter,
off_t proposedOffset = offset; off_t proposedOffset = offset;
off_t proposedSize = size; off_t proposedSize = size;
int32 index = 0; int32 index = 0;
status_t error = validate_create_child_partition(partition, changeCounter, error = validate_create_child_partition(partition, changeCounter,
&proposedOffset, &proposedSize, type, parameters, &index); &proposedOffset, &proposedSize, type, parameters, &index);
if (error != B_OK) if (!error) {
return error; error = (proposedOffset == offset && proposedSize == size)
if (proposedOffset != offset || proposedSize != size) ? B_OK : B_BAD_VALUE;
return B_BAD_VALUE; if (!error) {
// create the child // create the child
KPartition *child = NULL; KPartition *child = NULL;
error = partition->CreateChild(-1, index, &child); error = partition->CreateChild(-1, index, &child);
if (error != B_OK) if (!error) {
return error;
partition->Changed(B_PARTITION_CHANGED_CHILDREN); partition->Changed(B_PARTITION_CHANGED_CHILDREN);
if (childID) if (_childID) {
*childID = child->ID(); partition_id childID = child->ID();
user_memcpy(_childID, &childID, sizeof(childID));
}
// set the parameters // set the parameters
child->SetOffset(offset); child->SetOffset(offset);
child->SetSize(offset); child->SetSize(offset);
error = child->SetType(type); error = child->SetType(type);
if (error != B_OK) }
return error; if (!error) {
error = partition->SetParameters(parameters); error = partition->SetParameters(parameters);
if (error != B_OK) }
return error; if (!error) {
// implicit partitioning system changes // implicit partitioning system changes
return partition->DiskSystem()->ShadowPartitionChanged( error = partition->DiskSystem()->ShadowPartitionChanged(
partition, B_PARTITION_CREATE_CHILD); partition, B_PARTITION_CREATE_CHILD);
} }
}
}
}
free(parameters);
return error;
}
// _kern_delete_partition // _kern_delete_partition
status_t status_t
@@ -1468,20 +1600,25 @@ _kern_delete_partition(partition_id partitionID, int32 changeCounter)
// _kern_get_next_disk_device_job_info // _kern_get_next_disk_device_job_info
status_t status_t
_kern_get_next_disk_device_job_info(int32 *cookie, _kern_get_next_disk_device_job_info(int32 *_cookie,
user_disk_device_job_info *info) user_disk_device_job_info *_info)
{ {
if (!cookie || !info) if (!_cookie || !_info)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 cookie;
user_disk_device_job_info info;
user_memcpy(&cookie, _cookie, sizeof(cookie));
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
status_t error = B_ENTRY_NOT_FOUND;
if (ManagerLocker locker = manager) { if (ManagerLocker locker = manager) {
// get the next job and an info // get the next job and an info
while (KDiskDeviceJob *job = manager->NextJob(cookie)) { while (KDiskDeviceJob *job = manager->NextJob(&cookie)) {
// return info only on job scheduled or in progress // return info only on job scheduled or in progress
switch (job->Status()) { switch (job->Status()) {
case B_DISK_DEVICE_JOB_SCHEDULED: case B_DISK_DEVICE_JOB_SCHEDULED:
case B_DISK_DEVICE_JOB_IN_PROGRESS: case B_DISK_DEVICE_JOB_IN_PROGRESS:
return job->GetInfo(info); error = job->GetInfo(&info);
break;
case B_DISK_DEVICE_JOB_UNINITIALIZED: case B_DISK_DEVICE_JOB_UNINITIALIZED:
case B_DISK_DEVICE_JOB_SUCCEEDED: case B_DISK_DEVICE_JOB_SUCCEEDED:
case B_DISK_DEVICE_JOB_FAILED: case B_DISK_DEVICE_JOB_FAILED:
@@ -1490,38 +1627,50 @@ _kern_get_next_disk_device_job_info(int32 *cookie,
} }
} }
} }
return B_ENTRY_NOT_FOUND; if (!error) {
user_memcpy(_cookie, &cookie, sizeof(cookie));
user_memcpy(_info, &info, sizeof(info));
}
return error;
} }
// _kern_get_disk_device_job_info // _kern_get_disk_device_job_info
status_t status_t
_kern_get_disk_device_job_info(disk_job_id id, user_disk_device_job_info *info) _kern_get_disk_device_job_info(disk_job_id id, user_disk_device_job_info *_info)
{ {
if (!info) if (!_info)
return B_BAD_VALUE; return B_BAD_VALUE;
user_disk_device_job_info info;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
status_t error = B_ENTRY_NOT_FOUND;
if (ManagerLocker locker = manager) { if (ManagerLocker locker = manager) {
// find the job and get the info // find the job and get the info
if (KDiskDeviceJob *job = manager->FindJob(id)) if (KDiskDeviceJob *job = manager->FindJob(id))
return job->GetInfo(info); error = job->GetInfo(&info);
} }
return B_ENTRY_NOT_FOUND; if (!error)
user_memcpy(_info, &info, sizeof(info));
return error;
} }
// _kern_get_disk_device_job_status // _kern_get_disk_device_job_status
status_t status_t
_kern_get_disk_device_job_progress_info(disk_job_id id, _kern_get_disk_device_job_progress_info(disk_job_id id,
disk_device_job_progress_info *info) disk_device_job_progress_info *_info)
{ {
if (!info) if (!_info)
return B_BAD_VALUE; return B_BAD_VALUE;
disk_device_job_progress_info info;
KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDeviceManager *manager = KDiskDeviceManager::Default();
status_t error = B_ENTRY_NOT_FOUND;
if (ManagerLocker locker = manager) { if (ManagerLocker locker = manager) {
// find the job and get the info // find the job and get the info
if (KDiskDeviceJob *job = manager->FindJob(id)) if (KDiskDeviceJob *job = manager->FindJob(id))
return job->GetProgressInfo(info); error = job->GetProgressInfo(&info);
} }
return B_ENTRY_NOT_FOUND; if (!error)
user_memcpy(_info, &info, sizeof(info));
return error;
} }
// _kern_pause_disk_device_job // _kern_pause_disk_device_job