The Storage Kit: BVolume

Derived from: public BObject

Declared in: <storage/Volume.h>


Overview

A BVolume object represents a volume, an entity that contains a single, hierarchical file system and a single database. The data in a volume (the file system and database) is persistent: It's stored on a medium such as a hard disk, floppy disk, CD-ROM, or other storage device.

When a volume's existence is made known to the computer--when the volume is mounted--the system automatically constructs a BVolume (for your application) to represent it. When the volume is unmounted, the representative object is automatically destroyed. You can retrieve these BVolume objects directly through global functions, or construct your own BVolume objects that point to the objects that are created by the Kit. This is described in the next section.

Through a BVolume object you can retrieve information such as the volume's name, its storage capacity, how much of the volume is available, and so on. None of the BVolume functions manipulate or alter the volume--for example, you can't unmount a volume by calling a BVolume function (and rightly so, mounting and unmounting isn't an activity that's expected of an application).


Retrieving a BVolume

There are three ways to retrieve BVolume objects:

      BVolume myBootVol = boot_volume();

      /* Print the name of every mounted volume. */
      void VolumeNamePrinter()
      {
         BVolume this_vol;
         char vol_name[B_OS_NAME_LENGTH];
         long counter = 0; 
         while((this_vol = volume_at(counter++))) 
         {
            if (this_vol.Error() != B_NO_ERROR)
               break;
            this_vol.GetName(vol_name);
            printf("Volume %s is available\\n", vol_name);
         }
      }


Mounting and Unmounting

As mentioned above, BVolume objects are automatically constructed as volumes are mounted. Similarly, the system frees the BVolume object for a volume that's been unmounted. The system informs your application of these events through BApplication's VolumeMounted() and VolumeUnmounted() hook functions. Both functions provide a BMessage as an argument; in the "volume_id" field of the BMessage you'll find the volume ID of the affected volume. To turn the volume ID into a BVolume object, you pass it as an argument to the BVolume constructor .

In the following example implementation of these functions, information is printed as volumes are mounted and unmounted:

   void MyApp::VolumeMounted(BMessage *msg)
   {
      BVolume *new_vol;
      char vol_name[B_OS_NAME_LENGTH];
   
      /* Get the volume ID and turn it into an object. */
      new_vol = new BVolume(msg->FindLong("volume_id"));
      new_vol->GetName(vol_name);
   
      /* Print information about the volume. */
      printf("Volume %s mounted; %f bytes available.\\n",
         vol_name, new_vol->FreeBytes());
   }
   
   void MyApp::VolumeUnmounted(BMessage *msg)
   {
      BVolume *old_vol;
      char vol_name[B_OS_NAME_LENGTH];
      
      new_vol = new BVolume(msg->FindLong("volume_id"));
      new_vol->GetName(vol_name);
   
      /* Print information about the volume. */
      printf("Volume %s unmounted.\\n", vol_name);
   }

As implied by the example, VolumeMounted() is called after the BVolume is constructed; VolumeUnmounted() is called before the object is destroyed. Thus, within the implementations of these functions, you can assume that the BVolume object is still valid.

Important: If you want your application's volume list to be updated as volumes are mounted and unmounted, you must have a running be_app object. This is so even if you don't implement VolumeMounted() and VolumeUnmounted(). Furthermore, your application mustn't be an "Argv Only" app.


The File System

Every volume encapsulates the hierarchy of directories and files for a single file system. The "bridge" between a volume and the file system hierarchy is the volume's root directory. As its name implies, a root directory stands at the root of a file hierarchy such that all files (and directories) in the hierarchy can be traced back to it.

Every volume has a single root directory; to retrieve a volume's root directory (in the form of a BDirectory object), you pass an allocated BDirectory to BVolume's GetRootDirectory() function:

   /* Get the root directory for the first mounted volume. */
   BVolume *first_vol; 
   BDirectory root_dir;
   
   first_vol = volume_at(0);
   new_vol->GetRootDirectory(&root_dir);

The GetRootDirectory() "fills in" the BDirectory that you pass so that it refers to the root directory.

Volumes in Path Names

The Storage Kit's implementation of the file system obviates the need for path names. Specific files aren't identified by a concatenation of slash-separated subdirectories, but by objects. However, path names are still displayed in terminal windows, and are used by command-line programs. To identify a volume in a path name, you use this format:

/volumeName/directoryName/directoryName /...

The volume name itself doesn't include the surrounding slashes. In other words, a volume name might be "fido" but not "/fido/" (nor "/fido" nor "fido/").

