As mentioned previously, mount table entries can be sourced from two
places. Static entries may be defined by using the
MTAB_ENTRY() macro. Such entries will be
automatically mounted on system startup. For each entry in the mount
table that has a non-null
name field the
filesystem table is searched for a match with the
fsname field. If a match is found the
mount entry is called and if
successful the mount table entry marked valid and the
fs field initialized. The
mount() function is responsible for initializing
The size of the mount table is defined by the configuration value CYGNUM_FILEIO_MTAB_MAX. Any entries that have not been statically defined are available for use by dynamic mounts.
A filesystem may be mounted dynamically by calling
function has the following prototype:
int mount( const char *devname, const char *dir, const char *fsname);
devname argument identifies a device that
will be used by this filesystem and will be assigned to the
devname field of the mount table entry.
dir argument is the mount point name, it
will be assigned to the
name field of the
mount table entry.
fsname argument is the name of the
implementing filesystem, it will be assigned to the
fsname entry of the mount table entry. This
argument may also contain options that control the mode in which the
filesystem is mounted.
Since these three arguments are assigned directly to the mount table entry, the memory pointed to by these arguments must not change for the duration of the mount. This means they must be allocated from memory that will persist unchanged until unmounting, such as constant strings, dynamically allocated memory, or static or automatic variables that do not pass out of scope or get their values changed before unmounting.
The options attached to the
consist of a comma separated list of single keywords or keyword=value
pairs separated from the filesystem name by a colon. For example, to
mount the FAT filesystem with write-through cache synchronization the
string would be: "fatfs:sync=write" and to mount it
The process of mounting a filesystem dynamically is as follows. First
a search is made of the mount table for an entry with a NULL
name field to be used for the new mount
point. The filesystem table is then searched for an entry whose name
fsname. If this is successful then
the mount table entry is initialized and the filesystem's
mount() operation called. If this is successful,
the mount table entry is marked valid and the
fs field initialized.
Mounting a filesystem dynamically at the current working directory name,
does not in fact change the current directory to one on the newly
Instead the current working directory remains on the previous filesystem
(or no filesystem in the case of '/' with no filesystems previously
mounted). This is in line with usual POSIX/UNIX behaviour. To change
to the new filesystem, a
chdir() call must be
made, even if it is to the current directory name as given by
getcwd(). This is especially relevant when
mounting a filesystem on '/' as the current working directory is
usually also '/' .
Normally you can access files and directories with both absolute paths
(for example '/fs/dir1/file1.txt') or paths
relative to the current working directory (for example
'./dir1/file1.txt' or just
'dir1/file1.txt'). As a special exception, you
cannot use relative paths if your current working directory is the
root directory '/', unless there is a filesystem mounted directly on
'/'. This is a deliberate simplification due to the fact that the
current working directory is not really a valid directory and there is
no true filesystem at '/' to navigate within. Instead it is
recommended to either change directory into a filesystem after
chdir(), use absolute paths, or
mount a filesystem at '/'.
It should also be noted that there is no requirement for there to be a directory entry for a filesystem mount point if mounted within another filesystem. So for example, there need not be a directory named “/dev” in the directory list of “/” even though there is a filesystem mounted on “/dev”.
Unmounting a filesystem is done by the
function. This can unmount filesystems whether they were mounted
statically or dynamically.
umount() function has the following prototype:
int umount( const char *name );
The mount table is searched for a match between the
name argument and the entry
name field. When a match is found the
umount() operation, with the
force argument set to false
is called and if successful, the mount table entry is invalidated by
valid field false and the
name field to NULL.
There is also an
umount_force() function with the
int umount_force( const char *name );
The main difference between this and the standard
umount() function is that it forces the
filesystem to be unmounted. In the FILEIO package this means that all
open files will be forced to close, the current directory will be
moved away from the filesystem if it points to it and any threads
waiting for access to the filesystem will be forced to return. In
general, any buffered data not yet written to the medium will be lost;
such buffering may take place in libraries like C standard I/O, C++
streams or the filesystem itself. If the programmer wishes for
buffered data to be committed beforehand, they must use whatever mechanism
has been provided by the layers performing the buffering. This is not
always the case however, such as if the reason to force an unmounting
is because the medium has been removed. When
umount() function is called, the
force argument will be set
true, and the filesystem should take steps to free
all resources and detach from the underlying device.
Care must be taken if mounting a filesystem on “/” as it will not be possible to unmount the filesystem later if it is in use as the current working directory. Instead it will be necessary to change directory to a different filesystem before unmounting.