Chapter 26. Initialization and Mounting
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
filesystem's 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 root
field.
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 mount()
. This
function has the following prototype:
int mount(const char *devname, const char *dir, const char *fsname);
The 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.
The dir
argument is the mount point name, it
will be assigned to the name
field of the
mount table entry.
The 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 fsname
argument
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
read-only: "fatfs:readonly"
.
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
matches 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
mounted filesystem.
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
mounting using 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 umount()
function. This can unmount filesystems whether they were mounted
statically or dynamically.
The 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
filesystem's umount()
operation, with the
force
argument set to false
is called and if successful, the mount table entry is invalidated by
setting its valid
field false and the
name
field to NULL.
There is also an umount_force()
function with the
following prototype:
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
the filesystem's 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.
2024-03-18 | Open Publication License |