Mounting a Generic Filesystem

Once the root filesystem is initialized, additional filesystems may be mounted. Each must have its own mount point, which is just an already existing directory in the system's directory tree.

The mount( ) system call is used to mount a filesystem; its sys_mount( ) service routine acts on the following parameters:

• The pathname of a device file containing the filesystem, or null if it is not required

(for instance, when the filesystem to be mounted is network-based)

• The pathname of the directory on which the filesystem will be mounted (the mount point)

• The filesystem type, which must be the name of a registered filesystem

• The mount flags (permitted values are listed in Table 12-13)

• A pointer to a filesystem-dependent data structure (which may be null)

Table 12-13. Mount flags

Macro

Description

MS RDONLY

Files can only be read

MS NOSUID

Forbid setuid and setgid flags

MS NODEV

Forbid access to device files

MS NOEXEC

Disallow program execution

MS SYNCHRONOUS

Write operations are immediate

MS REMOUNT

Remount the filesystem changing the mount flags

MS MANDLOCK

Mandatory locking allowed

MS NOATIME

Do not update file access time

MS NODIRATIME

Do not update directory access time

MS BIND

Create a "bind mount," which allows making a file or directory visible at another point of the system directory tree

MS MOVE

Atomically move a mounted filesystem on another mount point

MS REC

Should recursively create "bind mounts" for a directory subtree (still unfinished in 2.4.18)

MS VERBOSE

Generate kernel messages on mount errors

The sys_mount( ) function copies the value of the parameters into temporary kernel buffers, acquires the big kernel lock, and invokes the do_mount( ) function. Once do_mount( ) returns, the service routine releases the big kernel lock and frees the temporary kernel buffers.

The do_mount( ) function takes care of the actual mount operation by performing the following operations:

1. Checks whether the sixteen highest-order bits of the mount flags are set to the "magic" value 0xce0d; in this case, they are cleared. This is a legacy hack that allows the sys_mount( ) service routine to be used with old C libraries that do not handle the highest-order flags.

2. If any of the ms_nosuid, ms_nodev, or ms_noexec flags passed as a parameter are set, clears them and sets the corresponding flag (mnt_nosuid, mnt_nodev, mnt_noexec) in the mounted filesystem object.

3. Looks up the pathname of the mount point by invoking path_init( ) and path_walk( ) (see the later section Section 12.5).

4. Examines the mount flags to determine what has to be done. In particular:

a. If the ms_remount flag is specified, the purpose is usually to change the mount flags in the s_flags field of the superblock object and the mounted filesystem flags in the mnt_flags field of the mounted filesystem object. The do_remount( ) function performs these changes.

b. Otherwise, checks the ms_bind flag. If it is specified, the user is asking to make visible a file or directory on another point of the system directory tree. Usually, this is done when mounting a filesystem stored in a regular file instead of a physical disk partition (loopback). The do_loopback( ) function accomplishes this task.

c. Otherwise, checks the ms_move flag. If it is specified, the user is asking to change the mount point of an already mounted filesystem. The do_move_mount( ) function does this atomically.

d. Otherwise, invokes do_add_mount( ). This is the most common case. It is triggered when the user asks to mount either a special filesystem or a regular filesystem stored in a disk partition. do_add_mount( ) performs the following actions:

a. Invokes do_kern_mount( ) passing, to it the filesystem type, the mount flags, and the block device name. As already described in Section 12.4.1, do_kern_mount( ) takes care of the actual mount operation.

b. Acquires the mount_sem semaphore.

c. Initializes the flags in the mnt_flags field of the new mounted filesystem object allocated by do_kern_mount( ).

d. Invokes graft_tree( ) to insert the new mounted filesystem object in the global list, in the hash table, and in the children list of the parent-mounted filesystem.

e. Releases the mount_sem semaphore.

5. Invokes path_release( ) to terminate the pathname lookup of the mount point (see the later section Section 12.5).

The core of the mount operation is the do_kern_mount( ) function, which we already described in the earlier section Section 12.4.1. Recall that this function checks the filesystem type flags to determine how the mount operation is to be done. For a regular disk-based filesystem, the fs_requires_dev flag is set, so do_kern_mount( ) invokes the get_sb_bdev( ) function, which performs the following actions:

1. Invokes path_init( ) and path_walk( ) to look up the pathname of the mount point (see Section 12.5).

2. Invokes blkdev_get( ) to open the block device storing the regular filesystem.

3. Searches the list of superblock objects; if a superblock relative to the block device is already present, returns its address. This means that the filesystem is already mounted and will be mounted again.

4. Otherwise, allocates a new superblock object, initializes its s_dev, s_bdev, s_flags, and s_type fields, and inserts it into the global lists of superblocks and the superblock list of the filesystem type descriptor.

5. Acquires the s_lock spin lock of the superblock.

6. Invokes the read_super method of the filesystem type to access the superblock information on disk and fill the other fields of the new superblock object.

7. Sets the ms_active flag of the superblock.

8. Releases the s_lock spin lock of the superblock.

9. If the filesystem type is implemented by a kernel module, increments its usage counter.

10. Invokes path_release( ) to terminate the mount point lookup operation.

11. Returns the address of the new superblock object. 12.4.3 Unmounting a Filesystem

The umount( ) system call is used to unmount a filesystem. The corresponding sys_umount( ) service routine acts on two parameters: a filename (either a mount point directory or a block device filename) and a set of flags. It performs the following actions:

1. Invokes path_init( ) and path_walk( ) to look up the mount point pathname (see the next section). Once finished, the functions return the address d of the dentry object corresponding to the pathname.

2. If the resulting directory is not the mount point of a filesystem, returns the -einval error code. This check is done by verifying that d->mnt->mnt_root contains the address of the dentry object d.

3. If the filesystem to be unmounted has not been mounted on the system directory tree, returns the -einval error code. (Recall that some special filesystems have no mount point.) This check is done by invoking the check_mnt( ) function on d-

4. If the user does not have the privileges required to unmount the filesystem, returns the -eperm error code.

5. Invokes do_umount( ), which performs the following operations:

a. Retrieves the address of the superblock object from the mnt_sb field of the mounted filesystem object.

If the user asked to force the unmount operation, interrupts any ongoing mount operation by invoking the umount_begin superblock operation.

c. If the filesystem to be unmounted is the root filesystem and the user didn't ask to actually detach it, invokes do_remount_sb( ) to remount the root filesystem read-only and terminates.

d. Acquires the mount_sem semaphore for writing and the dcache_lock dentry spin lock.

e. If the mounted filesystem does not include mount points for any child mounted filesystem, or if the user asked to forcibly detach the filesystem, invokes umount_tree( ) to unmount the filesystem (together with all children).

f. Releases mount sem and dcache lock.

I [email protected] RuBoard

4 previous

Continue reading here: Pathname Lookup

Was this article helpful?

0 0

Responses

  • daavid
    How are mounts stored linux kernel?
    1 year ago