Understanding Linux File Systems: Directories, Paths, and System Calls Explained
This article provides a comprehensive overview of Linux file systems, covering VFS, directory hierarchy, absolute and relative paths, symbolic links, mounting, file locking, and the essential system calls such as creat, open, read, write, lseek, stat, pipe, and fcntl.
Linux File System Basics
In Linux the most visible component is the file system. The article explains the evolution from the original MINIX‑1 file system (14‑byte names, 64 MB limit) to the ext family and the role of the Virtual File System ( VFS) that allows multiple concrete file systems to be mounted simultaneously.
Files are treated as arbitrary byte sequences; directories are special files that can contain other directories, forming a hierarchical tree rooted at /. The most common top‑level directories are listed below: /bin – essential binaries for all users /boot – boot loader files /dev – device nodes /etc – configuration files and startup scripts /home – user home directories /lib – shared libraries for binaries in /bin and
/sbin /lost+found– recovered files (root only) /media – mount points for removable media /mnt – generic mount point /opt – optional application installations /proc – virtual filesystem exposing kernel and process information /root – root user's home directory /sbin – system binaries /tmp – temporary files (cleared on reboot) /usr – majority of user‑level applications and data /var – variable data such as logs and databases
Linux distinguishes between absolute paths (starting with /) and relative paths that are interpreted from the current working directory. For example, if the working directory is /usr/local/books, the command cp books books-replica uses a relative path, while
cp /usr/local/books/books /usr/local/books/books-replicauses an absolute path.
When two users need to share files, symbolic links simplify access. The article shows a before‑and‑after diagram where user jianshe creates a link to /usr/cxuan/A so that the path ../cxuan/xxx can be used instead of the full absolute path.
Linux also supports mounting one filesystem onto another, making files from different disks appear under a single unified hierarchy. This eliminates the need for users to know the physical location of a file.
File locking is another key feature. Linux provides shared (read) and exclusive (write) locks to prevent race conditions when multiple processes access the same file. The article illustrates three scenarios with diagrams: a single shared lock, overlapping shared locks between two processes, and multiple shared locks across three processes. If a process attempts to acquire an exclusive lock on a region already held by shared locks, the request fails and the process may block until the region is free.
Linux File System Calls
Creating a new file uses the creat system call (note the missing “e”). It takes a filename and a mode, returns a non‑negative file descriptor, and truncates an existing file to zero length. Example: fd = creat("aaa", mode); The returned file descriptor is used for subsequent operations such as read, write, and close. The article lists the most common file‑related system calls: fd = open(file, ...) – open a file for reading/writing s = close(fd) – close a file descriptor n = read(fd, buffer, nbytes) – read data n = write(fd, buffer, nbytes) – write data position = lseek(fd, offset, whence) – move the file pointer s = stat(name, &buf) – retrieve file metadata by pathname s = fstat(fd, &buf) – retrieve metadata by descriptor s = pipe(&fd[0]) – create a pipe (two pseudo‑files) s = fcntl(fd, ...) – perform locking and other control operations
Standard input, output, and error are the first three descriptors (0, 1, 2) and are inherited by child processes.
The lseek call changes the file offset without performing any I/O. Its prototype is: lseek(int fildes, off_t offset, int whence); Locking is performed via fcntl with F_SETLK, F_SETLKW, etc., allowing shared or exclusive locks on byte ranges.
Directory‑related calls include: s = mkdir(path, mode) – create a directory s = rmdir(path) – remove an empty directory s = link(oldpath, newpath) – create a hard link s = unlink(path) – remove a link (file is deleted when the last link disappears) s = chdir(path) – change the working directory dir = opendir(path) – open a directory for reading s = closedir(dir) – close a directory stream dirent = readdir(dir) – read the next directory entry rewinddir(dir) – reset the read position to the start
Each opened file or directory is represented internally by an entry in the global file table, which stores the inode, current offset, and access mode. The file descriptor returned to user space is simply the index of this entry.
Images illustrating directory trees, symbolic links, mounting relationships, lock diagrams, and the file descriptor table are retained to aid understanding.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
