> 시스템 튜토리얼 > 리눅스 > Linux 가상 파일 시스템의 원리를 자세히 설명

Linux 가상 파일 시스템의 원리를 자세히 설명

WBOY
풀어 주다: 2024-02-15 09:21:11
앞으로
567명이 탐색했습니다.

Unix 세계에는 모든 것이 파일이다라는 고전적인 속담이 있습니다. 이것이 의미하는 바는 유닉스 운영체제에서는 모든 객체가 파일로 취급될 수 있고, 파일 운영을 위한 인터페이스를 사용해 조작할 수 있다는 것이다. Unix와 유사한 운영 체제인 Linux도 이러한 목표를 달성하기 위해 노력하고 있습니다.

가상 파일 시스템 소개

달성하려면 一切皆文件 这个目标,Linux 内核提供了一个中间层:虚拟文件系统(Virtual File System).

객체 지향 프로그래밍 언어(예: C++/Java 등)를 사용해 본 적이 있다면 이 개념을 잘 알고 있어야 합니다 接口. 가상 파일 시스템은 표준 인터페이스 세트를 정의하는 객체 지향 프로그래밍의 인터페이스와 유사합니다. 개발자는 이 인터페이스 집합을 구현하기만 하면 파일 운영용 인터페이스를 사용하여 개체를 운영할 수 있습니다. 아래 그림과 같이:

细说 Linux 虚拟文件系统原理

위 사진의 파란색 부분이 가상 파일 시스템의 위치입니다.

위 그림에서 볼 수 있듯이 가상 파일 시스템은 상위 계층 애플리케이션에 대한 통합 인터페이스를 제공합니다. 파일 시스템이 가상 파일 시스템의 인터페이스를 구현하는 경우 상위 계층 응용 프로그램은 open()read()write()와 같은 기능을 사용하여 작동할 수 있습니다.

오늘은 가상 파일 시스템의 원리와 구현에 대해 소개하겠습니다.

가상 파일 시스템의 원리

가상 파일 시스템의 원리를 설명하기 전에 먼저 Java 예제를 소개하겠습니다. 이 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 内核是如何实现的。

1. file结构

为了模拟接口,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 字段后,虚拟文件系统就能够使用通用的接口来操作此文件了。调用过程如下:

细说 Linux 虚拟文件系统原理

2. file_operations结构

底层文件系统需要实现虚拟文件系统的接口,才能被虚拟文件系统使用。也就是说,底层文件系统需要实现 file_operations 结构中的方法集。

一般底层文件系统会在其内部定义好 file_operations 结构,并且填充好其方法集中的函数指针。如 minix文件系统 就定义了一个名为 minix_file_operationsfile_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() 函数来读取文件的内容。

3. dentry结构

到这里,虚拟文件系统的原理基本分析完毕,但还有两个非常重要的结构要介绍一下的:dentryinode

dentry 结构表示一个打开的目录项,当我们打开文件 /usr/local/lib/libc.so 文件时,内核会为文件路径中的每个目录创建一个 dentry 结构。如下图所示:

细说 Linux 虚拟文件系统原理

由于 /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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:lxlinux.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