[openbeosstorage] Device API (update)

Hi,

here's an update on my first attempt to document the device API methods. In
the next iteration I will certainly just check in the headers and empty
source files with doxygen documentation. However, here's the complete list 
again;
updated are:

Partition::BuildFileSystemInfo()
Partition::AddVirtualDevice()
Session::VirtualPartitionOnly()
Session::SetAddOnEntry()
Session::BuildPartitionMap()
Session::BuildFileSystemInfo()
Device::NewSession()
DeviceList::RescanDevices()

CU, Ingo


Partition
=========

Partition(Session *, const char *name, const char *type, 
        const char *fsShortName, const char *fsLongName, 
        const char *volumeName, const char *mountedAt,
        uint32 logicalBlockSize, uint64 offset, uint64 blocks, 
        bool hidden = false);
Partition(Session *, uint32 logicalBlockSize, uint64 offset, 
        uint64 blocks, bool hidden = false);
Partition(Session *, const partition_data &);

Not much to say about. Create the object and set the supplied data.

-----------------------------------------------------------------------

void SetName(const char *);
const char *Name() const;
void SetType(const char *);
const char *Type() const;
void SetFileSystemShortName(const char *);
const char *FileSystemShortName() const;
void SetFileSystemLongName(const char *);
const char *FileSystemLongName() const;
void SetVolumeName(const char *);
const char *VolumeName() const;
void SetMountedAt(const char *);
const char *MountedAt() const;
status_t GetMountPointNodeRef(node_ref*) const;
void SetMountPointNodeRef(const node_ref*);
MountState Mounted() const;
void SetMountState(MountState state);
uint32 LogicalBlockSize() const;
uint64 Offset() const;
uint64 Blocks() const;
bool Hidden() const;
partition_data *Data();
bool IsBFSDisk() const;
bool IsHFSDisk() const;
bool IsOFSDisk() const;
int32 Index() const;
Session *GetSession() const;
Device *GetDevice() const;

Accessors for the object's members.

-----------------------------------------------------------------------

bool BuildFileSystemInfo(void *params);
bool RebuildFileSystemInfo();

The comment says: `set up the files system short and long names for 
this partition'. Matches the EachPartitionMemberFunction signature. `params'
points to a structure containing at least a device FD, maybe other data.
The former method one invokes the function `EachAddOnCommon(char const *,
bool (*)(long, BEntry *, void *), void *)', which iterates through the
available FS DS add-ons to find the matching one.

RebuildFileSystemInfo() uses BuildFileSystemInfo().

-----------------------------------------------------------------------

bool SetOneUnknownMountState(void *);
bool ClearOneMountState(void *);

According to the comment: `utility calls for updating mounting info'. I 
guess they manipulate the member `MountState mounted'. The first method 
is very short, probably only a `mounted = kUnknown; return false;'. The 
second one seems to call `SetMountedAt()'. Both have the 
EachPartitionMemberFunction signature.

-----------------------------------------------------------------------

status_t Mount(int32 mountflags = 0, void *params = NULL,
               int32 len = 0);
status_t Unmount();

Mount/unmount the partition. The Mount() parameters are passed to the 
FS's mount function.

Mount() seems to rebuild the FS info, check whether there exist that 
many partitions, check whether the mount point exists and is an empty 
directory and publish a device in `/dev/...'.

Unmount() uses BVolume to get the mount point.

I don't see, how the actual mounting/unmounting is done, but I would 
use the POSIX API functions mount() and unmount() (unistd.h).

-----------------------------------------------------------------------

status_t Initialize(InitializeControlBlock *params,
                    const char *fileSystem = "bfs");

The comment:
`the drive setup addon call protocol requires a lot of extra stuff:
you have to pass a window onto which the drive setup addon will
center itself. Upon completion it will send it a message with
<completionMessage> signature; the MessageReceived in the window
needs to release <completionSemaphore> to unblock the call'

-----------------------------------------------------------------------

int32 UniqueID() const;

`returns a number uinque to the volume in a given device list
used to identify unmounted volumes'

Returns `int32 partitionUniqueID', which is set at construction time 
using `static int32 lastUniqueID'.

