diff --git a/headers/private/kernel/disk_device_manager/KDiskDevice.h b/headers/private/kernel/disk_device_manager/KDiskDevice.h new file mode 100644 index 0000000000..9c97767143 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskDevice.h @@ -0,0 +1,56 @@ +// KDiskDevice.h + +#ifndef _K_DISK_DEVICE_H +#define _K_DISK_DEVICE_H + +#include + +#include "KPartition.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDevice : public KPartition { + KDiskDevice(partition_id id = -1); + virtual ~KDiskDevice(); + + // A read lock owner can be sure that the device (incl. all of its + // partitions won't be changed). + // A write lock owner is moreover allowed to make changes. + // The hierarchy is additionally protected by the disk device manager's + // lock -- only a device write lock owner is allowed to change it, but + // manager lock owners can be sure, that it won't change. + bool ReadLock(); + void ReadUnlock(); + bool WriteLock(); + void WriteUnlock(); + + void SetDeviceFlags(uint32 flags); // comprises the ones below + uint32 DeviceFlags() const; + bool IsRemovable() const; + bool HasMedia() const; + + status_t SetPath(const char *path); + virtual status_t GetPath(char *path) const; + + // File descriptor: Set only from a kernel thread, valid only for + // kernel threads. + void SetFD(int fd); + int FD() const; + + // access to C style device data + disk_device_data *DeviceData(); + const disk_device_data *DeviceData() const; + + virtual KPartition *CreateShadowPartition(); + + void SetShadowOwner(team_id team); + team_id ShadowOwner() const; +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskDevice; + +#endif // _K_DISK_DEVICE_H diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h b/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h new file mode 100644 index 0000000000..fdeddc21ef --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceJob.h @@ -0,0 +1,57 @@ +// KDiskDeviceJob.h + +#ifndef _K_DISK_DEVICE_JOB_H +#define _K_DISK_DEVICE_JOB_H + +#include "disk_device_manager.h" + +struct user_disk_device_job_info; + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDeviceJob { +public: + KDiskDeviceJob(partition_id partition, partition_id scope = -1); + virtual ~KDiskDeviceJob(); + + disk_job_id ID() const; + + void SetStatus(uint32 status); + uint32 Status() const; + + void SetDescription(const char *description); + const char *Description() const; + // Maybe better just a virtual void GetDescription(char*)? + + void SetPartitionID(partition_id partitionID); + // Probably not needed, since passed to the constructor. + partition_id PartitionID() const; + partition_id ScopeID() const; + + virtual void UpdateProgress(float progress); + // may trigger a notification + // virtual, since some jobs are composed of several tasks (e.g. Move). + // We might want to explicitly support subtasks in the base class, or + // even in the userland API. + void UpdateExtraProgress(const char *info); + // triggers a notification + float Progress() const; + + status_t GetInfo(user_disk_device_job_info *info); + + virtual status_t Do(); + + // TODO: Do we want to add a Cancel() here? We probably can't tell the + // disk system directly anyway. That is, if the job is in progress, + // the disk system would have to check the job status periodically + // to find out, if the job had been canceled. But then a + // SetStatus(B_DISK_DEVICE_JOB_CANCELED) would be sufficient. +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskDeviceJob; + +#endif // _DISK_DEVICE_JOB_H diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceJobFactory.h b/headers/private/kernel/disk_device_manager/KDiskDeviceJobFactory.h new file mode 100644 index 0000000000..6b689908e7 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceJobFactory.h @@ -0,0 +1,44 @@ +// KDiskDeviceJob.h + +#ifndef _K_DISK_DEVICE_JOB_FACTORY_H +#define _K_DISK_DEVICE_JOB_FACTORY_H + +#include "disk_device_manager.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDeviceJob; + +class KDiskDeviceJobFactory { +public: + KDiskDeviceJobFactory(); + ~KDiskDeviceJobFactory(); + + KDiskDeviceJob *CreateCreateChildJob(partition_id partition, + partition_id child, off_t offset, + off_t size, const char *parameters); + KDiskDeviceJob *CreateDefragmentJob(partition_id partition); + KDiskDeviceJob *CreateDeleteChildJob(partition_id parent, + partition_id partition); + KDiskDeviceJob *CreateScanPartitionJob(partition_id partition); + KDiskDeviceJob *CreateInitializeJob(partition_id partition, + disk_system_id diskSystemID, + const char *parameters); + KDiskDeviceJob *CreateMoveJob(partition_id parent, partition_id partition, + off_t offset); + KDiskDeviceJob *CreateRepairJob(partition_id partition); + KDiskDeviceJob *CreateResizeJob(partition_id parent, + partition_id partition, off_t size); + KDiskDeviceJob *CreateSetParametersJob(partition_id parent, + partition_id partition, + const char *parameters, + const char *contentParameters); +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskDeviceJobQueue; + +#endif // _K_DISK_DEVICE_JOB_FACTORY_H diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceJobQueue.h b/headers/private/kernel/disk_device_manager/KDiskDeviceJobQueue.h new file mode 100644 index 0000000000..f708a71afd --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceJobQueue.h @@ -0,0 +1,39 @@ +// KDiskDeviceJobQueue.h + +#ifndef _K_DISK_DEVICE_JOB_QUEUE_H +#define _K_DISK_DEVICE_JOB_QUEUE_H + +#include "disk_device_manager.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDevice; +class KDiskDeviceJob; + +class KDiskDeviceJobQueue { +public: + KDiskDeviceJobQueue(); + ~KDiskDeviceJobQueue(); + + void SetDevice(KDiskDevice *device); + KDiskDevice *Device() const; + + KDiskDeviceJob *ActiveJob() const; // is not in list of scheduled jobs + + // list of scheduled jobs + bool AddJob(KDiskDeviceJob *job); + KDiskDeviceJob *RemoveJob(int32 index); + bool RemoveJob(KDiskDeviceJob *job); + KDiskDeviceJob *JobAt(int32 index) const; + int32 CountJobs() const; + + void Execute(); +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskDeviceJobQueue; + +#endif // _K_DISK_DEVICE_JOB_QUEUE_H diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h b/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h new file mode 100644 index 0000000000..3f7b990b4a --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h @@ -0,0 +1,77 @@ +// KDiskDeviceManager.h + +#ifndef _K_DISK_DEVICE_MANAGER_H +#define _K_DISK_DEVICE_MANAGER_H + +#include "disk_device_manager.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDevice; +class KDiskDeviceJob; +class KDiskDeviceJobQueue; +class KDiskSystem; +class KPartition; + +class KDiskDeviceManager { + KDiskDeviceManager(); + ~KDiskDeviceManager(); + + // Singleton Creation, Deletion, and Access + + static status_t CreateDefault(); + static void DeleteDefault(); + static KDiskDeviceManager *Default(); + + // Locking + + bool Lock(); + void Unlock(); + + // Disk Device / Partition Management + + KDiskDevice *RegisterDevice(const char *path, bool noShadow = true); + KDiskDevice *RegisterDevice(partition_id id, bool noShadow = true); + KPartition *RegisterPartition(const char *path, bool noShadow = true); + KPartition *RegisterPartition(partition_id id, bool noShadow = true); + + // manager must be locked + int32 CountDiskDevices() const; + KDiskDevice *DiskDeviceAt(int32 index) const; + + void PartitionAdded(KPartition *partition); // implementation internal + void PartitionRemoved(KPartition *partition); // + + // Jobs + + // manager must be locked + KDiskDeviceJob *JobWithID(disk_job_id id) const; + int32 CountJobs() const; + KDiskDeviceJob *JobAt(int32 index) const; + + // manager must be locked + bool AddJobQueue(KDiskDeviceJobQueue *jobQueue) const; + int32 CountJobQueues() const; + KDiskDeviceJobQueue *JobQueueAt(int32 index) const; + + // Disk Systems + + // manager must be locked + KDiskSystem *DiskSystemWithName(const char *name); + KDiskSystem *DiskSystemWithID(disk_system_id id); + int32 CountDiskSystems() const; + KDiskSystem *DiskSystemAt(int32 index) const; + + // Watching + + // TODO: Watching service for the kernel. The userland watching is handled + // by the registrar. +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskDeviceManager; + +#endif // _K_DISK_DEVICE_MANAGER_H diff --git a/headers/private/kernel/disk_device_manager/KDiskSystem.h b/headers/private/kernel/disk_device_manager/KDiskSystem.h new file mode 100644 index 0000000000..ea5a47f34f --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KDiskSystem.h @@ -0,0 +1,113 @@ +// KDiskSystem.h + +#ifndef _K_DISK_DEVICE_SYSTEM_H +#define _K_DISK_DEVICE_SYSTEM_H + +#include "disk_device_manager.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDeviceJob; +class KPartition; + +class KDiskSystem { + KDiskSystem(const char *name); + virtual ~KDiskSystem(); + + void SetID(disk_system_id id); + disk_system_id ID() const; + const char *Name() const; + // We might want to introduce another name -- a more user friendly one. + // This one is the name of the partition module/FS add-on, e.g. + // "intel/extended", "bfs". + + virtual bool IsFileSystem() const; + bool IsPartitioningSystem() const; + + virtual status_t Load(); // load/unload -- can be nested + virtual status_t Unload(); // + virtual bool IsLoaded() const; + + // Scanning + // Device must be write locked. + + virtual float Identify(KPartition *partition, void **cookie); + virtual status_t Scan(KPartition *partition, void *cookie); + virtual void FreeIdentifyCookie(KPartition *partition, void *cookie); + virtual void FreeCookie(KPartition *partition); + virtual void FreeContentCookie(KPartition *partition); + + // Querying + // Device must be read locked. + + virtual bool SupportsDefragmenting(KPartition *partition, + bool *whileMounted); + virtual bool SupportsRepairing(KPartition *partition, bool checkOnly, + bool *whileMounted); + virtual bool SupportsResizing(KPartition *partition, bool *whileMounted); + virtual bool SupportsResizingChild(KPartition *child); + virtual bool SupportsMoving(KPartition *partition, bool *whileMounted); + virtual bool SupportsMovingChild(KPartition *child); + virtual bool SupportsParentSystem(KDiskSystem *system); + virtual bool SupportsChildSystem(KDiskSystem *system); + + virtual bool ValidateResize(KPartition *partition, off_t *size); + virtual bool ValidateMove(KPartition *partition, off_t *start); + virtual bool ValidateResizeChild(KPartition *partition, off_t *size); + virtual bool ValidateMoveChild(KPartition *partition, off_t *start); + virtual bool ValidateCreateChild(KPartition *partition, off_t *start, + off_t *size, const char *parameters); + virtual bool ValidateInitialize(KPartition *partition, + const char *parameters); + virtual bool ValidateSetParameters(KPartition *partition, + const char *parameters); + virtual bool ValidateSetContentParameters(KPartition *child, + const char *parameters); + virtual int32 CountPartitionableSpaces(KPartition *partition); + virtual bool GetPartitionableSpaces(KPartition *partition, + partitionable_space_data *spaces, + int32 count, + int32 *actualCount = NULL); + + // Writing + // Device should not be locked. + + virtual status_t Defragment(KPartition *partition, KDiskDeviceJob *job); + virtual status_t Repair(KPartition *partition, bool checkOnly, + KDiskDeviceJob *job); + virtual status_t Resize(KPartition *partition, off_t size, + KDiskDeviceJob *job); + virtual status_t ResizeChild(KPartition *child, off_t size, + KDiskDeviceJob *job); + virtual status_t Move(KPartition *partition, off_t offset, + KDiskDeviceJob *job); + virtual status_t MoveChild(KPartition *child, off_t offset, + KDiskDeviceJob *job); + virtual status_t CreateChild(KPartition *partition, off_t offset, + off_t size, const char *parameters, + KDiskDeviceJob *job, + KPartition **child = NULL, + partition_id childID = -1); + // optional childID parameter or allow setting the ID later? + virtual status_t DeleteChild(KPartition *child, KDiskDeviceJob *job); + virtual status_t Initialize(KPartition *partition, const char *parameters, + KDiskDeviceJob *job); + virtual status_t SetParameters(KPartition *partition, + const char *parameters, + KDiskDeviceJob *job); + virtual status_t SetContentParameters(KPartition *partition, + const char *parameters, + KDiskDeviceJob *job); +// The KPartition* parameters for the writing methods are a bit `volatile', +// since the device will not be locked, when they are called. The KPartition +// is registered though, so that it is at least guaranteed that the object +// won't go away. +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KDiskSystem; + +#endif // _K_DISK_DEVICE_SYSTEM_H diff --git a/headers/private/kernel/disk_device_manager/KFileSystem.h b/headers/private/kernel/disk_device_manager/KFileSystem.h new file mode 100644 index 0000000000..ae26d26edc --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KFileSystem.h @@ -0,0 +1,70 @@ +// KFileSystem.h +// +// KFileSystem implements the KDiskSystem interface for file systems. +// It works with the FS API. + +#ifndef _K_FILE_DISK_DEVICE_SYSTEM_H +#define _K_FILE_DISK_DEVICE_SYSTEM_H + +#include "KDiskSystem.h" + +namespace BPrivate { +namespace DiskDevice { + +class KFileSystem { + KFileSystem(const char *name); + virtual ~KFileSystem(); + + virtual bool IsFileSystem() const; + + virtual status_t Load(); // load/unload -- can be nested + virtual status_t Unload(); // + virtual bool IsLoaded() const; + + // Scanning + + virtual float Identify(KPartition *partition, void **cookie); + virtual status_t Scan(KPartition *partition, void *cookie); + virtual void FreeIdentifyCookie(KPartition *partition, void *cookie); + virtual void FreeContentCookie(KPartition *partition); + + // Querying + + virtual bool SupportsDefragmenting(KPartition *partition, + bool *whileMounted); + virtual bool SupportsRepairing(KPartition *partition, bool checkOnly, + bool *whileMounted); + virtual bool SupportsResizing(KPartition *partition, bool *whileMounted); + virtual bool SupportsMoving(KPartition *partition, bool *whileMounted); + virtual bool SupportsParentSystem(KDiskSystem *system); + + virtual bool ValidateResize(KPartition *partition, off_t *size); + virtual bool ValidateMove(KPartition *partition, off_t *start); + virtual bool ValidateInitialize(KPartition *partition, + const char *parameters); + virtual bool ValidateSetContentParameters(KPartition *child, + const char *parameters); + + // Writing + + virtual status_t Defragment(KPartition *partition, KDiskDeviceJob *job); + virtual status_t Repair(KPartition *partition, bool checkOnly, + KDiskDeviceJob *job); + virtual status_t Resize(KPartition *partition, off_t size, + KDiskDeviceJob *job); + virtual status_t Move(KPartition *partition, off_t offset, + KDiskDeviceJob *job); + virtual status_t Initialize(KPartition *partition, const char *parameters, + KDiskDeviceJob *job); + virtual status_t SetContentParameters(KPartition *partition, + const char *parameters, + KDiskDeviceJob *job); + +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KFileSystem; + +#endif // _K_FILE_DISK_DEVICE_SYSTEM_H diff --git a/headers/private/kernel/disk_device_manager/KPartition.h b/headers/private/kernel/disk_device_manager/KPartition.h new file mode 100644 index 0000000000..0aa610f276 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KPartition.h @@ -0,0 +1,157 @@ +// KPartition.h + +#ifndef _K_DISK_DEVICE_PARTITION_H +#define _K_DISK_DEVICE_PARTITION_H + +#include "disk_device_manager.h" +#include "List.h" + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDevice; +class KDiskSystem; + +// partition flags +// TODO: move to another header (must be accessible from userland API impl.) +enum { + B_PARTITION_IS_DEVICE = 0x01, + B_PARTITION_MOUNTABLE = 0x02, + B_PARTITION_PARTITIONABLE = 0x04, + B_PARTITION_READ_ONLY = 0x08, + B_PARTITION_MOUNTED = 0x10, // needed? + B_PARTITION_BUSY = 0x20, + B_PARTITION_DESCENDANT_BUSY = 0x40, +}; + +class KPartition { + KPartition(partition_id id = -1); + virtual ~KPartition(); + + // Reference counting. As long as there's at least one referrer, the + // object won't be deleted. + // manager must be locked + bool Register(); + bool Unregister(); + int32 CountReferences() const; + + void SetBusy(bool busy); + bool IsBusy() const; + // == jobs which may affect this partition are scheduled/in progress + void SetDescendantBusy(bool busy); + 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. + + void SetOffset(off_t offset); + off_t Offset() const; // 0 for devices + + void SetSize(off_t size); + off_t Size() const; + + void SetBlockSize(uint32 blockSize); + uint32 BlockSize() const; + + void SetIndex(int32 index); + int32 Index() const; // 0 for devices + + void SetStatus(uint32 status); + uint32 Status() const; + + void SetFlags(uint32 flags); // comprises the ones below + uint32 Flags() const; + bool IsMountable() const; + bool IsPartitionable() const; + bool IsReadOnly() const; + bool IsMounted() const; + + bool IsDevice() const; + + status_t SetName(const char *name); + const char *Name() const; + + status_t SetContentName(const char *name); + const char *ContentName() const; + + status_t SetType(const char *type); + const char *Type() const; + + status_t SetContentType(const char *type); + const char *ContentType() const; + + // access to C style partition data + partition_data *PartitionData(); + const partition_data *PartitionData() const; + + void SetID(partition_id id); + partition_id ID() const; + + int32 ChangeCounter() const; + + virtual status_t GetPath(char *path) const; + // no setter (see BDiskDevice) -- built on the fly + + void SetVolumeID(dev_t volumeID); + dev_t VolumeID() const; + + status_t Mount(uint32 mountFlags, const char *parameters); + status_t Unmount(); + + // Parameters + + status_t SetParameters(const char *parameters); + const char *Parameters() const; + + status_t SetContentParameters(const char *parameters); + const char *ContentParameters() const; + + // Hierarchy + + void SetDevice(KDiskDevice *device); + KDiskDevice *Device() const; + + void SetParent(KPartition *parent); + KPartition *Parent() const; + + status_t AddChild(KPartition *partition, int32 index = -1); + KPartition *RemoveChild(int32 index); + KPartition *ChildAt(int32 index) const; + int32 CountChildren() const; + + // Shadow Partition + + virtual KPartition *CreateShadowPartition(); // creates a complete tree + void DeleteShadowPartition(); // deletes ... + KPartition *ShadowPartition() const; + bool IsShadowPartition() const; + + // DiskSystem + + void SetDiskSystem(KDiskSystem *diskSystem); + KDiskSystem *DiskSystem() const; + void SetParentDiskSystem(KDiskSystem *diskSystem); + KDiskSystem *ParentDiskSystem() const; + + void SetCookie(void *cookie); + void *Cookie() const; + + void SetContentCookie(void *cookie); + void *ContentCookie() const; + +protected: + partition_data fPartitionData; + List fChildren; + KDiskDevice *fDevice; + KPartition *fParent; + KDiskSystem *fDiskSystem; + KDiskSystem *fParentDiskSystem; + int32 fReferenceCount; +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KPartition; + +#endif // _K_DISK_DEVICE_PARTITION_H diff --git a/headers/private/kernel/disk_device_manager/KPartitioningSystem.h b/headers/private/kernel/disk_device_manager/KPartitioningSystem.h new file mode 100644 index 0000000000..5134894a17 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KPartitioningSystem.h @@ -0,0 +1,90 @@ +// KPartitioningSystem.h + +#ifndef _K_PARTITIONING_DISK_DEVICE_SYSTEM_H +#define _K_PARTITIONING_DISK_DEVICE_SYSTEM_H + +#include "KDiskSystem.h" + +namespace BPrivate { +namespace DiskDevice { + +class KPartitioningSystem { + KPartitioningSystem(const char *name); + virtual ~KPartitioningSystem(); + + virtual bool IsFileSystem() const; + + virtual status_t Load(); // load/unload -- can be nested + virtual status_t Unload(); // + virtual bool IsLoaded() const; + + // Scanning + + virtual float Identify(KPartition *partition, void **cookie); + virtual status_t Scan(KPartition *partition, void *cookie); + virtual void FreeIdentifyCookie(KPartition *partition, void *cookie); + virtual void FreeCookie(KPartition *partition); + virtual void FreeContentCookie(KPartition *partition); + + // Querying + + virtual bool SupportsRepairing(KPartition *partition, bool checkOnly, + bool *whileMounted); + // Does that makes sense for partitioning systems? + virtual bool SupportsResizing(KPartition *partition, bool *whileMounted); + virtual bool SupportsResizingChild(KPartition *child); + virtual bool SupportsMoving(KPartition *partition, bool *whileMounted); + virtual bool SupportsMovingChild(KPartition *child); + virtual bool SupportsParentSystem(KDiskSystem *system); + virtual bool SupportsChildSystem(KDiskSystem *system); + + virtual bool ValidateResize(KPartition *partition, off_t *size); + virtual bool ValidateMove(KPartition *partition, off_t *start); + virtual bool ValidateResizeChild(KPartition *partition, off_t *size); + virtual bool ValidateMoveChild(KPartition *partition, off_t *start); + virtual bool ValidateCreateChild(KPartition *partition, off_t *start, + off_t *size, const char *parameters); + virtual bool ValidateInitialize(KPartition *partition, + const char *parameters); + virtual bool ValidateSetParameters(KPartition *partition, + const char *parameters); + virtual bool ValidateSetContentParameters(KPartition *child, + const char *parameters); + virtual bool GetPartitionableSpaces(KPartition *partition, + partitionable_space_data **spaces, + int32 *count); + + // Writing + + virtual status_t Repair(KPartition *partition, bool checkOnly, + KDiskDeviceJob *job); + virtual status_t Resize(KPartition *partition, off_t size, + KDiskDeviceJob *job); + virtual status_t ResizeChild(KPartition *child, off_t size, + KDiskDeviceJob *job); + virtual status_t Move(KPartition *partition, off_t offset, + KDiskDeviceJob *job); + virtual status_t MoveChild(KPartition *child, off_t offset, + KDiskDeviceJob *job); + virtual status_t CreateChild(KPartition *partition, off_t offset, + off_t size, const char *parameters, + KDiskDeviceJob *job, + KPartition **child = NULL, + partition_id childID = -1); + virtual status_t DeleteChild(KPartition *child, KDiskDeviceJob *job); + virtual status_t Initialize(KPartition *partition, const char *parameters, + KDiskDeviceJob *job); + virtual status_t SetParameters(KPartition *partition, + const char *parameters, + KDiskDeviceJob *job); + virtual status_t SetContentParameters(KPartition *partition, + const char *parameters, + KDiskDeviceJob *job); +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KPartitioningSystem; + +#endif // _K_PARTITIONING_DISK_DEVICE_SYSTEM_H diff --git a/headers/private/kernel/disk_device_manager/ddm_modules.h b/headers/private/kernel/disk_device_manager/ddm_modules.h new file mode 100644 index 0000000000..b230549ec1 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/ddm_modules.h @@ -0,0 +1,140 @@ +// ddm_modules.h +// +// Interfaces to be implemented by partition modules/FS add-ons. +// For better readibility this is not yet a module interface, but just a +// listing of functions. + +#ifndef _K_DISK_DEVICE_MODULES_H +#define _K_DISK_DEVICE_MODULES_H + +#include + +// partition module interface + +// scanning +// (the device is write locked) +float identify_partition(int deviceFD, partition_data *partition, + void **cookie); +status_t scan_partition(int deviceFD, partition_data *partition, + void *identifyCookie); +void free_identify_partition_cookie(partition_data *partition, void *cookie); +void free_partition_cookie(partition_data *partition); +void free_partition_content_cookie(partition_data *partition); + +// querying +// (the device is read locked) +bool supports_reparing_partition(partition_data *partition, bool checkOnly, + bool *whileMounted); +bool supports_resizing_partition(partition_data *partition, + bool *whileMounted); +bool supports_resizing_child_partition(partition_data *partition, + partition_data *child); +bool supports_moving_partition(partition_data *partition, bool *whileMounted); +bool supports_moving_child_partition(partition_data *partition, + partition_data *child); +bool supports_parent_system(const char *system); +bool supports_child_system(const char *system); + +bool validate_resize_partition(partition_data *partition, off_t *size); +bool validate_move_partition(partition_data *partition, off_t *start); +bool validate_resize_child_partition(partition_data *partition, + partition_data *child, off_t *size); +bool validate_move_child_partition(partition_data *partition, + partition_data *child, off_t *start); +bool validate_create_child_partition(partition_data *partition, + partition_data *child, off_t *start, + off_t *size, const char *parameters); +bool validate_initialize_partition(partition_data *partition, + const char *parameters); +bool validate_set_partition_parameters(partition_data *partition, + const char *parameters); +bool validate_set_partition_content_parameters(partition_data *partition, + const char *parameters); +bool get_partitionable_spaces(partition_data *partition, + partitionable_space_data *spaces, + int32 count, int32 *actualCount); + // When not implemented, a standard algorithm is used. + +// Alternatively we can multiplex the supports_*()/validate_*() hooks +// (see supports_validates_parameters.h for parameters): +bool supports_partition_operation(uint32 operation, void *parameters); +bool validate_partition_operation(uint32 operation, void *parameters); +// (same holds for the FS add-on API, of course) + +// writing +// (device is NOT locked) +status_t repair_partition(int deviceFD, partition_id partition, + bool checkOnly, disk_job_id job); +status_t resize_partition(int deviceFD, partition_id partition, off_t size, + disk_job_id job); +status_t resize_child_partition(int deviceFD, partition_id partition, + off_t size, disk_job_id job); +status_t move_partition(int deviceFD, partition_id partition, off_t offset, + disk_job_id job); +status_t move_child_partition(int deviceFD, partition_id partition, + partition_id child, off_t offset, + disk_job_id job); +status_t create_child_partition(int deviceFD, partition_id partition, + off_t offset, off_t size, + const char *parameters, disk_job_id job, + partition_id *childID); + // childID is used for the return value, but is also an optional input + // parameter -- -1 to be ignored +status_t delete_child_partition(int deviceFD, partition_id partition, + partition_id child, disk_job_id job); +status_t initialize_partition(int deviceFD, partition_id partition, + const char *parameters, disk_job_id job); +status_t set_parameters_partition(int deviceFD, partition_id partition, + const char *parameters, disk_job_id job); +status_t set_partition_content_parameters(int deviceFD, partition_id partition, + const char *parameters, + disk_job_id job); + + +// FS add-on interface + +// scanning +// (the device is write locked) +float identify_partition(const char *partitionPath, partition_data *partition, + void **cookie); +status_t scan_partition(const char *partitionPath, partition_data *partition, + void *identifyCookie); +void free_identify_partition_cookie(partition_data *partition, void *cookie); +void free_partition_content_cookie(partition_data *partition, void *cookie); + +// querying +// (the device is read locked) +bool supports_defragmenting_partition(partition_data *partition, + bool *whileMounted); +bool supports_reparing_partition(partition_data *partition, bool checkOnly, + bool *whileMounted); +bool supports_resizing_partition(partition_data *partition, + bool *whileMounted); +bool supports_moving_partition(partition_data *partition, bool *whileMounted); +bool supports_parent_system(const char *system); + +bool validate_resize_partition(partition_data *partition, off_t *size); +bool validate_move_partition(partition_data *partition, off_t *start); +bool validate_initialize_partition(partition_data *partition, + const char *parameters); +bool validate_set_partition_content_parameters(partition_data *partition, + const char *parameters); + +// writing +// (the device is NOT locked) +status_t defragment_partition(int fd, partition_id partition, disk_job_id job); +status_t repair_partition(int fd, partition_id partition, bool checkOnly, + disk_job_id job); +status_t resize_partition(int fd, partition_id partition, off_t size, + disk_job_id job); +status_t move_partition(int fd, partition_id partition, off_t offset, + disk_job_id job); +status_t initialize_partition(const char *partition, const char *parameters, + disk_job_id job); + // This is pretty close to how the hook in R5 looked. Save the job ID, of + // course and that the parameters were given as (void*, size_t) pair. +status_t set_partition_content_parameters(int fd, partition_id partition, + const char *parameters, + disk_job_id job); + +#endif // _K_DISK_DEVICE_MODULES_H diff --git a/headers/private/kernel/disk_device_manager/ddm_userland_interface.h b/headers/private/kernel/disk_device_manager/ddm_userland_interface.h new file mode 100644 index 0000000000..b5ae3133fe --- /dev/null +++ b/headers/private/kernel/disk_device_manager/ddm_userland_interface.h @@ -0,0 +1,114 @@ +// ddm_userland_interface.h + +#ifndef _DISK_DEVICE_MANAGER_USERLAND_INTERFACE_H +#define _DISK_DEVICE_MANAGER_USERLAND_INTERFACE_H + +#include "disk_device_manager.h" + +// userland partition representation +struct user_partition_data { + partition_id id; + off_t offset; + off_t size; + uint32 block_size; + uint32 status; + uint32 flags; + dev_t volume; + int32 change_counter; // needed? + char *name; + char *content_name; + char *type; + char *content_type; + char *parameters; + char *content_parameters; + void *user_data; + int32 child_count; + user_partition_data *children[1]; +}; + +// userland disk device representation +struct user_disk_device_data { + uint32 device_flags; + char *path; + user_partition_data device_partition_data; +}; + +// userland partitionable space representation +struct user_partitionable_space_data { + off_t offset; + off_t size; +}; + +// userland disk device job representation +struct user_disk_device_job_info { + disk_job_id id; + uint32 type; + partition_id partition; + char desription[256]; +}; + +// iterating, retrieving device/partition data +partition_id get_next_disk_device_id(int32 *cookie, size_t neededSize = NULL); +status_t get_disk_device_data(partition_id deviceID, bool shadow, + user_disk_device_data *buffer, + size_t bufferSize, size_t *neededSize); +status_t get_partition_data(partition_id partitionID, bool shadow, + user_partition_data *buffer, + size_t bufferSize, size_t *neededSize); + // Dangerous?! +status_t get_partitionable_spaces(partition_id partitionID, bool shadow, + user_partitionable_space_data *buffer, + size_t bufferSize, size_t *neededSize); + // Pass the partition change counter? If GetPartitionInfo() is only + // allowed, when the device is locked, then we wouldn't need it. + +// disk systems +status_t find_disk_system(const char *name, disk_system_id *id); +status_t get_next_disk_system(disk_system_id *id, char *name, int32 *cookie); +bool supports_partition_operation(uint32 operation, void *parameters); +bool validate_partition_operation(uint32 operation, void *parameters); + // TODO: Sorry, I was too lazy: supports_validates_parameters.h is only + // for kernel internal use. There needs to be something similar for these + // functions. + +// partition modification +status_t prepare_disk_device_modifications(partition_id device); +status_t commit_disk_device_modifications(partition_id device, port_id port, + int32 token, bool completeProgress); +status_t cancel_disk_device_modifications(partition_id device); +bool is_disk_device_modified(partition_id device); + +status_t defragment_partition(partition_id partition); +status_t repair_partition(partition_id partition, bool checkOnly); +status_t resize_partition(partition_id partition, off_t size); +status_t move_partition(partition_id partition, off_t offset); +status_t set_partition_parameters(partition_id partition, + const char *parameters, + const char *contentParameters); +status_t initialize_partition(partition_id partition, const char *diskSystem, + const char *parameters); + // Note: There is also fs_initialize_volume(), which is not compatible + // with this function, for it is more general with respect to how the + // volume to be initialized is specified (though this might be solved + // by providing an API for registering files as disk devices), and more + // specific regarding the other parameters (flags and volumeName). +status_t create_child_partition(partition_id partition, off_t offset, + off_t size, const char *parameters, + partition_id *child); +status_t delete_partition(partition_id partition); + +// jobs +status_t get_next_disk_device_job_info(user_disk_device_job_info *info, + int32 *cookie); +status_t get_disk_device_job_info(disk_job_id id, + user_disk_device_job_info *info); +status_t get_disk_device_job_status(disk_job_id id, uint32 *status, + float *progress); + +// watching +status_t start_disk_device_watching(port_id, int32 token, uint32 flags); +status_t start_disk_device_job_watching(disk_job_id job, port_id, int32 token, + uint32 flags); +status_t stop_disk_device_watching(port_id, int32 token); + +#endif // _DISK_DEVICE_MANAGER_USERLAND_INTERFACE_H diff --git a/headers/private/kernel/disk_device_manager/disk_device_manager.h b/headers/private/kernel/disk_device_manager/disk_device_manager.h new file mode 100644 index 0000000000..0a6218fc87 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/disk_device_manager.h @@ -0,0 +1,90 @@ +// disk_device_manager.h +// +// C API exported by the disk device manager. +// Currently only functions of interest for partition modules/FS add-ons +// are considered. + +#ifndef _DISK_DEVICE_MANAGER_H +#define _DISK_DEVICE_MANAGER_H + +#include + +// TODO: These don't belong here. partition_id and disk_job_id are +// public (exposed by the userland API), while disk_system_id is at least +// known to the userland API, but probably exposed as well, as type of a +// private member variable of BDiskSystem. +typedef int32 partition_id; +typedef int32 disk_system_id; +typedef int32 disk_job_id; + +// C API partition representation +typedef struct partition_data { + partition_id id; + off_t offset; + off_t size; + uint32 block_size; + int32 child_count; + int32 index; // needed? + uint32 status; + uint32 flags; + dev_t volume; + char *name; // max: B_FILE_NAME_LENGTH + char *content_name; // + char *type; // + char *content_type; // + char *parameters; + char *content_parameters; + void *cookie; + void *content_cookie; +} partition_data; + +// C API disk device representation +typedef struct disk_device_data { + partition_id id; // equal to that of the root partition + uint32 flags; + char *path; +} disk_device_data; + +// C API partitionable space representation +typedef struct partitionable_space_data { + off_t offset; + off_t size; +} partitionable_space_data; + +// disk device locking +disk_device_data *write_lock_disk_device(partition_id partition); +void write_unlock_disk_device(partition_id partition); +disk_device_data *read_lock_disk_device(partition_id partition); +void read_unlock_disk_device(partition_id partition); + // parameter is the ID of any partition on the device + +// getting disk devices/partitions by path +// (no locking required) +int32 find_disk_device(const char *path); +int32 find_partition(const char *path); + +// disk device/partition read access +// (read lock required) +disk_device_data *get_disk_device(partition_id partition); +partition_data *get_partition(partition_id partition); +partition_data *get_parent_partition(partition_id partition); +partition_data *get_child_partition(partition_id partition, int32 index); + +// partition write access +// (write lock required) +partition_data *create_child_partition(partition_id partition, int32 index, + partition_id *childID); + // childID is used for the return value, but is also an optional input + // parameter -- -1 to be ignored +bool delete_partition(partition_id partition); +void partition_modified(partition_id partition); + // tells the disk device manager, that the parition has been modified + +// jobs +bool set_disk_device_job_status(disk_job_id job, uint32 status); + // probably not needed +uint32 get_disk_device_job_status(disk_job_id job); +bool update_disk_device_job_progress(disk_job_id job, float progress); +bool update_disk_device_job_extra_progress(disk_job_id job, const char *info); + +#endif // _DISK_DEVICE_MANAGER_H