解析Linux中的VFS文件系统

本文详细探讨了Linux中的虚拟文件系统(VFS)的概念,解释了它如何为应用程序提供一层抽象,屏蔽底层文件系统的差异。VFS在内存中建立一个目录树,作为所有其他文件系统的挂载点。文章通过分析内核源码,阐述了rootfs文件系统如何注册、挂载,并介绍了如何在VFS下建立目录,以及根文件系统的挂载过程。
摘要由CSDN通过智能技术生成

Vfs文件系统详解

前言:

本文基于linux kernel 3.14.17来讨论VFS机制,以及内核对VFS的支持,试图从源代码的角度来理解,所以在阅读本文之前需要读者对linuxVFS的基本的数据结构有所了解,(super_blockinodedentryvfsmount)

一、VFS的概念

VFSLinux中的一个虚拟文件文件系统,也称为虚拟文件系统交换层(Virtual Filesystem Switch)。它为应用程序员提供一层抽象,屏蔽底层各种文件系统的差异。如下图所示:

 


不同的文件系统,如Ext2/3XFSFAT32等,具有不同的结构,假如用户调用open等文件IO函数去打开文件,具体的实现会非常不同。为了屏蔽这种差异,Linux引入了VFS的概念。相当于是Linux自建了一个新的贮存在内存中的文件系统。所有其他文件系统都需要先转换成VFS的结构才能为用户所调用。

二、VFS 概述

VFS 是一种软件机制,也许称它为 Linux 的文件系统管理者更确切点,与它相关的数据结构只存在于物理内存当中。所以在每次系统初始化期间,Linux 都首先要在内存当中构造一棵 VFS 的目录树(在 Linux 的源代码里称之为 namespace),实际上便是在内存中建立相应的数据结构。VFS 目录树在 Linux 的文件系统模块中是个很重要的概念,希望读者不要将其与实际文件系统目录树混淆,在笔者看来,VFS 中的各目录其主要用途是用来提供实际文件系统的挂载点,当然在 VFS 中也会涉及到文件级的操作,本文不阐述这种情况。下文提到目录树或目录,如果不特别说明,均指 VFS 的目录树或目录。图 是一种可能的目录树在内存中的影像:

图 1VFS 目录树结构

 

三、rootfs目录树的建立

在众多的实际文件系统中,之所以单独介绍 rootfs 文件系统的注册过程,实在是因为该文件系统 VFS 的关系太过密切,如果说 ext2/ext3 是 Linux 的本土文件系统,那么 rootfs 文件系统则是 VFS 存在的基础。

1、文件系统的注册

int register_filesystem(struct file_system_type * fs)
{
	int res = 0;
	struct file_system_type ** p;

	BUG_ON(strchr(fs->name, '.'));
	if (fs->next)
		return -EBUSY;
	write_lock(&file_systems_lock);
	p = find_filesystem(fs->name, strlen(fs->name));
	if (*p)
		res = -EBUSY;
	else
		*p = fs;
	write_unlock(&file_systems_lock);
	return res;
}
static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
	struct file_system_type **p;
	for (p=&file_systems; *p; p=&(*p)->next)
		if (strlen((*p)->name) == len &&
		    strncmp((*p)->name, name, len) == 0)
			break;
	return p;
}
注册过程实际上将表示各实际文件系统的  struct file_system_type  数据结构的实例化,然后形成一个链表,内核中用一个名为  file_systems  的全局变量来指向该链表的表头。

 2、文件系统的挂载

本节阐述 Linux 在初始化阶段是如何建立根结点的,即 "/"目录。这其中会包括挂载 rootfs 文件系统到根目录 "/" 的具体过程。构造根目录的代码是在 init_mount_tree() 函数 (fs\namespace.c) 中。

文件系统类型

struct file_system_type {
	const char *name;
	int fs_flags;
	struct dentry *(*mount) (struct file_system_type *, int,
		       const char *, void *);
	void (*kill_sb) (struct super_block *);
	struct module *owner;
	struct file_system_type * next;
	struct hlist_head fs_supers;
};
这里只截取了关键的成员变量
图:文件系统挂载流程

 

内核通过sys_mount来挂载文件系统,其中关键函数是vfs_kern_mount()和graft_tree(),前者申请了一个挂载示例vfsmount,并调用要挂载的文件系统的mount()函数来申请对应的超级块、dentry和inode节点填充必要的字段和文件系统信息。下面我们以rootfs的挂载来详细阐述这一过程。

graft_tree() 函数要做的事情便是将 do_kern_mount() 函数返回的一 struct vf

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值