2003-06-10 03:10:09 +04:00
|
|
|
// KPartition.cpp
|
|
|
|
|
2003-06-11 02:37:43 +04:00
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
2003-06-10 03:10:09 +04:00
|
|
|
#include <stdlib.h>
|
2003-06-14 04:06:57 +04:00
|
|
|
#include <unistd.h>
|
2003-06-10 03:10:09 +04:00
|
|
|
|
2004-06-12 01:03:31 +04:00
|
|
|
#include <KernelExport.h>
|
2003-06-14 04:06:57 +04:00
|
|
|
#include <Drivers.h>
|
2003-06-11 02:37:43 +04:00
|
|
|
#include <Errors.h>
|
2007-11-12 21:41:36 +03:00
|
|
|
#include <fs_volume.h>
|
2004-06-12 01:03:31 +04:00
|
|
|
#include <util/kernel_cpp.h>
|
2003-06-11 02:37:43 +04:00
|
|
|
|
2003-09-29 02:04:13 +04:00
|
|
|
#include <ddm_userland_interface.h>
|
2007-11-02 02:36:21 +03:00
|
|
|
#include <fs/devfs.h>
|
2003-09-29 02:04:13 +04:00
|
|
|
#include <KDiskDevice.h>
|
|
|
|
#include <KDiskDeviceManager.h>
|
|
|
|
#include <KDiskDeviceUtils.h>
|
|
|
|
#include <KDiskSystem.h>
|
|
|
|
#include <KPartition.h>
|
|
|
|
#include <KPartitionListener.h>
|
|
|
|
#include <KPartitionVisitor.h>
|
2004-10-28 01:48:47 +04:00
|
|
|
#include <KPath.h>
|
2003-09-29 02:04:13 +04:00
|
|
|
#include <VectorSet.h>
|
2007-11-12 21:41:36 +03:00
|
|
|
#include <vfs.h>
|
2003-09-29 02:04:13 +04:00
|
|
|
|
2003-07-07 03:01:22 +04:00
|
|
|
#include "UserDataWriter.h"
|
2003-06-10 03:10:09 +04:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2003-06-25 03:56:16 +04:00
|
|
|
// debugging
|
|
|
|
//#define DBG(x)
|
|
|
|
#define DBG(x) x
|
2004-06-12 01:03:31 +04:00
|
|
|
#define OUT dprintf
|
2003-06-25 03:56:16 +04:00
|
|
|
|
2003-09-29 02:04:13 +04:00
|
|
|
// ListenerSet
|
|
|
|
struct KPartition::ListenerSet : VectorSet<KPartitionListener*> {};
|
|
|
|
|
2003-07-05 03:45:26 +04:00
|
|
|
// constructor
|
2003-06-10 03:10:09 +04:00
|
|
|
KPartition::KPartition(partition_id id)
|
|
|
|
: fPartitionData(),
|
|
|
|
fChildren(),
|
|
|
|
fDevice(NULL),
|
|
|
|
fParent(NULL),
|
|
|
|
fDiskSystem(NULL),
|
2003-09-29 02:04:13 +04:00
|
|
|
fListeners(NULL),
|
2003-07-22 04:03:35 +04:00
|
|
|
fChangeFlags(0),
|
|
|
|
fChangeCounter(0),
|
2003-07-25 02:56:53 +04:00
|
|
|
fAlgorithmData(0),
|
2003-06-25 03:56:16 +04:00
|
|
|
fReferenceCount(0),
|
2007-09-07 04:05:06 +04:00
|
|
|
fObsolete(false),
|
|
|
|
fPublished(false)
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2003-06-13 02:21:10 +04:00
|
|
|
fPartitionData.id = (id >= 0 ? id : _NextID());
|
2003-06-10 03:10:09 +04:00
|
|
|
fPartitionData.offset = 0;
|
|
|
|
fPartitionData.size = 0;
|
2003-07-30 04:21:21 +04:00
|
|
|
fPartitionData.content_size = 0;
|
2003-06-10 03:10:09 +04:00
|
|
|
fPartitionData.block_size = 0;
|
|
|
|
fPartitionData.child_count = 0;
|
|
|
|
fPartitionData.index = -1;
|
2003-07-08 21:25:32 +04:00
|
|
|
fPartitionData.status = B_PARTITION_UNRECOGNIZED;
|
2007-11-02 03:29:46 +03:00
|
|
|
fPartitionData.flags = B_PARTITION_BUSY;
|
2003-06-10 03:10:09 +04:00
|
|
|
fPartitionData.volume = -1;
|
2003-09-21 22:25:42 +04:00
|
|
|
fPartitionData.mount_cookie = NULL;
|
2003-06-10 03:10:09 +04:00
|
|
|
fPartitionData.name = NULL;
|
|
|
|
fPartitionData.content_name = NULL;
|
|
|
|
fPartitionData.type = NULL;
|
|
|
|
fPartitionData.content_type = NULL;
|
|
|
|
fPartitionData.parameters = NULL;
|
|
|
|
fPartitionData.content_parameters = NULL;
|
|
|
|
fPartitionData.cookie = NULL;
|
|
|
|
fPartitionData.content_cookie = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// destructor
|
|
|
|
KPartition::~KPartition()
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
delete fListeners;
|
2003-06-25 03:56:16 +04:00
|
|
|
SetDiskSystem(NULL);
|
2003-06-10 03:10:09 +04:00
|
|
|
free(fPartitionData.name);
|
|
|
|
free(fPartitionData.content_name);
|
|
|
|
free(fPartitionData.type);
|
|
|
|
free(fPartitionData.parameters);
|
|
|
|
free(fPartitionData.content_parameters);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register
|
2003-06-11 02:37:43 +04:00
|
|
|
void
|
2003-06-10 03:10:09 +04:00
|
|
|
KPartition::Register()
|
|
|
|
{
|
|
|
|
fReferenceCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unregister
|
2003-06-11 02:37:43 +04:00
|
|
|
void
|
2003-06-10 03:10:09 +04:00
|
|
|
KPartition::Unregister()
|
|
|
|
{
|
2003-06-25 03:56:16 +04:00
|
|
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
|
|
|
ManagerLocker locker(manager);
|
2003-06-10 03:10:09 +04:00
|
|
|
fReferenceCount--;
|
2003-06-25 03:56:16 +04:00
|
|
|
if (IsObsolete() && fReferenceCount == 0) {
|
|
|
|
// let the manager delete object
|
|
|
|
manager->DeletePartition(this);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// CountReferences
|
|
|
|
int32
|
|
|
|
KPartition::CountReferences() const
|
|
|
|
{
|
|
|
|
return fReferenceCount;
|
|
|
|
}
|
|
|
|
|
2003-06-25 03:56:16 +04:00
|
|
|
// MarkObsolete
|
|
|
|
void
|
|
|
|
KPartition::MarkObsolete()
|
|
|
|
{
|
|
|
|
fObsolete = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsObsolete
|
|
|
|
bool
|
|
|
|
KPartition::IsObsolete() const
|
|
|
|
{
|
|
|
|
return fObsolete;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PrepareForRemoval
|
|
|
|
bool
|
|
|
|
KPartition::PrepareForRemoval()
|
|
|
|
{
|
|
|
|
bool result = RemoveAllChildren();
|
2008-02-06 14:46:44 +03:00
|
|
|
UninitializeContents();
|
2003-06-25 03:56:16 +04:00
|
|
|
UnpublishDevice();
|
2003-07-20 21:15:35 +04:00
|
|
|
if (ParentDiskSystem())
|
|
|
|
ParentDiskSystem()->FreeCookie(this);
|
|
|
|
if (DiskSystem())
|
|
|
|
DiskSystem()->FreeContentCookie(this);
|
2003-06-25 03:56:16 +04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PrepareForDeletion
|
|
|
|
bool
|
|
|
|
KPartition::PrepareForDeletion()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-06-11 02:37:43 +04:00
|
|
|
// Open
|
|
|
|
status_t
|
|
|
|
KPartition::Open(int flags, int *fd)
|
|
|
|
{
|
2007-11-02 02:36:21 +03:00
|
|
|
if (!fd)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
|
|
|
// get the path
|
|
|
|
KPath path;
|
|
|
|
status_t error = GetPath(&path);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
// open the device
|
|
|
|
*fd = open(path.Path(), flags);
|
|
|
|
if (*fd < 0)
|
|
|
|
return errno;
|
|
|
|
|
|
|
|
return B_OK;
|
2003-06-11 02:37:43 +04:00
|
|
|
}
|
|
|
|
|
2003-06-12 02:03:26 +04:00
|
|
|
// PublishDevice
|
|
|
|
status_t
|
|
|
|
KPartition::PublishDevice()
|
|
|
|
{
|
2007-11-02 02:36:21 +03:00
|
|
|
if (fPublished)
|
|
|
|
return B_OK;
|
|
|
|
|
|
|
|
// get the path
|
|
|
|
KPath path;
|
|
|
|
status_t error = GetPath(&path);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
// 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 (strlcpy(info.device, Device()->Path(), B_PATH_NAME_LENGTH)
|
|
|
|
>= B_PATH_NAME_LENGTH) {
|
|
|
|
return B_NAME_TOO_LONG;
|
|
|
|
}
|
|
|
|
|
|
|
|
error = devfs_publish_partition(path.Path() + 5, &info);
|
|
|
|
// we need to remove the "/dev/" part from the path
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
fPublished = true;
|
|
|
|
|
|
|
|
return B_OK;
|
2003-06-12 02:03:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// UnpublishDevice
|
|
|
|
status_t
|
|
|
|
KPartition::UnpublishDevice()
|
|
|
|
{
|
2007-11-02 02:36:21 +03:00
|
|
|
if (!fPublished)
|
|
|
|
return B_OK;
|
|
|
|
|
|
|
|
// get the path
|
|
|
|
KPath path;
|
|
|
|
status_t error = GetPath(&path);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
fPublished = false;
|
|
|
|
|
|
|
|
return devfs_unpublish_partition(path.Path() + 5);
|
|
|
|
// we need to remove the "/dev/" part from the path
|
2003-06-12 02:03:26 +04:00
|
|
|
}
|
|
|
|
|
2007-09-07 04:05:06 +04:00
|
|
|
|
|
|
|
// IsPublished
|
|
|
|
bool
|
|
|
|
KPartition::IsPublished() const
|
|
|
|
{
|
|
|
|
return fPublished;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// SetBusy
|
|
|
|
void
|
|
|
|
KPartition::SetBusy(bool busy)
|
|
|
|
{
|
|
|
|
if (busy)
|
2003-08-03 22:27:33 +04:00
|
|
|
SetFlags(B_PARTITION_BUSY);
|
2003-06-10 03:10:09 +04:00
|
|
|
else
|
2003-08-03 22:27:33 +04:00
|
|
|
ClearFlags(B_PARTITION_BUSY);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2007-11-02 03:29:46 +03:00
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// IsBusy
|
|
|
|
bool
|
|
|
|
KPartition::IsBusy() const
|
|
|
|
{
|
|
|
|
return (fPartitionData.flags & B_PARTITION_BUSY);
|
|
|
|
}
|
|
|
|
|
2007-11-02 03:29:46 +03:00
|
|
|
|
2007-11-05 03:30:14 +03:00
|
|
|
// IsBusy
|
|
|
|
bool
|
|
|
|
KPartition::IsBusy(bool includeDescendants)
|
|
|
|
{
|
|
|
|
if (!includeDescendants)
|
|
|
|
return IsBusy();
|
|
|
|
|
|
|
|
struct IsBusyVisitor : KPartitionVisitor {
|
|
|
|
virtual bool VisitPre(KPartition* partition)
|
|
|
|
{
|
|
|
|
return partition->IsBusy();
|
|
|
|
}
|
|
|
|
} checkVisitor;
|
|
|
|
|
|
|
|
return VisitEachDescendant(&checkVisitor) != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-02 03:29:46 +03:00
|
|
|
// CheckAndMarkBusy
|
|
|
|
bool
|
|
|
|
KPartition::CheckAndMarkBusy(bool includeDescendants)
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2007-11-05 03:30:14 +03:00
|
|
|
if (IsBusy(includeDescendants))
|
|
|
|
return false;
|
2007-11-02 03:29:46 +03:00
|
|
|
|
2007-11-12 21:41:36 +03:00
|
|
|
MarkBusy(includeDescendants);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// MarkBusy
|
|
|
|
void
|
|
|
|
KPartition::MarkBusy(bool includeDescendants)
|
|
|
|
{
|
2007-11-05 03:30:14 +03:00
|
|
|
if (includeDescendants) {
|
2007-11-02 03:29:46 +03:00
|
|
|
struct MarkBusyVisitor : KPartitionVisitor {
|
|
|
|
virtual bool VisitPre(KPartition* partition)
|
|
|
|
{
|
|
|
|
partition->AddFlags(B_PARTITION_BUSY);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} markVisitor;
|
|
|
|
|
|
|
|
VisitEachDescendant(&markVisitor);
|
2007-11-05 03:30:14 +03:00
|
|
|
} else
|
2007-11-02 03:29:46 +03:00
|
|
|
SetBusy(true);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2007-11-02 03:29:46 +03:00
|
|
|
|
|
|
|
// UnmarkBusy
|
|
|
|
void
|
|
|
|
KPartition::UnmarkBusy(bool includeDescendants)
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2007-11-02 03:29:46 +03:00
|
|
|
if (includeDescendants) {
|
|
|
|
struct UnmarkBusyVisitor : KPartitionVisitor {
|
|
|
|
virtual bool VisitPre(KPartition* partition)
|
|
|
|
{
|
|
|
|
partition->ClearFlags(B_PARTITION_BUSY);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} visitor;
|
|
|
|
|
|
|
|
VisitEachDescendant(&visitor);
|
|
|
|
} else
|
|
|
|
SetBusy(false);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2007-11-02 03:29:46 +03:00
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// SetOffset
|
|
|
|
void
|
|
|
|
KPartition::SetOffset(off_t offset)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.offset != offset) {
|
|
|
|
fPartitionData.offset = offset;
|
|
|
|
FireOffsetChanged(offset);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Offset
|
|
|
|
off_t
|
|
|
|
KPartition::Offset() const
|
|
|
|
{
|
|
|
|
return fPartitionData.offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSize
|
|
|
|
void
|
|
|
|
KPartition::SetSize(off_t size)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.size != size) {
|
|
|
|
fPartitionData.size = size;
|
|
|
|
FireSizeChanged(size);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Size
|
|
|
|
off_t
|
|
|
|
KPartition::Size() const
|
|
|
|
{
|
|
|
|
return fPartitionData.size;
|
|
|
|
}
|
|
|
|
|
2003-07-30 04:21:21 +04:00
|
|
|
// SetContentSize
|
|
|
|
void
|
|
|
|
KPartition::SetContentSize(off_t size)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.content_size != size) {
|
|
|
|
fPartitionData.content_size = size;
|
|
|
|
FireContentSizeChanged(size);
|
|
|
|
}
|
2003-07-30 04:21:21 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ContentSize
|
|
|
|
off_t
|
|
|
|
KPartition::ContentSize() const
|
|
|
|
{
|
|
|
|
return fPartitionData.content_size;
|
|
|
|
}
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// SetBlockSize
|
|
|
|
void
|
|
|
|
KPartition::SetBlockSize(uint32 blockSize)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.block_size != blockSize) {
|
|
|
|
fPartitionData.block_size = blockSize;
|
|
|
|
FireBlockSizeChanged(blockSize);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// BlockSize
|
|
|
|
uint32
|
|
|
|
KPartition::BlockSize() const
|
|
|
|
{
|
|
|
|
return fPartitionData.block_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetIndex
|
|
|
|
void
|
|
|
|
KPartition::SetIndex(int32 index)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.index != index) {
|
|
|
|
fPartitionData.index = index;
|
|
|
|
FireIndexChanged(index);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Index
|
|
|
|
int32
|
|
|
|
KPartition::Index() const
|
|
|
|
{
|
|
|
|
return fPartitionData.index;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetStatus
|
|
|
|
void
|
|
|
|
KPartition::SetStatus(uint32 status)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.status != status) {
|
|
|
|
fPartitionData.status = status;
|
|
|
|
FireStatusChanged(status);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Status
|
|
|
|
uint32
|
|
|
|
KPartition::Status() const
|
|
|
|
{
|
|
|
|
return fPartitionData.status;
|
|
|
|
}
|
|
|
|
|
2003-09-22 01:21:10 +04:00
|
|
|
// IsUninitialized
|
|
|
|
bool
|
|
|
|
KPartition::IsUninitialized() const
|
|
|
|
{
|
|
|
|
return (Status() == B_PARTITION_UNINITIALIZED);
|
|
|
|
}
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// SetFlags
|
|
|
|
void
|
|
|
|
KPartition::SetFlags(uint32 flags)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.flags != flags) {
|
|
|
|
fPartitionData.flags = flags;
|
|
|
|
FireFlagsChanged(flags);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2003-08-03 22:27:33 +04:00
|
|
|
// AddFlags
|
|
|
|
void
|
|
|
|
KPartition::AddFlags(uint32 flags)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (~fPartitionData.flags & flags) {
|
|
|
|
fPartitionData.flags |= flags;
|
|
|
|
FireFlagsChanged(fPartitionData.flags);
|
|
|
|
}
|
2003-08-03 22:27:33 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ClearFlags
|
|
|
|
void
|
|
|
|
KPartition::ClearFlags(uint32 flags)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.flags & flags) {
|
|
|
|
fPartitionData.flags &= ~flags;
|
|
|
|
FireFlagsChanged(fPartitionData.flags);
|
|
|
|
}
|
2003-08-03 22:27:33 +04:00
|
|
|
}
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// Flags
|
|
|
|
uint32
|
|
|
|
KPartition::Flags() const
|
|
|
|
{
|
|
|
|
return fPartitionData.flags;
|
|
|
|
}
|
|
|
|
|
2003-07-08 21:38:45 +04:00
|
|
|
// ContainsFileSystem
|
2003-06-10 03:10:09 +04:00
|
|
|
bool
|
2003-07-08 21:38:45 +04:00
|
|
|
KPartition::ContainsFileSystem() const
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2003-07-08 21:38:45 +04:00
|
|
|
return (fPartitionData.flags & B_PARTITION_FILE_SYSTEM);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2003-07-08 21:38:45 +04:00
|
|
|
// ContainsPartitioningSystem
|
2003-06-10 03:10:09 +04:00
|
|
|
bool
|
2003-07-08 21:38:45 +04:00
|
|
|
KPartition::ContainsPartitioningSystem() const
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2003-07-08 21:38:45 +04:00
|
|
|
return (fPartitionData.flags & B_PARTITION_PARTITIONING_SYSTEM);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// IsReadOnly
|
|
|
|
bool
|
|
|
|
KPartition::IsReadOnly() const
|
|
|
|
{
|
|
|
|
return (fPartitionData.flags & B_PARTITION_READ_ONLY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsMounted
|
|
|
|
bool
|
|
|
|
KPartition::IsMounted() const
|
|
|
|
{
|
|
|
|
return (fPartitionData.flags & B_PARTITION_MOUNTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsDevice
|
|
|
|
bool
|
|
|
|
KPartition::IsDevice() const
|
|
|
|
{
|
|
|
|
return (fPartitionData.flags & B_PARTITION_IS_DEVICE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetName
|
|
|
|
status_t
|
|
|
|
KPartition::SetName(const char *name)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
status_t error = set_string(fPartitionData.name, name);
|
|
|
|
FireNameChanged(fPartitionData.name);
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Name
|
|
|
|
const char *
|
|
|
|
KPartition::Name() const
|
|
|
|
{
|
|
|
|
return fPartitionData.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetContentName
|
|
|
|
status_t
|
|
|
|
KPartition::SetContentName(const char *name)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
status_t error = set_string(fPartitionData.content_name, name);
|
|
|
|
FireContentNameChanged(fPartitionData.content_name);
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ContentName
|
|
|
|
const char *
|
|
|
|
KPartition::ContentName() const
|
|
|
|
{
|
|
|
|
return fPartitionData.content_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetType
|
|
|
|
status_t
|
|
|
|
KPartition::SetType(const char *type)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
status_t error = set_string(fPartitionData.type, type);
|
|
|
|
FireTypeChanged(fPartitionData.type);
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Type
|
|
|
|
const char *
|
|
|
|
KPartition::Type() const
|
|
|
|
{
|
|
|
|
return fPartitionData.type;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ContentType
|
|
|
|
const char *
|
|
|
|
KPartition::ContentType() const
|
|
|
|
{
|
|
|
|
return fPartitionData.content_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PartitionData
|
|
|
|
partition_data *
|
|
|
|
KPartition::PartitionData()
|
|
|
|
{
|
|
|
|
return &fPartitionData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// PartitionData
|
|
|
|
const partition_data *
|
|
|
|
KPartition::PartitionData() const
|
|
|
|
{
|
|
|
|
return &fPartitionData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetID
|
|
|
|
void
|
|
|
|
KPartition::SetID(partition_id id)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.id != id) {
|
|
|
|
fPartitionData.id = id;
|
|
|
|
FireIDChanged(id);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ID
|
|
|
|
partition_id
|
|
|
|
KPartition::ID() const
|
|
|
|
{
|
|
|
|
return fPartitionData.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPath
|
|
|
|
status_t
|
2004-10-28 01:48:47 +04:00
|
|
|
KPartition::GetPath(KPath *path) const
|
2003-06-10 03:10:09 +04:00
|
|
|
{
|
2003-06-11 02:37:43 +04:00
|
|
|
// For a KDiskDevice this version is never invoked, so the check for
|
|
|
|
// Parent() is correct.
|
2004-10-28 01:48:47 +04:00
|
|
|
if (!path || path->InitCheck() != B_OK || !Parent() || Index() < 0)
|
2003-06-11 02:37:43 +04:00
|
|
|
return B_BAD_VALUE;
|
|
|
|
// get the parent's path
|
|
|
|
status_t error = Parent()->GetPath(path);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
2003-07-05 03:45:26 +04:00
|
|
|
if (Parent()->IsDevice()) {
|
2003-06-11 02:37:43 +04:00
|
|
|
// Our parent is a device, so we replace `raw' by our index.
|
2004-10-28 19:13:08 +04:00
|
|
|
const char *leaf = path->Leaf();
|
|
|
|
if (!leaf || strcmp(leaf, "raw") != B_OK)
|
|
|
|
return B_ERROR;
|
|
|
|
#ifdef _KERNEL_MODE
|
|
|
|
char indexBuffer[12];
|
|
|
|
snprintf(indexBuffer, sizeof(indexBuffer), "%ld", Index());
|
|
|
|
#else
|
|
|
|
const char *prefix = "haiku_";
|
|
|
|
char indexBuffer[strlen(prefix) + 12];
|
|
|
|
snprintf(indexBuffer, sizeof(indexBuffer), "%s%ld", prefix,
|
|
|
|
Index());
|
|
|
|
#endif
|
|
|
|
error = path->ReplaceLeaf(indexBuffer);
|
2003-06-11 02:37:43 +04:00
|
|
|
} else {
|
|
|
|
// Our parent is a normal partition, no device: Append our index.
|
2004-10-28 19:13:08 +04:00
|
|
|
char indexBuffer[13];
|
|
|
|
snprintf(indexBuffer, sizeof(indexBuffer), "_%ld", Index());
|
|
|
|
error = path->Append(indexBuffer, false);
|
2003-06-11 02:37:43 +04:00
|
|
|
}
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetVolumeID
|
|
|
|
void
|
|
|
|
KPartition::SetVolumeID(dev_t volumeID)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.volume != volumeID) {
|
|
|
|
fPartitionData.volume = volumeID;
|
|
|
|
FireVolumeIDChanged(volumeID);
|
|
|
|
if (VolumeID() >= 0)
|
|
|
|
AddFlags(B_PARTITION_MOUNTED);
|
|
|
|
else
|
|
|
|
ClearFlags(B_PARTITION_MOUNTED);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// VolumeID
|
|
|
|
dev_t
|
|
|
|
KPartition::VolumeID() const
|
|
|
|
{
|
2003-06-23 03:04:56 +04:00
|
|
|
return fPartitionData.volume;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2003-09-21 22:25:42 +04:00
|
|
|
// SetMountCookie
|
|
|
|
void
|
|
|
|
KPartition::SetMountCookie(void *cookie)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.mount_cookie != cookie) {
|
|
|
|
fPartitionData.mount_cookie = cookie;
|
|
|
|
FireMountCookieChanged(cookie);
|
|
|
|
}
|
2003-09-21 22:25:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// MountCookie
|
|
|
|
void *
|
|
|
|
KPartition::MountCookie() const
|
|
|
|
{
|
|
|
|
return fPartitionData.mount_cookie;
|
|
|
|
}
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// Mount
|
|
|
|
status_t
|
|
|
|
KPartition::Mount(uint32 mountFlags, const char *parameters)
|
|
|
|
{
|
|
|
|
// not implemented
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unmount
|
|
|
|
status_t
|
|
|
|
KPartition::Unmount()
|
|
|
|
{
|
|
|
|
// not implemented
|
|
|
|
return B_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetParameters
|
|
|
|
status_t
|
|
|
|
KPartition::SetParameters(const char *parameters)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
status_t error = set_string(fPartitionData.parameters, parameters);
|
|
|
|
FireParametersChanged(fPartitionData.parameters);
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Parameters
|
|
|
|
const char *
|
|
|
|
KPartition::Parameters() const
|
|
|
|
{
|
|
|
|
return fPartitionData.parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetContentParameters
|
|
|
|
status_t
|
|
|
|
KPartition::SetContentParameters(const char *parameters)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
status_t error = set_string(fPartitionData.content_parameters, parameters);
|
|
|
|
FireContentParametersChanged(fPartitionData.content_parameters);
|
|
|
|
return error;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ContentParameters
|
|
|
|
const char *
|
|
|
|
KPartition::ContentParameters() const
|
|
|
|
{
|
|
|
|
return fPartitionData.content_parameters;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDevice
|
|
|
|
void
|
|
|
|
KPartition::SetDevice(KDiskDevice *device)
|
|
|
|
{
|
|
|
|
fDevice = device;
|
2003-07-08 21:25:32 +04:00
|
|
|
if (fDevice && fDevice->IsReadOnlyMedia())
|
2003-08-03 22:27:33 +04:00
|
|
|
AddFlags(B_PARTITION_READ_ONLY);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Device
|
|
|
|
KDiskDevice *
|
|
|
|
KPartition::Device() const
|
|
|
|
{
|
|
|
|
return fDevice;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetParent
|
|
|
|
void
|
|
|
|
KPartition::SetParent(KPartition *parent)
|
|
|
|
{
|
2003-06-11 02:37:43 +04:00
|
|
|
// Must be called in a {Add,Remove}Child() only!
|
2003-06-10 03:10:09 +04:00
|
|
|
fParent = parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parent
|
|
|
|
KPartition *
|
|
|
|
KPartition::Parent() const
|
|
|
|
{
|
|
|
|
return fParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddChild
|
|
|
|
status_t
|
|
|
|
KPartition::AddChild(KPartition *partition, int32 index)
|
|
|
|
{
|
|
|
|
// check parameters
|
|
|
|
int32 count = fPartitionData.child_count;
|
|
|
|
if (index == -1)
|
|
|
|
index = count;
|
|
|
|
if (index < 0 || index > count || !partition)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
// add partition
|
2003-06-11 02:37:43 +04:00
|
|
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
|
|
|
if (ManagerLocker locker = manager) {
|
2003-07-02 20:29:33 +04:00
|
|
|
status_t error = fChildren.Insert(partition, index);
|
|
|
|
if (error != B_OK)
|
|
|
|
return error;
|
2003-06-11 02:37:43 +04:00
|
|
|
if (!manager->PartitionAdded(partition)) {
|
2003-07-02 20:29:33 +04:00
|
|
|
fChildren.Erase(index);
|
2003-06-11 02:37:43 +04:00
|
|
|
return B_NO_MEMORY;
|
|
|
|
}
|
|
|
|
partition->SetIndex(index);
|
|
|
|
_UpdateChildIndices(index);
|
|
|
|
fPartitionData.child_count++;
|
|
|
|
partition->SetParent(this);
|
|
|
|
partition->SetDevice(Device());
|
2003-09-29 02:04:13 +04:00
|
|
|
// notify listeners
|
|
|
|
FireChildAdded(partition, index);
|
2003-06-11 02:37:43 +04:00
|
|
|
return B_OK;
|
|
|
|
}
|
|
|
|
return B_ERROR;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
2007-11-02 02:36:21 +03:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
// RemoveChild
|
2003-06-25 03:56:16 +04:00
|
|
|
bool
|
2003-06-10 03:10:09 +04:00
|
|
|
KPartition::RemoveChild(int32 index)
|
|
|
|
{
|
2003-06-25 03:56:16 +04:00
|
|
|
if (index < 0 || index >= fPartitionData.child_count)
|
|
|
|
return false;
|
|
|
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
|
|
|
if (ManagerLocker locker = manager) {
|
2003-07-02 20:29:33 +04:00
|
|
|
KPartition *partition = fChildren.ElementAt(index);
|
2003-06-25 03:56:16 +04:00
|
|
|
PartitionRegistrar _(partition);
|
|
|
|
if (!partition || !manager->PartitionRemoved(partition)
|
2003-07-02 20:29:33 +04:00
|
|
|
|| !fChildren.Erase(index)) {
|
2003-06-25 03:56:16 +04:00
|
|
|
return false;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
2003-06-25 03:56:16 +04:00
|
|
|
_UpdateChildIndices(index + 1);
|
|
|
|
partition->SetIndex(-1);
|
|
|
|
fPartitionData.child_count--;
|
|
|
|
partition->SetParent(NULL);
|
|
|
|
partition->SetDevice(NULL);
|
2003-09-29 02:04:13 +04:00
|
|
|
// notify listeners
|
2007-10-07 19:39:35 +04:00
|
|
|
FireChildRemoved(partition, index);
|
2003-06-25 03:56:16 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveChild
|
|
|
|
bool
|
|
|
|
KPartition::RemoveChild(KPartition *child)
|
|
|
|
{
|
|
|
|
if (child) {
|
|
|
|
int32 index = fChildren.IndexOf(child);
|
|
|
|
if (index >= 0)
|
|
|
|
return RemoveChild(index);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
2003-06-25 03:56:16 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveAllChildren
|
|
|
|
bool
|
|
|
|
KPartition::RemoveAllChildren()
|
|
|
|
{
|
|
|
|
int32 count = CountChildren();
|
|
|
|
for (int32 i = count - 1; i >= 0; i--) {
|
|
|
|
if (!RemoveChild(i))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ChildAt
|
|
|
|
KPartition *
|
|
|
|
KPartition::ChildAt(int32 index) const
|
|
|
|
{
|
2003-07-02 20:29:33 +04:00
|
|
|
return (index >= 0 && index < fChildren.Count()
|
|
|
|
? fChildren.ElementAt(index) : NULL);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// CountChildren
|
|
|
|
int32
|
|
|
|
KPartition::CountChildren() const
|
|
|
|
{
|
|
|
|
return fPartitionData.child_count;
|
|
|
|
}
|
|
|
|
|
2003-08-01 02:48:08 +04:00
|
|
|
// CountDescendants
|
|
|
|
int32
|
|
|
|
KPartition::CountDescendants() const
|
|
|
|
{
|
|
|
|
int32 count = 1;
|
|
|
|
for (int32 i = 0; KPartition *child = ChildAt(i); i++)
|
|
|
|
count += child->CountDescendants();
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2003-08-03 22:27:33 +04:00
|
|
|
// VisitEachDescendant
|
|
|
|
KPartition *
|
|
|
|
KPartition::VisitEachDescendant(KPartitionVisitor *visitor)
|
|
|
|
{
|
|
|
|
if (!visitor)
|
|
|
|
return NULL;
|
|
|
|
if (visitor->VisitPre(this))
|
|
|
|
return this;
|
|
|
|
for (int32 i = 0; KPartition *child = ChildAt(i); i++) {
|
|
|
|
if (KPartition *result = child->VisitEachDescendant(visitor))
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
if (visitor->VisitPost(this))
|
|
|
|
return this;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-06-10 03:10:09 +04:00
|
|
|
|
|
|
|
// SetDiskSystem
|
|
|
|
void
|
|
|
|
KPartition::SetDiskSystem(KDiskSystem *diskSystem)
|
|
|
|
{
|
2003-06-13 02:21:10 +04:00
|
|
|
// unload former disk system
|
|
|
|
if (fDiskSystem) {
|
2003-07-22 04:03:35 +04:00
|
|
|
fPartitionData.content_type = NULL;
|
2003-06-13 02:21:10 +04:00
|
|
|
fDiskSystem->Unload();
|
|
|
|
fDiskSystem = NULL;
|
|
|
|
}
|
|
|
|
// set and load new one
|
2003-06-10 03:10:09 +04:00
|
|
|
fDiskSystem = diskSystem;
|
2003-06-13 02:21:10 +04:00
|
|
|
if (fDiskSystem)
|
2003-06-23 03:04:56 +04:00
|
|
|
fDiskSystem->Load(); // can't fail, since it's already loaded
|
2003-07-08 21:25:32 +04:00
|
|
|
// update concerned partition flags
|
|
|
|
if (fDiskSystem) {
|
2003-07-22 04:03:35 +04:00
|
|
|
fPartitionData.content_type = fDiskSystem->PrettyName();
|
2003-07-08 21:25:32 +04:00
|
|
|
if (fDiskSystem->IsFileSystem())
|
2003-08-03 22:27:33 +04:00
|
|
|
AddFlags(B_PARTITION_FILE_SYSTEM);
|
2003-07-08 21:25:32 +04:00
|
|
|
else
|
2003-08-03 22:27:33 +04:00
|
|
|
AddFlags(B_PARTITION_PARTITIONING_SYSTEM);
|
2003-07-08 21:25:32 +04:00
|
|
|
}
|
2003-09-29 02:04:13 +04:00
|
|
|
// notify listeners
|
|
|
|
FireDiskSystemChanged(fDiskSystem);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// DiskSystem
|
|
|
|
KDiskSystem *
|
|
|
|
KPartition::DiskSystem() const
|
|
|
|
{
|
|
|
|
return fDiskSystem;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParentDiskSystem
|
|
|
|
KDiskSystem *
|
|
|
|
KPartition::ParentDiskSystem() const
|
|
|
|
{
|
2003-06-25 03:56:16 +04:00
|
|
|
return (Parent() ? Parent()->DiskSystem() : NULL);
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetCookie
|
|
|
|
void
|
|
|
|
KPartition::SetCookie(void *cookie)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.cookie != cookie) {
|
|
|
|
fPartitionData.cookie = cookie;
|
|
|
|
FireCookieChanged(cookie);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cookie
|
|
|
|
void *
|
|
|
|
KPartition::Cookie() const
|
|
|
|
{
|
|
|
|
return fPartitionData.cookie;
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetContentCookie
|
|
|
|
void
|
|
|
|
KPartition::SetContentCookie(void *cookie)
|
|
|
|
{
|
2003-09-29 02:04:13 +04:00
|
|
|
if (fPartitionData.content_cookie != cookie) {
|
|
|
|
fPartitionData.content_cookie = cookie;
|
|
|
|
FireContentCookieChanged(cookie);
|
|
|
|
}
|
2003-06-10 03:10:09 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// ContentCookie
|
|
|
|
void *
|
|
|
|
KPartition::ContentCookie() const
|
|
|
|
{
|
|
|
|
return fPartitionData.content_cookie;
|
|
|
|
}
|
|
|
|
|
2003-09-29 02:04:13 +04:00
|
|
|
// AddListener
|
|
|
|
bool
|
|
|
|
KPartition::AddListener(KPartitionListener *listener)
|
|
|
|
{
|
|
|
|
if (!listener)
|
|
|
|
return false;
|
|
|
|
// lazy create listeners
|
|
|
|
if (!fListeners) {
|
|
|
|
fListeners = new(nothrow) ListenerSet;
|
|
|
|
if (!fListeners)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// add listener
|
|
|
|
return (fListeners->Insert(listener) == B_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveListener
|
|
|
|
bool
|
|
|
|
KPartition::RemoveListener(KPartitionListener *listener)
|
|
|
|
{
|
|
|
|
if (!listener || !fListeners)
|
|
|
|
return false;
|
|
|
|
// remove listener and delete the set, if empty now
|
|
|
|
bool result = (fListeners->Remove(listener) > 0);
|
|
|
|
if (fListeners->IsEmpty()) {
|
|
|
|
delete fListeners;
|
|
|
|
fListeners = NULL;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2003-07-22 04:03:35 +04:00
|
|
|
// Changed
|
|
|
|
void
|
2003-07-25 02:56:53 +04:00
|
|
|
KPartition::Changed(uint32 flags, uint32 clearFlags)
|
2003-07-22 04:03:35 +04:00
|
|
|
{
|
2003-07-25 02:56:53 +04:00
|
|
|
fChangeFlags &= ~clearFlags;
|
2003-07-22 04:03:35 +04:00
|
|
|
fChangeFlags |= flags;
|
|
|
|
fChangeCounter++;
|
2003-07-25 02:56:53 +04:00
|
|
|
if (Parent())
|
|
|
|
Parent()->Changed(B_PARTITION_CHANGED_DESCENDANTS);
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetChangeFlags
|
|
|
|
void
|
|
|
|
KPartition::SetChangeFlags(uint32 flags)
|
|
|
|
{
|
|
|
|
fChangeFlags = flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChangeFlags
|
|
|
|
uint32
|
|
|
|
KPartition::ChangeFlags() const
|
|
|
|
{
|
|
|
|
return fChangeFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChangeCounter
|
|
|
|
int32
|
|
|
|
KPartition::ChangeCounter() const
|
|
|
|
{
|
|
|
|
return fChangeCounter;
|
2003-07-22 04:03:35 +04:00
|
|
|
}
|
|
|
|
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-22 04:03:35 +04:00
|
|
|
// UninitializeContents
|
2003-09-28 23:26:18 +04:00
|
|
|
status_t
|
2003-07-22 04:03:35 +04:00
|
|
|
KPartition::UninitializeContents(bool logChanges)
|
|
|
|
{
|
|
|
|
if (DiskSystem()) {
|
2003-07-25 02:56:53 +04:00
|
|
|
uint32 flags = B_PARTITION_CHANGED_INITIALIZATION
|
2007-11-05 03:30:14 +03:00
|
|
|
| B_PARTITION_CHANGED_CONTENT_TYPE
|
|
|
|
| B_PARTITION_CHANGED_STATUS
|
|
|
|
| B_PARTITION_CHANGED_FLAGS;
|
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// children
|
|
|
|
if (CountChildren() > 0) {
|
2003-09-28 23:26:18 +04:00
|
|
|
if (!RemoveAllChildren())
|
|
|
|
return B_ERROR;
|
2003-07-25 02:56:53 +04:00
|
|
|
flags |= B_PARTITION_CHANGED_CHILDREN;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// volume
|
2003-07-22 04:03:35 +04:00
|
|
|
if (VolumeID() >= 0) {
|
2007-11-12 21:41:36 +03:00
|
|
|
status_t error = vfs_unmount(VolumeID(),
|
|
|
|
B_FORCE_UNMOUNT | B_UNMOUNT_BUSY_PARTITION);
|
|
|
|
if (error != B_OK) {
|
|
|
|
dprintf("KPartition::UninitializeContents(): Failed to unmount "
|
|
|
|
"device %ld: %s\n", VolumeID(), strerror(error));
|
|
|
|
}
|
|
|
|
|
2003-07-22 04:03:35 +04:00
|
|
|
SetVolumeID(-1);
|
|
|
|
flags |= B_PARTITION_CHANGED_VOLUME;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// content name
|
2003-07-22 04:03:35 +04:00
|
|
|
if (ContentName()) {
|
|
|
|
SetContentName(NULL);
|
|
|
|
flags |= B_PARTITION_CHANGED_CONTENT_NAME;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// content parameters
|
2003-07-22 04:03:35 +04:00
|
|
|
if (ContentParameters()) {
|
|
|
|
SetContentParameters(NULL);
|
|
|
|
flags |= B_PARTITION_CHANGED_CONTENT_PARAMETERS;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-30 04:21:21 +04:00
|
|
|
// content size
|
|
|
|
if (ContentSize() > 0) {
|
|
|
|
SetContentSize(0);
|
|
|
|
flags |= B_PARTITION_CHANGED_CONTENT_SIZE;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// block size
|
|
|
|
if (Parent() && Parent()->BlockSize() != BlockSize()) {
|
|
|
|
SetBlockSize(Parent()->BlockSize());
|
|
|
|
flags |= B_PARTITION_CHANGED_BLOCK_SIZE;
|
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// disk system
|
2003-07-22 04:03:35 +04:00
|
|
|
DiskSystem()->FreeContentCookie(this);
|
|
|
|
SetDiskSystem(NULL);
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// status
|
|
|
|
SetStatus(B_PARTITION_UNINITIALIZED);
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// flags
|
2003-08-03 22:27:33 +04:00
|
|
|
ClearFlags(B_PARTITION_FILE_SYSTEM | B_PARTITION_PARTITIONING_SYSTEM);
|
2003-07-25 02:56:53 +04:00
|
|
|
if (!Device()->IsReadOnlyMedia())
|
2003-08-03 22:27:33 +04:00
|
|
|
ClearFlags(B_PARTITION_READ_ONLY);
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// log changes
|
|
|
|
if (logChanges) {
|
|
|
|
Changed(flags, B_PARTITION_CHANGED_DEFRAGMENTATION
|
2007-11-05 03:30:14 +03:00
|
|
|
| B_PARTITION_CHANGED_CHECK | B_PARTITION_CHANGED_REPAIR);
|
2003-07-25 02:56:53 +04:00
|
|
|
}
|
2003-07-22 04:03:35 +04:00
|
|
|
}
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-09-28 23:26:18 +04:00
|
|
|
return B_OK;
|
2003-07-22 04:03:35 +04:00
|
|
|
}
|
|
|
|
|
2007-11-05 03:30:14 +03:00
|
|
|
|
2003-07-25 02:56:53 +04:00
|
|
|
// SetAlgorithmData
|
|
|
|
void
|
|
|
|
KPartition::SetAlgorithmData(uint32 data)
|
|
|
|
{
|
|
|
|
fAlgorithmData = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
// AlgorithmData
|
|
|
|
uint32
|
|
|
|
KPartition::AlgorithmData() const
|
|
|
|
{
|
|
|
|
return fAlgorithmData;
|
|
|
|
}
|
|
|
|
|
2003-07-07 03:01:22 +04:00
|
|
|
// WriteUserData
|
|
|
|
void
|
|
|
|
KPartition::WriteUserData(UserDataWriter &writer, user_partition_data *data)
|
|
|
|
{
|
|
|
|
// allocate
|
|
|
|
char *name = writer.PlaceString(Name());
|
|
|
|
char *contentName = writer.PlaceString(ContentName());
|
|
|
|
char *type = writer.PlaceString(Type());
|
|
|
|
char *contentType = writer.PlaceString(ContentType());
|
|
|
|
char *parameters = writer.PlaceString(Parameters());
|
|
|
|
char *contentParameters = writer.PlaceString(ContentParameters());
|
|
|
|
// fill in data
|
|
|
|
if (data) {
|
|
|
|
data->id = ID();
|
|
|
|
data->offset = Offset();
|
|
|
|
data->size = Size();
|
2003-07-30 04:21:21 +04:00
|
|
|
data->content_size = ContentSize();
|
2003-07-07 03:01:22 +04:00
|
|
|
data->block_size = BlockSize();
|
|
|
|
data->status = Status();
|
|
|
|
data->flags = Flags();
|
|
|
|
data->volume = VolumeID();
|
|
|
|
data->index = Index();
|
|
|
|
data->change_counter = ChangeCounter();
|
|
|
|
data->disk_system = (DiskSystem() ? DiskSystem()->ID() : -1);
|
|
|
|
data->name = name;
|
|
|
|
data->content_name = contentName;
|
|
|
|
data->type = type;
|
|
|
|
data->content_type = contentType;
|
|
|
|
data->parameters = parameters;
|
|
|
|
data->content_parameters = contentParameters;
|
|
|
|
data->child_count = CountChildren();
|
2003-09-28 19:15:20 +04:00
|
|
|
// make buffer relocatable
|
|
|
|
writer.AddRelocationEntry(&data->name);
|
|
|
|
writer.AddRelocationEntry(&data->content_name);
|
|
|
|
writer.AddRelocationEntry(&data->type);
|
|
|
|
writer.AddRelocationEntry(&data->content_type);
|
|
|
|
writer.AddRelocationEntry(&data->parameters);
|
|
|
|
writer.AddRelocationEntry(&data->content_parameters);
|
2003-07-07 03:01:22 +04:00
|
|
|
}
|
|
|
|
// children
|
|
|
|
for (int32 i = 0; KPartition *child = ChildAt(i); i++) {
|
|
|
|
user_partition_data *childData
|
|
|
|
= writer.AllocatePartitionData(child->CountChildren());
|
2003-09-28 19:15:20 +04:00
|
|
|
if (data) {
|
2003-07-07 03:01:22 +04:00
|
|
|
data->children[i] = childData;
|
2003-09-28 19:15:20 +04:00
|
|
|
writer.AddRelocationEntry(&data->children[i]);
|
|
|
|
}
|
2003-07-07 03:01:22 +04:00
|
|
|
child->WriteUserData(writer, childData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-23 03:04:56 +04:00
|
|
|
// Dump
|
|
|
|
void
|
|
|
|
KPartition::Dump(bool deep, int32 level)
|
|
|
|
{
|
|
|
|
if (level < 0 || level > 255)
|
|
|
|
return;
|
|
|
|
char prefix[256];
|
|
|
|
sprintf(prefix, "%*s%*s", (int)level, "", (int)level, "");
|
2004-10-28 01:48:47 +04:00
|
|
|
KPath path;
|
|
|
|
GetPath(&path);
|
2003-06-23 03:04:56 +04:00
|
|
|
if (level > 0)
|
2004-10-28 01:48:47 +04:00
|
|
|
OUT("%spartition %ld: %s\n", prefix, ID(), path.Path());
|
2003-06-23 03:04:56 +04:00
|
|
|
OUT("%s offset: %lld\n", prefix, Offset());
|
2003-09-02 08:06:01 +04:00
|
|
|
OUT("%s size: %lld (%.2f MB)\n", prefix, Size(), Size() / (1024.0*1024));
|
2003-07-30 04:21:21 +04:00
|
|
|
OUT("%s content size: %lld\n", prefix, ContentSize());
|
2003-06-23 03:04:56 +04:00
|
|
|
OUT("%s block size: %lu\n", prefix, BlockSize());
|
|
|
|
OUT("%s child count: %ld\n", prefix, CountChildren());
|
|
|
|
OUT("%s index: %ld\n", prefix, Index());
|
|
|
|
OUT("%s status: %lu\n", prefix, Status());
|
|
|
|
OUT("%s flags: %lx\n", prefix, Flags());
|
|
|
|
OUT("%s volume: %ld\n", prefix, VolumeID());
|
|
|
|
OUT("%s disk system: %s\n", prefix,
|
|
|
|
(DiskSystem() ? DiskSystem()->Name() : NULL));
|
|
|
|
OUT("%s name: %s\n", prefix, Name());
|
|
|
|
OUT("%s content name: %s\n", prefix, ContentName());
|
|
|
|
OUT("%s type: %s\n", prefix, Type());
|
|
|
|
OUT("%s content type: %s\n", prefix, ContentType());
|
|
|
|
OUT("%s params: %s\n", prefix, Parameters());
|
|
|
|
OUT("%s content params: %s\n", prefix, ContentParameters());
|
|
|
|
if (deep) {
|
|
|
|
for (int32 i = 0; KPartition *child = ChildAt(i); i++)
|
|
|
|
child->Dump(true, level + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-29 02:04:13 +04:00
|
|
|
// FireOffsetChanged
|
|
|
|
void
|
|
|
|
KPartition::FireOffsetChanged(off_t offset)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->OffsetChanged(this, offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireSizeChanged
|
|
|
|
void
|
|
|
|
KPartition::FireSizeChanged(off_t size)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->SizeChanged(this, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireContentSizeChanged
|
|
|
|
void
|
|
|
|
KPartition::FireContentSizeChanged(off_t size)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ContentSizeChanged(this, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireBlockSizeChanged
|
|
|
|
void
|
|
|
|
KPartition::FireBlockSizeChanged(uint32 blockSize)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->BlockSizeChanged(this, blockSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireIndexChanged
|
|
|
|
void
|
|
|
|
KPartition::FireIndexChanged(int32 index)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->IndexChanged(this, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireStatusChanged
|
|
|
|
void
|
|
|
|
KPartition::FireStatusChanged(uint32 status)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->StatusChanged(this, status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireFlagsChanged
|
|
|
|
void
|
|
|
|
KPartition::FireFlagsChanged(uint32 flags)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->FlagsChanged(this, flags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireNameChanged
|
|
|
|
void
|
|
|
|
KPartition::FireNameChanged(const char *name)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->NameChanged(this, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireContentNameChanged
|
|
|
|
void
|
|
|
|
KPartition::FireContentNameChanged(const char *name)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ContentNameChanged(this, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireTypeChanged
|
|
|
|
void
|
|
|
|
KPartition::FireTypeChanged(const char *type)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->TypeChanged(this, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireIDChanged
|
|
|
|
void
|
|
|
|
KPartition::FireIDChanged(partition_id id)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->IDChanged(this, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireVolumeIDChanged
|
|
|
|
void
|
|
|
|
KPartition::FireVolumeIDChanged(dev_t volumeID)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->VolumeIDChanged(this, volumeID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireMountCookieChanged
|
|
|
|
void
|
|
|
|
KPartition::FireMountCookieChanged(void *cookie)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->MountCookieChanged(this, cookie);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireParametersChanged
|
|
|
|
void
|
|
|
|
KPartition::FireParametersChanged(const char *parameters)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ParametersChanged(this, parameters);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireContentParametersChanged
|
|
|
|
void
|
|
|
|
KPartition::FireContentParametersChanged(const char *parameters)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ContentParametersChanged(this, parameters);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireChildAdded
|
|
|
|
void
|
|
|
|
KPartition::FireChildAdded(KPartition *child, int32 index)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ChildAdded(this, child, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireChildRemoved
|
|
|
|
void
|
|
|
|
KPartition::FireChildRemoved(KPartition *child, int32 index)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ChildRemoved(this, child, index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireDiskSystemChanged
|
|
|
|
void
|
|
|
|
KPartition::FireDiskSystemChanged(KDiskSystem *diskSystem)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->DiskSystemChanged(this, diskSystem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireCookieChanged
|
|
|
|
void
|
|
|
|
KPartition::FireCookieChanged(void *cookie)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->CookieChanged(this, cookie);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FireContentCookieChanged
|
|
|
|
void
|
|
|
|
KPartition::FireContentCookieChanged(void *cookie)
|
|
|
|
{
|
|
|
|
if (fListeners) {
|
|
|
|
for (ListenerSet::Iterator it = fListeners->Begin();
|
|
|
|
it != fListeners->End(); ++it) {
|
|
|
|
(*it)->ContentCookieChanged(this, cookie);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-06-11 02:37:43 +04:00
|
|
|
// _UpdateChildIndices
|
|
|
|
void
|
|
|
|
KPartition::_UpdateChildIndices(int32 index)
|
|
|
|
{
|
2003-07-02 20:29:33 +04:00
|
|
|
for (int32 i = index; i < fChildren.Count(); i++)
|
|
|
|
fChildren.ElementAt(i)->SetIndex(i);
|
2003-06-11 02:37:43 +04:00
|
|
|
}
|
|
|
|
|
2003-06-13 02:21:10 +04:00
|
|
|
// _NextID
|
|
|
|
int32
|
|
|
|
KPartition::_NextID()
|
|
|
|
{
|
|
|
|
return atomic_add(&fNextID, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// fNextID
|
|
|
|
int32 KPartition::fNextID = 0;
|
|
|
|
|