4.4   Raw File System: rawFs

VxWorks provides a minimal "file system," rawFs, for use in systems that require only the most basic disk I/O functions. The rawFs file system, implemented in rawFsLib, treats the entire disk volume much like a single large file. Although the dosFs and rt11Fs file systems do provide this ability to varying degrees, the rawFs file system offers advantages in size and performance if more complex functions are not required.

4.4.1   Disk Organization

As mentioned previously, rawFs imposes no organization of the data on the disk.

The rawFs file system maintains no directory information; thus there is no division of the disk area into specific files, and no file names are used. All open( ) operations on rawFs devices specify only the device name; no additional file names are allowed.

The entire disk area is available to any file descriptor that is open for the device. All read and write operations to the disk use a byte-offset relative to the start of the first block on the disk.

4.4.2   Initializing the rawFs File System

Before any other operations can be performed, the rawFs library, rawFsLib, must be initialized by calling rawFsInit( ). This routine takes a single parameter, the maximum number of rawFs file descriptors that can be open at one time. This count is used to allocate a set of descriptors; a descriptor is used each time a rawFs device is opened.

The rawFsInit( ) routine also makes an entry for the rawFs file system in the I/O system driver table (with iosDrvInstall( )). This entry specifies the entry points for rawFs file operations and is for all devices that use the rawFs file system. The driver number assigned to the rawFs file systems is placed in a global variable rawFsDrvNum.

The rawFsInit( ) routine is normally called by the usrRoot( ) task after starting the VxWorks system. To use this initialization, define INCLUDE_RAWFS in the project facility VxWorks view, and set NUM_RAWFS_FILES to the desired maximum open file descriptor count on the Params tab of the properties window.

4.4.3   Initializing a Device for Use with the rawFs File System

After the rawFs file system is initialized, the next step is to create one or more devices. Devices are created by the device driver's device creation routine (xxDevCreate( )). The driver routine returns a pointer to a block device descriptor structure (BLK_DEV). The BLK_DEV structure describes the physical aspects of the device and specifies the routines in the device driver that a file system can call. For more information on block devices, see 3.9.4 Block Devices.

Immediately after its creation, the block device has neither a name nor a file system associated with it. To initialize a block device for use with rawFs, the already-created block device must be associated with rawFs and a name must be assigned to it. This is done with the rawFsDevInit( ) routine. Its parameters are the name to be used to identify the device and a pointer to the block device descriptor structure (BLK_DEV):

RAW_VOL_DESC *pVolDesc; 
BLK_DEV      *pBlkDev; 
pVolDesc = rawFsDevInit ("DEV1:", pBlkDev); 

The rawFsDevInit( ) call assigns the specified name to the device and enters the device in the I/O system device table (with iosDevAdd( )). It also allocates and initializes the file system's volume descriptor for the device. It returns a pointer to the volume descriptor to the caller; this pointer is used to identify the volume during certain file system calls.

Note that initializing the device for use with rawFs does not format the disk. That is done using an ioctl( ) call with the FIODISKFORMAT function.

No disk initialization (FIODISKINIT) is required, because there are no file system structures on the disk. Note, however, that rawFs accepts that ioctl( ) function code for compatibility with other file systems; in such cases, it performs no action and always returns OK.

4.4.4   Mounting Volumes

A disk volume is mounted automatically, generally during the first open( ) or creat( ) operation. (Certain ioctl( ) functions also cause the disk to be mounted.) The volume is again mounted automatically on the first disk access following a ready-change operation (see 4.4.6 Changing Disks).


*

CAUTION: Because device names are recognized by the I/O system using simple substring matching, file systems should not use a slash (/) alone as a name; unexpected results may occur.

4.4.5   File I/O

To begin I/O to a rawFs device, first open the device using the standard open( ) function. (The creat( ) function can be used instead, although nothing is actually "created.") Data on the rawFs device is written and read using the standard I/O routines write( ) and read( ). For more information, see 3.3 Basic I/O.

The character pointer associated with a file descriptor (that is, the byte offset where reads and writes take place) can be set by using ioctl( ) with the FIOSEEK function.

Multiple file descriptors can be open simultaneously for a single device. These must be carefully managed to avoid modifying data that is also being used by another file descriptor. In most cases, such multiple open descriptors use FIOSEEK to set their character pointers to separate disk areas.

4.4.6   Changing Disks

The rawFs file system must be notified when removable disks are changed (for example, when floppies are swapped). Two different notification methods are provided: (1) rawFsVolUnmount( ) and (2) the ready-change mechanism.

Unmounting Volumes

