Made KPartition abstract and derived two classes, KPhysicalPartition

and KShadowPartition from it. KPhysicalPartition represents a partition
that exists on-disk, while KShadowPartition is a partition edited by the
API user, but not yet written to disk. Related changes in other classes.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3851 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-07-04 23:45:26 +00:00
parent 904c699d7f
commit a162af3b0e
13 changed files with 481 additions and 112 deletions

View File

@ -5,7 +5,7 @@
#include <OS.h>
#include "KPartition.h"
#include "KPhysicalPartition.h"
#include "RWLocker.h"
// disk device flags
@ -18,7 +18,7 @@ enum {
namespace BPrivate {
namespace DiskDevice {
class KDiskDevice : public KPartition {
class KDiskDevice : public KPhysicalPartition {
public:
KDiskDevice(partition_id id = -1);
virtual ~KDiskDevice();
@ -66,8 +66,6 @@ public:
disk_device_data *DeviceData();
const disk_device_data *DeviceData() const;
virtual KPartition *CreateShadowPartition();
void SetShadowOwner(team_id team);
team_id ShadowOwner() const;

View File

@ -37,20 +37,18 @@ public:
// Disk Device / Partition Management
// manager must be locked
KDiskDevice *FindDevice(const char *path, bool noShadow = true);
KDiskDevice *FindDevice(partition_id id, bool noShadow = true);
KPartition *FindPartition(const char *path, bool noShadow = true);
KPartition *FindPartition(partition_id id, bool noShadow = true);
KFileDiskDevice *FindFileDevice(const char *filePath,
bool noShadow = true);
KDiskDevice *FindDevice(const char *path);
KDiskDevice *FindDevice(partition_id id);
KPartition *FindPartition(const char *path, bool noShadow = false);
KPartition *FindPartition(partition_id id, bool noShadow = false);
KFileDiskDevice *FindFileDevice(const char *filePath);
KDiskDevice *RegisterDevice(const char *path, bool noShadow = true);
KDiskDevice *RegisterDevice(partition_id id, bool noShadow = true);
KDiskDevice *RegisterDevice(const char *path);
KDiskDevice *RegisterDevice(partition_id id);
KDiskDevice *RegisterNextDevice(int32 *cookie);
KPartition *RegisterPartition(const char *path, bool noShadow = true);
KPartition *RegisterPartition(partition_id id, bool noShadow = true);
KFileDiskDevice *RegisterFileDevice(const char *filePath,
bool noShadow = true);
KPartition *RegisterPartition(const char *path, bool noShadow = false);
KPartition *RegisterPartition(partition_id id, bool noShadow = false);
KFileDiskDevice *RegisterFileDevice(const char *filePath);
status_t CreateFileDevice(const char *filePath, partition_id *device = 0);
status_t DeleteFileDevice(const char *filePath);

View File

@ -22,8 +22,6 @@ public:
const char *FilePath() const;
virtual KPartition *CreateShadowPartition();
// virtual void Dump(bool deep = true, int32 level = 0);
private:

View File

@ -24,6 +24,8 @@ namespace DiskDevice {
class KDiskDevice;
class KDiskSystem;
class KPhysicalPartition;
class KShadowPartition;
class KPartition {
public:
@ -44,7 +46,7 @@ public:
virtual bool PrepareForRemoval();
virtual bool PrepareForDeletion();
status_t Open(int flags, int *fd);
virtual status_t Open(int flags, int *fd);
virtual status_t PublishDevice();
virtual status_t UnpublishDevice();
@ -55,7 +57,7 @@ public:
bool IsDescendantBusy() const;
// == jobs which may affect a descendant of this partition are
// scheduled/in progress; IsBusy() => IsDescendantBusy()
// In the userland API, both can probably mapped to one flag.
// In the userland API, both can probably be mapped to one flag.
void SetOffset(off_t offset);
off_t Offset() const; // 0 for devices
@ -108,8 +110,8 @@ public:
void SetVolumeID(dev_t volumeID);
dev_t VolumeID() const;
status_t Mount(uint32 mountFlags, const char *parameters);
status_t Unmount();
virtual status_t Mount(uint32 mountFlags, const char *parameters);
virtual status_t Unmount();
// Parameters
@ -128,8 +130,8 @@ public:
KPartition *Parent() const;
status_t AddChild(KPartition *partition, int32 index = -1);
status_t CreateChild(partition_id id, int32 index,
KPartition **child = NULL);
virtual status_t CreateChild(partition_id id, int32 index,
KPartition **child = NULL) = 0;
bool RemoveChild(int32 index);
bool RemoveChild(KPartition *child);
bool RemoveAllChildren();
@ -138,10 +140,11 @@ public:
// Shadow Partition
virtual KPartition *CreateShadowPartition(); // creates a complete tree
void DeleteShadowPartition(); // deletes ...
KPartition *ShadowPartition() const;
bool IsShadowPartition() const;
virtual status_t CreateShadowPartition(); // creates a complete tree
virtual void DeleteShadowPartition(); // deletes ...
virtual KShadowPartition *ShadowPartition() = 0;
virtual bool IsShadowPartition() const = 0;
virtual KPhysicalPartition *PhysicalPartition() = 0;
// DiskSystem

View File

@ -0,0 +1,55 @@
// KPartition.h
#ifndef _K_DISK_DEVICE_PHYSICAL_PARTITION_H
#define _K_DISK_DEVICE_PHYSICAL_PARTITION_H
#include <KPartition.h>
namespace BPrivate {
namespace DiskDevice {
class KDiskDevice;
class KDiskSystem;
class KShadowPartition;
class KPhysicalPartition : public KPartition {
public:
KPhysicalPartition(partition_id id = -1);
virtual ~KPhysicalPartition();
virtual bool PrepareForRemoval();
virtual status_t Open(int flags, int *fd);
virtual status_t PublishDevice();
virtual status_t UnpublishDevice();
virtual status_t Mount(uint32 mountFlags, const char *parameters);
virtual status_t Unmount();
// Hierarchy
virtual status_t CreateChild(partition_id id, int32 index,
KPartition **child = NULL);
// Shadow Partition
virtual status_t CreateShadowPartition(); // creates a complete tree
virtual void DeleteShadowPartition(); // deletes ...
virtual KShadowPartition *ShadowPartition();
virtual bool IsShadowPartition() const;
virtual KPhysicalPartition *PhysicalPartition();
// DiskSystem
virtual void Dump(bool deep, int32 level);
protected:
KShadowPartition *fShadowPartition;
};
} // namespace DiskDevice
} // namespace BPrivate
using BPrivate::DiskDevice::KPhysicalPartition;
#endif // _K_DISK_DEVICE_PHYSICAL_PARTITION_H

View File

@ -0,0 +1,41 @@
// KPartition.h
#ifndef _K_DISK_DEVICE_SHADOW_PARTITION_H
#define _K_DISK_DEVICE_SHADOW_PARTITION_H
#include "KPartition.h"
namespace BPrivate {
namespace DiskDevice {
class KPhysicalPartition;
class KShadowPartition : public KPartition {
public:
KShadowPartition(KPhysicalPartition *physicalPartition);
virtual ~KShadowPartition();
// Hierarchy
virtual status_t CreateChild(partition_id id, int32 index,
KPartition **child = NULL);
// Shadow Partition
virtual KShadowPartition *ShadowPartition();
virtual bool IsShadowPartition() const;
void SetPhysicalPartition(KPhysicalPartition *partition);
virtual KPhysicalPartition *PhysicalPartition();
virtual void Dump(bool deep, int32 level);
protected:
KPhysicalPartition *fPhysicalPartition;
};
} // namespace DiskDevice
} // namespace BPrivate
using BPrivate::DiskDevice::KShadowPartition;
#endif // _K_DISK_DEVICE_SHADOW_PARTITION_H

View File

@ -11,6 +11,7 @@ UsePrivateHeaders [ FDirName storage ] ;
UseHeaders [ FDirName $(OBOS_TOP) src tests kits storage virtualdrive ] ;
SharedLibrary disk_device_manager :
disk_device_manager.cpp
KDiskDevice.cpp
KDiskDeviceJob.cpp
KDiskDeviceJobFactory.cpp
@ -21,7 +22,8 @@ SharedLibrary disk_device_manager :
KFileSystem.cpp
KPartition.cpp
KPartitioningSystem.cpp
disk_device_manager.cpp
KPhysicalPartition.cpp
KShadowPartition.cpp
# jobs
KCreateChildJob.cpp

View File

@ -17,7 +17,7 @@
// constructor
KDiskDevice::KDiskDevice(partition_id id)
: KPartition(id),
: KPhysicalPartition(id),
fDeviceData(),
fLocker("diskdevice"),
fFD(-1),
@ -143,7 +143,7 @@ KDiskDevice::IsWriteLocked()
void
KDiskDevice::SetID(partition_id id)
{
KPartition::SetID(id);
KPhysicalPartition::SetID(id);
fDeviceData.id = id;
}
@ -248,14 +248,6 @@ KDiskDevice::DeviceData() const
return &fDeviceData;
}
// CreateShadowPartition
KPartition *
KDiskDevice::CreateShadowPartition()
{
// not implemented
return NULL;
}
// SetShadowOwner
void
KDiskDevice::SetShadowOwner(team_id team)
@ -278,7 +270,7 @@ KDiskDevice::Dump(bool deep, int32 level)
OUT(" media status: %s\n", strerror(fMediaStatus));
OUT(" device flags: %lx\n", DeviceFlags());
if (fMediaStatus == B_OK)
KPartition::Dump(deep, 0);
KPhysicalPartition::Dump(deep, 0);
}
// GetMediaStatus

View File

@ -203,9 +203,8 @@ KDiskDeviceManager::Unlock()
// FindDevice
KDiskDevice *
KDiskDeviceManager::FindDevice(const char *path, bool noShadow)
KDiskDeviceManager::FindDevice(const char *path)
{
// TODO: Handle shadows correctly!
for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) {
if (device->Path() && !strcmp(path, device->Path()))
return device;
@ -215,9 +214,8 @@ KDiskDeviceManager::FindDevice(const char *path, bool noShadow)
// FindDevice
KDiskDevice *
KDiskDeviceManager::FindDevice(partition_id id, bool noShadow)
KDiskDeviceManager::FindDevice(partition_id id)
{
// TODO: Handle shadows correctly!
if (KPartition *partition = FindPartition(id))
return partition->Device();
return NULL;
@ -227,7 +225,6 @@ KDiskDeviceManager::FindDevice(partition_id id, bool noShadow)
KPartition *
KDiskDeviceManager::FindPartition(const char *path, bool noShadow)
{
// TODO: Handle shadows correctly!
// TODO: Optimize!
for (PartitionMap::Iterator it = fPartitions->Begin();
it != fPartitions->End();
@ -236,6 +233,8 @@ KDiskDeviceManager::FindPartition(const char *path, bool noShadow)
char partitionPath[B_PATH_NAME_LENGTH];
if (partition->GetPath(partitionPath) == B_OK
&& !strcmp(path, partitionPath)) {
if (noShadow && partition->IsShadowPartition())
return partition->PhysicalPartition();
return partition;
}
}
@ -246,18 +245,19 @@ KDiskDeviceManager::FindPartition(const char *path, bool noShadow)
KPartition *
KDiskDeviceManager::FindPartition(partition_id id, bool noShadow)
{
// TODO: Handle shadows correctly!
PartitionMap::Iterator it = fPartitions->Find(id);
if (it != fPartitions->End())
if (it != fPartitions->End()) {
if (noShadow && it->Value()->IsShadowPartition())
return it->Value()->PhysicalPartition();
return it->Value();
}
return NULL;
}
// FindFileDevice
KFileDiskDevice *
KDiskDeviceManager::FindFileDevice(const char *filePath, bool noShadow)
KDiskDeviceManager::FindFileDevice(const char *filePath)
{
// TODO: Handle shadows correctly!
for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) {
KFileDiskDevice *fileDevice = dynamic_cast<KFileDiskDevice*>(device);
if (fileDevice && fileDevice->FilePath()
@ -270,11 +270,10 @@ KDiskDeviceManager::FindFileDevice(const char *filePath, bool noShadow)
// RegisterDevice
KDiskDevice *
KDiskDeviceManager::RegisterDevice(const char *path, bool noShadow)
KDiskDeviceManager::RegisterDevice(const char *path)
{
// TODO: Handle shadows correctly!
if (ManagerLocker locker = this) {
if (KDiskDevice *device = FindDevice(path, noShadow)) {
if (KDiskDevice *device = FindDevice(path)) {
device->Register();
return device;
}
@ -284,11 +283,10 @@ KDiskDeviceManager::RegisterDevice(const char *path, bool noShadow)
// RegisterDevice
KDiskDevice *
KDiskDeviceManager::RegisterDevice(partition_id id, bool noShadow)
KDiskDeviceManager::RegisterDevice(partition_id id)
{
// TODO: Handle shadows correctly!
if (ManagerLocker locker = this) {
if (KDiskDevice *device = FindDevice(id, noShadow)) {
if (KDiskDevice *device = FindDevice(id)) {
device->Register();
return device;
}
@ -339,10 +337,10 @@ KDiskDeviceManager::RegisterPartition(partition_id id, bool noShadow)
// RegisterFileDevice
KFileDiskDevice *
KDiskDeviceManager::RegisterFileDevice(const char *filePath, bool noShadow)
KDiskDeviceManager::RegisterFileDevice(const char *filePath)
{
if (ManagerLocker locker = this) {
if (KFileDiskDevice *device = FindFileDevice(filePath, noShadow)) {
if (KFileDiskDevice *device = FindFileDevice(filePath)) {
device->Register();
return device;
}
@ -572,8 +570,6 @@ KDiskDeviceManager::LoadNextDiskSystem(int32 *cookie)
if (!cookie)
return NULL;
if (ManagerLocker locker = this) {
// TODO: This loop assumes that the disk system list is ordered.
// Make sure that this is really the case.
if (KDiskSystem *diskSystem = NextDiskSystem(cookie)) {
if (diskSystem->Load() == B_OK) {
*cookie = diskSystem->ID() + 1;

View File

@ -118,14 +118,6 @@ KFileDiskDevice::FilePath() const
return fFilePath;
}
// CreateShadowPartition
KPartition *
KFileDiskDevice::CreateShadowPartition()
{
// not implemented
return NULL;
}
// _RegisterDevice
status_t
KFileDiskDevice::_RegisterDevice(const char *file, const char *device)

View File

@ -18,12 +18,12 @@
using namespace std;
// constructor
// debugging
//#define DBG(x)
#define DBG(x) x
#define OUT printf
// constructor
KPartition::KPartition(partition_id id)
: fPartitionData(),
fChildren(),
@ -446,7 +446,7 @@ KPartition::GetPath(char *path) const
int32 len = strlen(path);
if (len >= B_PATH_NAME_LENGTH - 10)
return B_NAME_TOO_LONG;
if (Parent() == Device()) {
if (Parent()->IsDevice()) {
// Our parent is a device, so we replace `raw' by our index.
int32 leafLen = strlen("/raw");
if (len <= leafLen || strcmp(path + len - leafLen, "/raw"))
@ -579,29 +579,6 @@ KPartition::AddChild(KPartition *partition, int32 index)
return B_ERROR;
}
// CreateChild
status_t
KPartition::CreateChild(partition_id id, int32 index, KPartition **_child)
{
// check parameters
int32 count = fPartitionData.child_count;
if (index == -1)
index = count;
if (index < 0 || index > count)
return B_BAD_VALUE;
// create and add partition
KPartition *child = new(nothrow) KPartition(id);
if (!child)
return B_NO_MEMORY;
status_t error = AddChild(child, index);
// cleanup / set result
if (error != B_OK)
delete child;
else if (_child)
*_child = child;
return error;
}
// RemoveChild
bool
KPartition::RemoveChild(int32 index)
@ -666,34 +643,18 @@ KPartition::CountChildren() const
}
// CreateShadowPartition
KPartition *
status_t
KPartition::CreateShadowPartition()
{
// not implemented
return NULL;
// implemented by derived classes
return B_ERROR;
}
// DeleteShadowPartition
void
KPartition::DeleteShadowPartition()
{
// not implemented
}
// ShadowPartition
KPartition *
KPartition::ShadowPartition() const
{
// not implemented
return NULL;
}
// IsShadowPartition
bool
KPartition::IsShadowPartition() const
{
// not implemented
return false;
// implemented by derived classes
}
// SetDiskSystem

View File

@ -0,0 +1,236 @@
// KPhysicalPartition.cpp
#include <errno.h>
#include <fcntl.h>
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <Drivers.h>
#include <Errors.h>
#include "KDiskDevice.h"
#include "KDiskDeviceManager.h"
#include "KDiskDeviceUtils.h"
#include "KPhysicalPartition.h"
#include "KShadowPartition.h"
using namespace std;
// debugging
//#define DBG(x)
#define DBG(x) x
#define OUT printf
// constructor
KPhysicalPartition::KPhysicalPartition(partition_id id)
: KPartition(id),
fShadowPartition(NULL)
{
}
// destructor
KPhysicalPartition::~KPhysicalPartition()
{
}
// Register
// PrepareForRemoval
bool
KPhysicalPartition::PrepareForRemoval()
{
bool result = KPartition::PrepareForRemoval();
if (result) {
DeleteShadowPartition();
UnpublishDevice();
}
return result;
}
// Open
status_t
KPhysicalPartition::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;
}
// PublishDevice
status_t
KPhysicalPartition::PublishDevice()
{
// prepare a partition_info
partition_info info;
info.offset = Offset();
info.size = Size();
info.logical_block_size = BlockSize();
info.session = 0;
info.partition = ID();
if (strlen(Device()->Path()) >= 256)
return B_NAME_TOO_LONG;
strcpy(info.device, Device()->Path());
// get the entry path
char path[B_PATH_NAME_LENGTH];
status_t error = GetPath(path);
if (error != B_OK)
return error;
// create the entry
int fd = creat(path, 0666);
if (fd < 0)
return errno;
// set the partition info
error = B_OK;
if (ioctl(fd, B_SET_PARTITION, &info) < 0)
error = errno;
close(fd);
return error;
}
// UnpublishDevice
status_t
KPhysicalPartition::UnpublishDevice()
{
// get the entry path
char path[B_PATH_NAME_LENGTH];
status_t error = GetPath(path);
if (error != B_OK)
return error;
// remove the entry
if (remove(path) < 0)
return errno;
return B_OK;
}
// Mount
status_t
KPhysicalPartition::Mount(uint32 mountFlags, const char *parameters)
{
// not implemented
return B_ERROR;
}
// Unmount
status_t
KPhysicalPartition::Unmount()
{
// not implemented
return B_ERROR;
}
// CreateChild
status_t
KPhysicalPartition::CreateChild(partition_id id, int32 index,
KPartition **_child)
{
// check parameters
int32 count = fPartitionData.child_count;
if (index == -1)
index = count;
if (index < 0 || index > count)
return B_BAD_VALUE;
// create and add partition
KPhysicalPartition *child = new(nothrow) KPhysicalPartition(id);
if (!child)
return B_NO_MEMORY;
status_t error = AddChild(child, index);
// cleanup / set result
if (error != B_OK)
delete child;
else if (_child)
*_child = child;
return error;
}
// CreateShadowPartition
status_t
KPhysicalPartition::CreateShadowPartition()
{
if (fShadowPartition)
return B_BAD_VALUE;
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
if (ManagerLocker locker = manager) {
// create shadow partition
fShadowPartition = new(nothrow) KShadowPartition(this);
if (!fShadowPartition)
return B_NO_MEMORY;
// make it known to the manager
if (!manager->PartitionAdded(fShadowPartition)) {
delete fShadowPartition;
fShadowPartition = NULL;
return B_NO_MEMORY;
}
}
// create shadows for children
for (int32 i = 0; KPartition *child = ChildAt(i); i++) {
status_t error = child->CreateShadowPartition();
if (error == B_OK)
error = fShadowPartition->AddChild(child->ShadowPartition(), i);
// cleanup on error
if (error != B_OK) {
for (int32 k = 0; k <= i; i++)
ChildAt(k)->DeleteShadowPartition();
DeleteShadowPartition();
return error;
}
}
return B_OK;
}
// DeleteShadowPartition
void
KPhysicalPartition::DeleteShadowPartition()
{
if (!fShadowPartition)
return;
// delete children's shadows
for (int32 i = 0; KPartition *child = ChildAt(i); i++)
child->DeleteShadowPartition();
// delete the thing
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
if (ManagerLocker locker = manager) {
fShadowPartition->SetPhysicalPartition(NULL);
PartitionRegistrar _(fShadowPartition);
manager->PartitionRemoved(fShadowPartition);
fShadowPartition = NULL;
}
}
// ShadowPartition
KShadowPartition *
KPhysicalPartition::ShadowPartition()
{
return fShadowPartition;
}
// IsShadowPartition
bool
KPhysicalPartition::IsShadowPartition() const
{
return false;
}
// PhysicalPartition
KPhysicalPartition *
KPhysicalPartition::PhysicalPartition()
{
return this;
}
// Dump
void
KPhysicalPartition::Dump(bool deep, int32 level)
{
KPartition::Dump(deep, level);
}

View File

@ -0,0 +1,97 @@
// KShadowPartition.cpp
#include <errno.h>
#include <fcntl.h>
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <Drivers.h>
#include <Errors.h>
#include "KDiskDevice.h"
#include "KDiskDeviceManager.h"
#include "KDiskDeviceUtils.h"
#include "KShadowPartition.h"
using namespace std;
// debugging
//#define DBG(x)
#define DBG(x) x
#define OUT printf
// constructor
KShadowPartition::KShadowPartition(KPhysicalPartition *partition)
: KPartition(),
fPhysicalPartition(NULL)
{
SetPhysicalPartition(partition);
}
// destructor
KShadowPartition::~KShadowPartition()
{
}
// CreateChild
status_t
KShadowPartition::CreateChild(partition_id id, int32 index,
KPartition **_child)
{
// check parameters
int32 count = fPartitionData.child_count;
if (index == -1)
index = count;
if (index < 0 || index > count)
return B_BAD_VALUE;
// create and add partition
KShadowPartition *child = new(nothrow) KShadowPartition(NULL);
if (!child)
return B_NO_MEMORY;
status_t error = AddChild(child, index);
// cleanup / set result
if (error != B_OK)
delete child;
else if (_child)
*_child = child;
return error;
}
// IsShadowPartition
bool
KShadowPartition::IsShadowPartition() const
{
return true;
}
// ShadowPartition
KShadowPartition*
KShadowPartition::ShadowPartition()
{
return this;
}
// SetPhysicalPartition
void
KShadowPartition::SetPhysicalPartition(KPhysicalPartition *partition)
{
fPhysicalPartition = partition;
// TODO: clone the data of the physical partition.
}
// PhysicalPartition
KPhysicalPartition*
KShadowPartition::PhysicalPartition()
{
return fPhysicalPartition;
}
// Dump
void
KShadowPartition::Dump(bool deep, int32 level)
{
KPartition::Dump(deep, level);
}