Unix 세계에는 모든 것이 파일이다라는 고전적인 속담이 있습니다. 이것이 의미하는 바는 유닉스 운영체제에서는 모든 객체가 파일로 취급될 수 있고, 파일 운영을 위한 인터페이스를 사용해 조작할 수 있다는 것이다. Unix와 유사한 운영 체제인 Linux도 이러한 목표를 달성하기 위해 노력하고 있습니다.
달성하려면 一切皆文件
这个目标,Linux 内核提供了一个中间层:虚拟文件系统(Virtual File System)
.
객체 지향 프로그래밍 언어(예: C++/Java 등)를 사용해 본 적이 있다면 이 개념을 잘 알고 있어야 합니다 接口
. 가상 파일 시스템은 표준 인터페이스 세트를 정의하는 객체 지향 프로그래밍의 인터페이스와 유사합니다. 개발자는 이 인터페이스 집합을 구현하기만 하면 파일 운영용 인터페이스를 사용하여 개체를 운영할 수 있습니다. 아래 그림과 같이:
위 사진의 파란색 부분이 가상 파일 시스템의 위치입니다.
위 그림에서 볼 수 있듯이 가상 파일 시스템은 상위 계층 애플리케이션에 대한 통합 인터페이스를 제공합니다. 파일 시스템이 가상 파일 시스템의 인터페이스를 구현하는 경우 상위 계층 응용 프로그램은 open()
、read()
和 write()
와 같은 기능을 사용하여 작동할 수 있습니다.
오늘은 가상 파일 시스템의 원리와 구현에 대해 소개하겠습니다.
가상 파일 시스템의 원리를 설명하기 전에 먼저 Java 예제를 소개하겠습니다. 이 Java 예제를 통해 가상 파일 시스템의 원리를 더 쉽게 이해할 수 있습니다.
Java를 사용하여 프로그램을 작성해 본 적이 있다면 가상 파일 시스템을 이해하기 쉬울 것입니다. 우리는 Java의 인터페이스를 사용하여 가상 파일 시스템의 정의를 시뮬레이션합니다.
으아악위는 VFSFile
의 인터페이스, VFSFile
的接口,接口中定义了一些方法,如 open()
、read()
和 write()
等。现在我们来定义一个名为 Ext3File
등과 같은 일부 메소드를 정의합니다. 이제 이 인터페이스를 구현하기 위해 #10f5d6c">Ext3File 개체라는 글꼴을 정의해 보겠습니다.
이제 다음과 같이 VFSFile
接口来操作 Ext3File
개체를 사용할 수 있습니다.
public class Main() { public static void main(String[] args) { VFSFile file = new Ext3File(); int fd = file.open("/tmp/file.txt", 0); ... } }
从上面的例子可以看出,底层对象只需要实现 VFSFile
接口,就可以使用 VFSFile
接口相关的方法来操作对象,用户完全不需要了解底层对象的实现过程。
上面的 Java 例子已经大概说明虚拟文件系统的原理,但由于 Linux 是使用 C 语言来编写的,而 C 语言并没有接口这个概念。所以,Linux 内核使用了一些技巧来模拟接口这个概念。
下面来介绍一下 Linux 内核是如何实现的。
为了模拟接口,Linux 内核定义了一个名为 file
的结构体,其定义如下:
struct file { ... const struct file_operations *f_op; ... };
在 file 结构中,最为重要的一个字段就是 f_op
,其类型为 file_operations
结构。而 file_operations
结构是由一组函数指针组成,其定义如下:
struct file_operations { ... 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 *); ... int (*open) (struct inode *, struct file *); ... };
从 file_operations
结构的定义可以隐约看到接口的影子,所以可以猜想出,如果实现了 file_operations
结构中的方法,应该就能接入到虚拟文件系统中。
在 Linux 内核中,file
结构代表着一个被打开的文件。所以,只需要将 file
结构的 f_op
字段设置成不同文件系统实现好的方法集,那么就能够使用不同文件系统的功能。
这个过程在 __dentry_open()
函数中实现,如下所示:
static struct file * __dentry_open(struct dentry *dentry, struct vfsmount *mnt, truct file *f, int (*open)(struct inode *, struct file *), const struct cred *cred) { ... inode = dentry->d_inode; ... // 设置file结构的f_op字段为底层文件系统实现的方法集 f->f_op = fops_get(inode->i_fop); ... return f; }
设置好 file
结构的 f_op
字段后,虚拟文件系统就能够使用通用的接口来操作此文件了。调用过程如下:
底层文件系统需要实现虚拟文件系统的接口,才能被虚拟文件系统使用。也就是说,底层文件系统需要实现 file_operations
结构中的方法集。
一般底层文件系统会在其内部定义好 file_operations
结构,并且填充好其方法集中的函数指针。如 minix文件系统
就定义了一个名为 minix_file_operations
的 file_operations
结构。其定义如下:
// 文件:fs/minix/file.c const struct file_operations minix_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, .write = do_sync_write, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = generic_file_fsync, .splice_read = generic_file_splice_read, };
也就是说,如果当前使用的是 minix 文件系统,当使用 read()
函数读取其文件的内容时,那么最终将会调用 do_sync_read()
函数来读取文件的内容。
到这里,虚拟文件系统的原理基本分析完毕,但还有两个非常重要的结构要介绍一下的:dentry
和 inode
。
dentry
结构表示一个打开的目录项,当我们打开文件 /usr/local/lib/libc.so
文件时,内核会为文件路径中的每个目录创建一个 dentry
结构。如下图所示:
由于 /usr/local/lib/libc.so
和 /tmp/libc.so
指向同一个文件,所以它们都使用同一个 inode
对象。
inode 结构保存了文件的所有属性值,如文件的创建时间、文件所属用户和文件的大小等。其定义如下所示:
struct inode { ... uid_t i_uid; // 文件所属用户 gid_t i_gid; // 文件所属组 ... struct timespec i_atime; // 最后访问时间 struct timespec i_mtime; // 最后修改时间 struct timespec i_ctime; // 文件创建时间 ... unsigned short i_bytes; // 文件大小 ... const struct file_operations *i_fop; // 文件操作方法集(用于设置file结构) ... };
我们注意到 inode 结构有个类型为 file_operations
结构的字段 i_fop
,这个字段保存了文件的操作方法集。当用户调用 open()
系统调用打开文件时,内核将会使用 inode
结构的 i_fop
字段赋值给 file
结构的 f_op
字段。我们再来重温下赋值过程:
static struct file * __dentry_open(struct dentry *dentry, struct vfsmount *mnt, truct file *f, int (*open)(struct inode *, struct file *), const struct cred *cred) { ... // 文件对应的inode对象 inode = dentry->d_inode; ... // 使用inode结构的i_fop字段赋值给file结构的f_op字段 f->f_op = fops_get(inode->i_fop); ... return f; }
本文主要介绍了 虚拟文件系统
的基本原理,从分析中可以发现,虚拟文件系统使用了类似于面向对象编程语言中的接口概念。正是有了 虚拟文件系统
,Linux 才能支持各种各样的文件系统。
위 내용은 Linux 가상 파일 시스템의 원리를 자세히 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!