File system components and management
Components
Basic file system architecture
The Linux file system architecture is an interesting example of abstracting complexity. Using a common set of API functions, a large variety of file systems can be supported on a large variety of storage devices. Take, for example, the read
function call, which allows some number of bytes to be read from a given file descriptor. The read
function is unaware of file system types, such as ext3 or NFS. It is also unaware of the particular storage medium upon which the file system is mounted, such as AT Attachment Packet Interface (ATAPI) disk, Serial-Attached SCSI (SAS) disk, or Serial Advanced Technology Attachment (SATA) disk. Yet, when the read
function is called for an open file, the data is returned as expected. This article explores how this is done and investigates the major structures of the Linux file system layer.
A file system is an organization of data and metadata on a storage device. With a vague definition like that, you know that the code required to support this will be interesting. As I mentioned, there are many types of file systems and media. With all of this variation, you can expect that the Linux file system interface is implemented as a layered architecture, separating the user interface layer from the file system implementation from the drivers that manipulate the storage devices.
File systems as protocols
Associating a file system to a storage device in Linux is a process called mounting. The mount
command is used to attach a file system to the current file system hierarchy (root). During a mount, you provide a file system type, a file system, and a mount point.
To illustrate the capabilities of the Linux file system layer (and the use of mount), create a file system in a file within the current file system. This is accomplished first by creating a file of a given size using dd
(copy a file using /dev/zero as the source) -- in other words, a file initialized with zeros, as shown in Listing 1.
Listing 1. Creating an initialized file
$ dd if=/dev/zero of=file.img bs=1k count=10000 10000+0 records in 10000+0 records out $ |
You now have a file called file.img that's 10MB. Use the losetup
command to associate a loop device with the file (making it look like a block device instead of just a regular file within the file system):
$ losetup /dev/loop0 file.img $ |
With the file now appearing as a block device (represented by /dev/loop0), create a file system on the device with mke2fs
. This command creates a new second ext2 file system of the defined size, as shown in Listing 2.
Listing 2. Creating an ext2 file system with the loop device
$ mke2fs -c /dev/loop0 10000 mke2fs 1.35 (28-Feb-2004) max_blocks 1024000, rsv_groups = 1250, rsv_gdb = 39 Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 2512 inodes, 10000 blocks 500 blocks (5.00%) reserved for the super user ... $ |
The file.img file, represented by the loop device (/dev/loop0
), is now mounted to the mount point /mnt/point1 using the mount
command. Note the specification of the file system as ext2
. When mounted, you can treat this mount point as a new file system by doing using an ls
command, as shown in Listing 3.
Listing 3. Creating a mount point and mounting the file system through the loop device
$ mkdir /mnt/point1 $ mount -t ext2 /dev/loop0 /mnt/point1 $ ls /mnt/point1 lost+found $ |
As shown in Listing 4, you can continue this process by creating a new file within the new mounted file system, associating it with a loop device, and creating another file system on it.
Listing 4. Creating a new loop file system within a loop file system
$ dd if=/dev/zero of=/mnt/point1/file.img bs=1k count=1000 1000+0 records in 1000+0 records out $ losetup /dev/loop1 /mnt/point1/file.img $ mke2fs -c /dev/loop1 1000 mke2fs 1.35 (28-Feb-2004) max_blocks 1024000, rsv_groups = 125, rsv_gdb = 3 Filesystem label= ... $ mkdir /mnt/point2 $ mount -t ext2 /dev/loop1 /mnt/point2 $ ls /mnt/point2 lost+found $ ls /mnt/point1 file.img lost+found $ |
From this simple demonstration, it's easy to see how powerful the Linux file system (and the loop device) can be. You can use this same approach to create encrypted file systems with the loop device on a file. This is useful to protect your data by transiently mounting your file using the loop device when needed.
Filesystem Management
badblocks | Used to search a disk or partition for badblocks. | |
cfdisk | Similar to fdisk but with a nicer interface. | |
debugfs | Allows direct access to filesystems data structure. | |
df | Shows the disk free space on one or more filesystems. | |
dosfsck | Check and repair MS-Dos filesystems. | |
du | Shows how much disk space a directory and all its files contain. | |
dump | Used to back up an ext2 filesystem. Complement is restore. | |
dumpe2fs | Dump filesystem superblock and blocks group information. Ex: dumpe2fs /dev/hda2 | |
e2fsck | Check a Linux second extended filesystem. | |
e2label | Change the label on an ext2 filesystem. | |
exportfs | Used to set up filesystems to export for nfs (network file sharing). | |
fdisk | Used to fix or create partitions on a hard drive. | |
fdformat | Formats a floppy disk. | |
fsck | Used to add new blocks to a filesystem. Must not be run on a mounted file system. | |
hdparm | Get/set hard disk geometry parameters, cylinders, heads, sectors. | |
mkfs | Initializes a Linux filesystem. This is a front end that runs a separate program depending on the filesystem's type. | |
mke2fs | Create a Linux second extended filesystem. | |
mkswap | Sets up a Linux swap area on a device or file. | |
mount | Used to mount a filesystem. Complement is umount. | |
rdev | Query/set image root device, swap device, RAM disk size of video mode. What this does is code the device containing the root filesystem into the kernel image specified. | |
rdump | Same as dump. | |
rmt | Remote magtape protocol module. | |
restore | Used to restore an ext2 filesystem. | |
setfdprm | Set floppy drive parameters. | |
swapoff(8) | Used to de-activate a swap partition. | |
swapon(8) | Used to activate a swap partition. | |
sync | Forces all unwritten blocks in the buffer cache to be written to disk. | |
tune2fs | Adjust tunable filesystem parameters on second extended filesystems. | |
umount | Unmounts a filesystem. Complement is mount. |