You can't set a volume's name directly--BVolume doesn't have a name-setting function. A volume takes its name from that of its root directory. To change a volume's name, you have to retrieve the root directory and change its name (by invoking SetName() on the BDirectory).


The Database

You can retrieve a volume's database through the BVolume Database() function. The function returns the BDatabase object that represents the database. As described in the BDatabase class description, BDatabase objects are created for you in much the same way as are BVolume objects: As volumes are mounted and unmounted, BDatabase objects that represent the contained databases are constructed and destroyed.

In general, you only need to access a volume's database if you're creating an application that performs database activities (as opposed to an application that uses the Storage Kit simply to access the file system).


Constructor and Destructor


BVolume()

      BVolume(void)
      BVolume(long volume_id)

The first version of the constructor creates an "abstract" object that doesn't correspond to an actual volume. To create this correspondence, you invoke the SetID() function.

The second version creates a BVolume that corresponds to the volume identified by the argument.


~BVolume()

      virtual ~BVolume(void)

Destroys the object.


Member Functions


Capacity()

      double Capacity(void)

Returns the number of bytes of data that the volume can hold. This is the total of used and unused data--for an assessment of available storage, use the FreeBytes() function.

See also: FreeBytes()


Database()

      BDatabase *Database(void)

Returns the BDatabase object that represents the volume's database. Every volume contains exactly one database (and each database is contained in exactly one volume).

See also: BDatabase::Volume()


FreeBytes()

      double FreeBytes(void)

Returns a measure, in bytes, of the available storage in the volume.

See also: Capacity()


GetName()

       long GetName(char *name)

Copies the volume's name into the argument. The argument should be at least B_OS_NAME_LENGTH bytes long. The name returned here is that which, for example, shows up in the Browser's "volume window."

Setting the name is typically (and most politely) the user's responsibility (a task that's performed, most easily, through the Browser). If you really want to set the name of the volume programmatically, you do so by renaming the volume's root directory.

Currently, this function always returns B_NO_ERROR .

See also: GetRootDirectory()


GetRootDirectory()

      long GetRootDirectory(BDirectory *dir)

Returns, in dir, a BDirectory object that's set to the volume's root directory. This is the directory that lies at the root of the volume's file system , and from which all other files and directories descend.

You have to allocate the argument that you pass to this function; for example:

   BDirectory root_dir;
   
   a_volume->GetRootDirectory(&root_dir);

Some of the BDirectory (and, through inheritance, BStore) functions are treated specially for the root directory:

Currently, this function always returns B_NO_ERROR .


GetDevice()

      long GetDevice(char *deviceName)

Copies the name of the device upon which the volume is mounted into deviceName. The argument should be allocated to hold at least B_OS_NAME_LENGTH characters. If the BVolume corresponds to an actual volume (if its ID is set), this returns B_NO_ERROR. Otherwise, it returns B_ERROR.


ID()

      long ID(void)

Returns the volume's identification number. This number is unique among all volumes that are currently mounted, and is only valid for as long as the volume is mounted.

The value returned by this function is used, primarily, when you're communicating the identity of a volume to some other application.

See also: volume_at() in "Global Functions"


IsReadOnly()

      bool IsReadOnly(void)

Returns TRUE if the volume is declared to be read-only.


IsRemovable()

      bool IsRemovable(void)

Returns TRUE if the volume's media is removable (if it's a floppy disk).


Global Functions

The following functions are declared as global functions (in storage/Volume.h ). Since they're global, they don't rightfully belong in the BVolume class specification. But since they pertain specifically to volumes, their place, here, is justified.


boot_volume()

      BVolume boot_volume(void)

Returns the BVolume object that represents the "boot volume." This is the volume that contains the kernel and other system resources.


volume_at()

      BVolume volume_at(long index)

Returns the index'th BVolume in your application's volume list (counting from 0). The list is created and administered for you by the Storage Kit. See the class description, above, for an example of how the function is used.

If index is out-of-bounds, the function sets the returned object's Error() code to B_ERROR.


volume_for_database()

      BVolume volume_for_database(BDatabase *db)

Returns the BVolume that corresponds to the volume that contains the database identified by the argument.

If db is invalid, the function sets the returned object's Error() code to B_ERROR.




The Be Book, HTML Edition, for Developer Release 8 of the Be Operating System.

Copyright © 1996 Be, Inc. All rights reserved.

Be, the Be logo, BeBox, BeOS, BeWare, and GeekPort are trademarks of Be, Inc.

Last modified September 6, 1996.