-----------------------------------------------------------------------

dev_t VolumeDeviceID() const;
void SetVolumeDeviceID(dev_t);

Returns `dev_t volumeDeviceID', which should be set at construction or 
mount time.

-----------------------------------------------------------------------

status_t AddVirtualDevice();

`publishes a device in /dev...' that can be used to access the 
partition. AddVirtualDevice(char *) does the real work.

-----------------------------------------------------------------------

void Dump(const char *includeThisText = "");

Prints some info to stdout. includeThisText is prepended.

------------------------------private----------------------------------

status_t AddVirtualDevice(char *device);

`fills out <device> with the path to the device driver in /dev...' and
publishes the partition using the B_SET_PARTITION ioctl.

-----------------------------------------------------------------------

void InitialMountPointName(char *);

Copies the name of the initial mount point into the supplied buffer.

-----------------------------------------------------------------------


Session
=======

Session(Device *device, const char *, uint64 offset, uint64 blocks, 
        bool data);

Constructs the object initializing it with the supplied data.

-----------------------------------------------------------------------

uint64 Blocks() const;
void SetName(const char *);
const char *Name() const;
void SetType(int32 type);
uint64 Offset() const;
Device *GetDevice() const;
int32 Index() const;
bool IsDataSession() const;
static status_t GetSessionData(int32 dev, int32 index, int32 blockSize,
                               session_data *session);

Accessors for the object's members.

-----------------------------------------------------------------------

void AddPartition(Partition *);
int32 CountPartitions() const;
Partition *PartitionAt(int32 index) const;

Partition list accessors.

-----------------------------------------------------------------------

bool VirtualPartitionOnly() const;

Returns `bool virtualPartitionOnly'. Probably for devices like 
floppies, that don't support partitions, but have a Partition object, 
however, to fit into this framework.

A hard disk with an empty partition table has a virtual partition. I don't
have a floppy drive at hand to verify the first suspicion.

-----------------------------------------------------------------------

void SetAddOnEntry(const BEntry *entry);

`the addon that knows how to handle this session'

That would be the DS session add-on.

-----------------------------------------------------------------------

bool BuildPartitionMap(int32 dev, uchar *block, bool singlePartition);

`adds one or more partitions to the list
returns true if multiple partitions found
pass false in <singlePartition> if device cannot support
multiple partitions (floppy)'

`dev': File descriptor to the raw device (should actually be an int).
`block': The first block of the session (better: const uchar *).

The method iterates through the DS partition add-ons to find a suitable one.
If one could be found, all partitions are added to the partition list. If
there is no partition, a `virtual' one is added.

-----------------------------------------------------------------------

bool BuildFileSystemInfo(int32 dev);

`dev': File descriptor to the raw device (should actually be an int).

The method calls Partition::BuildFileSystemInfo() on all partitions.

-----------------------------------------------------------------------

bool EachPartition(EachPartitionMemberFunction, void *);