The first method of announcing a disk change is to call rawFsVolUnmount( ) prior to removing the disk. This call flushes all modified file descriptor buffers if possible (see Synchronizing Volumes) and also marks any open file descriptors as obsolete. The next I/O operation remounts the disk. Calling ioctl( ) with FIOUNMOUNT is equivalent to using rawFsVolUnmount( ). Any open file descriptor to the device can be used in the ioctl( ) call.

Attempts to use obsolete file descriptors for further I/O operations produce an S_rawFsLib_FD_OBSOLETE error. To free an obsolete descriptor, use close( ), as usual. This frees the descriptor even though it produces the same error.

ISRs must not call rawFsVolUnmount( ) directly, because the call can pend while the device becomes available. The ISR can instead give a semaphore that prompts a task to unmount the volume. (Note that rawFsReadyChange( ) can be called directly from ISRs; see Announcing Disk Changes with Ready-Change.)

When rawFsVolUnmount( ) is called, it attempts to write buffered data out to the disk. Its use is therefore inappropriate for situations where the disk-change notification does not occur until a new disk is inserted, because the old buffered data would be written to the new disk. In this case, use rawFsReadyChange( ), which is described in Announcing Disk Changes with Ready-Change.

If rawFsVolUnmount( ) is called after the disk is physically removed, the data flushing portion of its operation fails. However, the file descriptors are still marked as obsolete, and the disk is marked as requiring remounting. An error is not returned by rawFsVolUnmount( ); to avoid lost data in this situation, explicitly synchronize the disk before removing it (see Synchronizing Volumes).

Announcing Disk Changes with Ready-Change

The second method of announcing that a disk change is taking place is with the ready-change mechanism. A change in the disk's ready-status is interpreted by rawFsLib to indicate that the disk must be remounted during the next I/O call.

There are three ways to announce a ready-change:

The ready-change announcement does not cause buffered data to be flushed to the disk. It merely marks the volume as needing remounting. As a result, data written to files can be lost. This can be avoided by synchronizing the disk before asserting ready-change. The combination of synchronizing and asserting ready-change provides all the functionality of rawFsVolUnmount( ) except for marking file descriptors as obsolete.

Ready-change can be used in ISRs, because it does not attempt to flush data or perform other operations that could cause delay.

The block device driver status-check routine (identified by the bd_statusChk field in the BLK_DEV structure) is useful for asserting ready-change for devices that only detect a disk change after the new disk is inserted. This routine is called at the beginning of each open( ) or creat( ), before the file system checks for ready-change.

Disks with No Change Notification

If it is not possible for a ready-change to be announced each time the disk is changed, close all file descriptors for the volume before changing the disk.

Synchronizing Volumes

When a disk is synchronized, all buffered data that is modified is written to the physical device so that the disk is up to date. For the rawFs file system, the only such data is that contained in open file descriptor buffers.

To avoid loss of data, synchronize a disk before removing it. You may need to explicitly synchronize a disk, depending on when (or if) the rawFsVolUnmount( ) call is issued.

When rawFsVolUnmount( ) is called, an attempt is made to synchronize the device before unmounting. If this disk is still present and writable at the time of the call, synchronization takes place automatically; there is no need to synchronize the disk explicitly.

However, if the rawFsVolUnmount( ) call is made after a disk is removed, it is obviously too late to synchronize, and rawFsVolUnmount( ) discards the buffered data. Therefore, make a separate ioctl( ) call with the FIOSYNC function before removing the disk. (For example, this could be done in response to an operator command.) Any open file descriptor to the device can be used during the ioctl( ) call. This call writes all modified file descriptor buffers for the device out to the disk.

4.4.7   I/O Control Functions Supported by rawFsLib

The rawFs file system supports the ioctl( ) functions shown in Table 4-7. The functions listed are defined in the header file ioLib.h. For more information, see the manual entries for rawFsLib and for ioctl( ) in ioLib.

Table 4-7:  I/O Control Functions Supported by rawFsLib 


Function
Decimal Value
Description

FIODISKCHANGE  
13
Announce a media change. 
FIODISKFORMAT  
5
Format the disk (device driver function). 
FIODISKINIT  
6
Initialize a rawFs file system on a disk volume (not required). 
FIOFLUSH  
2
Same as FIOSYNC
FIOGETNAME  
18
Get the file name of the fd
FIONREAD  
1
Get the number of unread bytes on the device. 
FIOSEEK  
7
Set the current byte offset on the device. 
FIOSYNC  
21
Write out all modified file descriptor buffers. 
FIOUNMOUNT  
39
Unmount a disk volume. 
FIOWHERE  
8
Return the current byte position on the device.