How Linux system calls interact with the file system
I ran into this exercise lately:
Given this sequence of system calls in a Linux C language program:
fd = open("f123", O_RDWRT | O_CREAT, 0777);
lseek(fd, 0x1000000L, 0);
write(fd, &fd, sizeof(int));
draw the file system data structures and disk blocks that have been modified by these operations, given the 4 KB block size and 4 byte block pointers.
For the first system call ( open
), I figured out how it works and schematized it like this:
Now, skipping the drawing part (I understand that it will be difficult to answer), I would like to understand how lseek
u write
work in terms of indices and indices (whatever they are).
I've tried to figure out what is lseek
calculating the correct inode (since the block size is known), but still don't know how it works.
source to share
On Linux, these system calls interact with the virtual file system (VFS). VFS is an abstraction over real filesystems, it defines some useful data structures for organizing a filesystem.
- inodes is a real file on disk. Through the inodes structure, you can access not only the inode block, but also the data blocks on the disk.
- directory entry is part of the path. D_entry does not always refer to a real file on disk. If it refers to a directory on disk, there will be a pointer to the inode structure of the directory file.
- file represents files opened by processes. There's also a pointer to its d_entry in the structure.
Here are snippets from file
struct:
struct file {
// ... other attributes
struct path f_path;
#define f_dentry f_path.dentry
#define f_vfsmnt f_path.mnt
const struct file_operations *f_op;
};
struct file_operations {
// ... other operations
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
}
All of these objects have an operations list field. The VFS defines these operations and the underlying filesystems implement these operations or use the generic implementations provided by the VFS.
Syscall open()
creates a file object, other syscalls like lseek()
just get the object file
(via Fd) and call the corresponding function in the list of operations, for example write()
calls f->f_op->write(f, ...)
, then the file system can follow the path file -> d_entry -> inode
to access the file on disk.
source to share