`return true if terminated early'

...

-----------------------------------------------------------------------

BEntry add_on;  // we probably don't need this

The DS session add-on.

-----------------------------------------------------------------------


Device
======

Device(const char *path, int devfd = -1);
~Device();

The constructor initializes the object (Device::InitNewDeviceState()).

-----------------------------------------------------------------------

int32 CountSessions() const;
Session *SessionAt(int32 index) const;
int32 CountPartitions() const;

Session list accessors.

-----------------------------------------------------------------------
        
int32 BlockSize() const;
void SetPartitioningFlags(drive_setup_partition_flags newFlags);
const char *Name() const;
const char *DisplayName(bool includeBusID = true,
                        bool includeLUN = false) const;
bool ReadOnly() const
bool Removable() const
bool NoMedia() const;
bool IsFloppy() const;

Accessors for the object's members.

-----------------------------------------------------------------------

Session *NewSession(int32 dev, int32 index);

Looks like it would create a Session object for the `index'th session. 
`dev' is a FD to the device.

-----------------------------------------------------------------------

bool FindMountedVolumes(void *);

Looks like this methods iterates through all partitions of all sessions 
and checks whether the mount point node_ref identifies a valid 
directory and sets the mount point path (Partition::SetMountedAt()) 
accordingly.

-----------------------------------------------------------------------

void UpdateDeviceState();

Rebuilds the session list (MakeEmpty(), InitNewDeviceState()).

-----------------------------------------------------------------------

status_t Eject();

No idea, what that method might do. ;-)

-----------------------------------------------------------------------

void Dump(const char *);
bool Dump(void *);

...

-----------------------------------------------------------------------

bool DeviceStateChanged(void *params);

Has the EachDeviceMemberFunction signature.

Calls:
  Device::CountSessions(void)
  Device::DisplayName(bool, bool)
  Device::Name(void)

And is called by:
  ::OneHandleIfDisappeared(Partition *, void *)

Not sure, what it does.

------------------------------private----------------------------------

void InitNewDeviceState();

Seems to initialize the (some?) Device member vars (BBitmap methods are 
invoked, so the icons are certainly initialized), build the session 
list and initialize the sessions and their partitions.

-----------------------------------------------------------------------

void KillOldDeviceState();

MakeEmpty(). Probably does more. But what?

-----------------------------------------------------------------------

bool OneIfDeviceStateChangedAdaptor(void *params);

Obviously an adaptor for Device::DeviceStateChanged(void *). Not sure 
what it does though. Signature is the same -- both are of type 
EachDeviceMemberFunction.

-----------------------------------------------------------------------

void BuildDisplayName(bool includeBusID, bool includeLUN);

Initializes `shortName', a more human readable version of `name'.

-----------------------------------------------------------------------


DeviceList
==========

DeviceList();
~DeviceList();

Constructs empty device list/destroys list.

-----------------------------------------------------------------------

status_t RescanDevices(bool runRescanDriver = true);

Empties and rebuilds the device list.
`runRescanDriver': specifies whether or not the kernel shall scan for new
devices. The B_SCSI_SCAN_FOR_DEVICES ioctl is invoked on
`/dev/disk/{ide,scsi}/rescan'.
Invokes ScanDirectory() which does the actual scanning.

-----------------------------------------------------------------------

bool UpdateMountingInfo();

Checks all partitions for a change in their mount state. Comment: 
`returns true if there was a change'

-----------------------------------------------------------------------

bool EachDevice(EachDeviceMemberFunction, void *);
Device *EachDevice(EachDeviceFunction, void *);
Partition *EachPartition(EachPartitionFunction func, void *params);
bool EachPartition(EachPartitionMemberFunction func, void *params);
Partition *EachMountedPartition(EachPartitionFunction, void *);
Partition *EachMountablePartition(EachPartitionFunction, void *);
Partition *EachInitializablePartition(EachPartitionFunction, void *);

...

-----------------------------------------------------------------------
        
Partition *PartitionWithID(int32);

...

-----------------------------------------------------------------------

bool CheckDevicesChanged(DeviceScanParams *);

Checks whether some device has changed with respect to the device scan 
parameters. At least that's what I guess -- the dump shows only 
TypedList<Device *>::CountItems()/ItemAt(long), but no call to 
EachChangedDevice() as I would expect.

-----------------------------------------------------------------------

void UpdateChangedDevices(DeviceScanParams *);

Updates all devices that have changed wrt. the scan params. Finally 
Device::UpdateDeviceState() is called on the concerned devices, 
supposedly.

-----------------------------------------------------------------------

bool UnmountDisappearedPartitions();

Unmounts all disappeared partitions (OneHandleIfDisappeared() on each 
partition). I wonder, what `disappeared' means. Perhaps unmounted by 
someone else?

------------------------------private----------------------------------

bool EachChangedDevice(EachDeviceFunction, DeviceScanParams *, void *);

`iterate through every device that is out of sync with current state
used to sync when media changes, etc.'

-----------------------------------------------------------------------

status_t ScanDirectory(const char *path);

Given a directory path, checks recursively (?) which entries represent 
devices and initializes respective Device objects 
(InitNewDeviceState()) and adds them to the list.

-----------------------------------------------------------------------


Other related posts: