Implemented some more bits of KPartition. Added a very useful Open() method.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3463 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,12 +6,6 @@
|
|||||||
#include "disk_device_manager.h"
|
#include "disk_device_manager.h"
|
||||||
#include "List.h"
|
#include "List.h"
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
namespace DiskDevice {
|
|
||||||
|
|
||||||
class KDiskDevice;
|
|
||||||
class KDiskSystem;
|
|
||||||
|
|
||||||
// partition flags
|
// partition flags
|
||||||
// TODO: move to another header (must be accessible from userland API impl.)
|
// TODO: move to another header (must be accessible from userland API impl.)
|
||||||
enum {
|
enum {
|
||||||
@@ -24,17 +18,26 @@ enum {
|
|||||||
B_PARTITION_DESCENDANT_BUSY = 0x40,
|
B_PARTITION_DESCENDANT_BUSY = 0x40,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
namespace DiskDevice {
|
||||||
|
|
||||||
|
class KDiskDevice;
|
||||||
|
class KDiskSystem;
|
||||||
|
|
||||||
class KPartition {
|
class KPartition {
|
||||||
|
public:
|
||||||
KPartition(partition_id id = -1);
|
KPartition(partition_id id = -1);
|
||||||
virtual ~KPartition();
|
virtual ~KPartition();
|
||||||
|
|
||||||
// Reference counting. As long as there's at least one referrer, the
|
// Reference counting. As long as there's at least one referrer, the
|
||||||
// object won't be deleted.
|
// object won't be deleted.
|
||||||
// manager must be locked
|
// manager must be locked
|
||||||
bool Register();
|
void Register();
|
||||||
bool Unregister();
|
void Unregister();
|
||||||
int32 CountReferences() const;
|
int32 CountReferences() const;
|
||||||
|
|
||||||
|
status_t Open(int flags, int *fd);
|
||||||
|
|
||||||
void SetBusy(bool busy);
|
void SetBusy(bool busy);
|
||||||
bool IsBusy() const;
|
bool IsBusy() const;
|
||||||
// == jobs which may affect this partition are scheduled/in progress
|
// == jobs which may affect this partition are scheduled/in progress
|
||||||
@@ -84,7 +87,7 @@ class KPartition {
|
|||||||
partition_data *PartitionData();
|
partition_data *PartitionData();
|
||||||
const partition_data *PartitionData() const;
|
const partition_data *PartitionData() const;
|
||||||
|
|
||||||
void SetID(partition_id id);
|
virtual void SetID(partition_id id);
|
||||||
partition_id ID() const;
|
partition_id ID() const;
|
||||||
|
|
||||||
int32 ChangeCounter() const;
|
int32 ChangeCounter() const;
|
||||||
@@ -139,6 +142,9 @@ class KPartition {
|
|||||||
void SetContentCookie(void *cookie);
|
void SetContentCookie(void *cookie);
|
||||||
void *ContentCookie() const;
|
void *ContentCookie() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _UpdateChildIndices(int32 index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
partition_data fPartitionData;
|
partition_data fPartitionData;
|
||||||
List<KPartition*> fChildren;
|
List<KPartition*> fChildren;
|
||||||
|
|||||||
@@ -1,38 +1,24 @@
|
|||||||
// KPartition.cpp
|
// KPartition.cpp
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Errors.h>
|
||||||
|
|
||||||
//#include <Partition.h>
|
//#include <Partition.h>
|
||||||
// TODO: Move the definitions needed in the kernel to a separate header.
|
// TODO: Move the definitions needed in the kernel to a separate header.
|
||||||
|
|
||||||
|
#include "KDiskDevice.h"
|
||||||
|
#include "KDiskDeviceManager.h"
|
||||||
|
#include "KDiskDeviceUtils.h"
|
||||||
#include "KPartition.h"
|
#include "KPartition.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using BPrivate::DiskDevice::KDiskDevice;
|
|
||||||
using BPrivate::DiskDevice::KDiskSystem;
|
using BPrivate::DiskDevice::KDiskSystem;
|
||||||
|
|
||||||
// set_string
|
|
||||||
// simple helper
|
|
||||||
static
|
|
||||||
status_t
|
|
||||||
set_string(char *&location, const char *newValue)
|
|
||||||
{
|
|
||||||
// unset old value
|
|
||||||
if (location) {
|
|
||||||
free(location);
|
|
||||||
location = NULL;
|
|
||||||
}
|
|
||||||
// set new value
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (newValue) {
|
|
||||||
location = strdup(newValue);
|
|
||||||
if (!location)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
KPartition::KPartition(partition_id id)
|
KPartition::KPartition(partition_id id)
|
||||||
: fPartitionData(),
|
: fPartitionData(),
|
||||||
@@ -74,19 +60,17 @@ KPartition::~KPartition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
bool
|
void
|
||||||
KPartition::Register()
|
KPartition::Register()
|
||||||
{
|
{
|
||||||
fReferenceCount++;
|
fReferenceCount++;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unregister
|
// Unregister
|
||||||
bool
|
void
|
||||||
KPartition::Unregister()
|
KPartition::Unregister()
|
||||||
{
|
{
|
||||||
fReferenceCount--;
|
fReferenceCount--;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountReferences
|
// CountReferences
|
||||||
@@ -96,6 +80,24 @@ KPartition::CountReferences() const
|
|||||||
return fReferenceCount;
|
return fReferenceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open
|
||||||
|
status_t
|
||||||
|
KPartition::Open(int flags, int *fd)
|
||||||
|
{
|
||||||
|
if (!fd)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
// get the path
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
status_t error = GetPath(path);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
// open the device
|
||||||
|
*fd = open(path, flags);
|
||||||
|
if (*fd < 0)
|
||||||
|
return errno;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// SetBusy
|
// SetBusy
|
||||||
void
|
void
|
||||||
KPartition::SetBusy(bool busy)
|
KPartition::SetBusy(bool busy)
|
||||||
@@ -343,8 +345,29 @@ KPartition::ChangeCounter() const
|
|||||||
status_t
|
status_t
|
||||||
KPartition::GetPath(char *path) const
|
KPartition::GetPath(char *path) const
|
||||||
{
|
{
|
||||||
// not implemented
|
// For a KDiskDevice this version is never invoked, so the check for
|
||||||
return B_ERROR;
|
// Parent() is correct.
|
||||||
|
if (!path || !Parent() || Index() < 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
// get the parent's path
|
||||||
|
status_t error = Parent()->GetPath(path);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
// check length for safety
|
||||||
|
int32 len = strlen(path);
|
||||||
|
if (len >= B_PATH_NAME_LENGTH - 10)
|
||||||
|
return B_NAME_TOO_LONG;
|
||||||
|
if (Parent() == Device()) {
|
||||||
|
// Our parent is a device, so we replace `raw' by our index.
|
||||||
|
int32 leafLen = strlen("/raw");
|
||||||
|
if (len <= leafLen || strcmp(path + len - leafLen, "/raw"))
|
||||||
|
return B_ERROR;
|
||||||
|
sprintf(path + len - leafLen + 1, "%ld", Index());
|
||||||
|
} else {
|
||||||
|
// Our parent is a normal partition, no device: Append our index.
|
||||||
|
sprintf(path + len, "_%ld", Index());
|
||||||
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVolumeID
|
// SetVolumeID
|
||||||
@@ -423,6 +446,7 @@ KPartition::Device() const
|
|||||||
void
|
void
|
||||||
KPartition::SetParent(KPartition *parent)
|
KPartition::SetParent(KPartition *parent)
|
||||||
{
|
{
|
||||||
|
// Must be called in a {Add,Remove}Child() only!
|
||||||
fParent = parent;
|
fParent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,13 +468,22 @@ KPartition::AddChild(KPartition *partition, int32 index)
|
|||||||
if (index < 0 || index > count || !partition)
|
if (index < 0 || index > count || !partition)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
// add partition
|
// add partition
|
||||||
// TODO: Lock the disk device manager!
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||||
if (!fChildren.AddItem(partition, index))
|
if (ManagerLocker locker = manager) {
|
||||||
return B_NO_MEMORY;
|
if (!fChildren.AddItem(partition, index))
|
||||||
fPartitionData.child_count++;
|
return B_NO_MEMORY;
|
||||||
partition->SetParent(this);
|
if (!manager->PartitionAdded(partition)) {
|
||||||
partition->SetDevice(Device());
|
fChildren.RemoveItem(index);
|
||||||
return B_OK;
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
partition->SetIndex(index);
|
||||||
|
_UpdateChildIndices(index);
|
||||||
|
fPartitionData.child_count++;
|
||||||
|
partition->SetParent(this);
|
||||||
|
partition->SetDevice(Device());
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveChild
|
// RemoveChild
|
||||||
@@ -459,12 +492,18 @@ KPartition::RemoveChild(int32 index)
|
|||||||
{
|
{
|
||||||
KPartition *partition = NULL;
|
KPartition *partition = NULL;
|
||||||
if (index >= 0 && index < fPartitionData.child_count) {
|
if (index >= 0 && index < fPartitionData.child_count) {
|
||||||
// TODO: Lock the disk device manager!
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||||
partition = fChildren.ItemAt(index);
|
if (ManagerLocker locker = manager) {
|
||||||
if (partition && fChildren.RemoveItem(index)) {
|
partition = fChildren.ItemAt(index);
|
||||||
fPartitionData.child_count--;
|
if (!partition || !manager->PartitionRemoved(partition))
|
||||||
partition->SetParent(NULL);
|
return NULL;
|
||||||
partition->SetDevice(NULL);
|
if (fChildren.RemoveItem(index)) {
|
||||||
|
_UpdateChildIndices(index + 1);
|
||||||
|
partition->SetIndex(-1);
|
||||||
|
fPartitionData.child_count--;
|
||||||
|
partition->SetParent(NULL);
|
||||||
|
partition->SetDevice(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return partition;
|
return partition;
|
||||||
@@ -571,3 +610,11 @@ KPartition::ContentCookie() const
|
|||||||
return fPartitionData.content_cookie;
|
return fPartitionData.content_cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _UpdateChildIndices
|
||||||
|
void
|
||||||
|
KPartition::_UpdateChildIndices(int32 index)
|
||||||
|
{
|
||||||
|
for (int32 i = index; KPartition *child = fChildren.ItemAt(i); i++)
|
||||||
|
child->SetIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user