话说文件系统——一个简单的文件系统(一)【转】

本文转载自:https://www.cnblogs.com/xie0812/articles/8832881.html

linux的文件系统很庞大,之前看过、学过、哭过、也闹过,差点就撒娇了,哎,只怪功底不够,硬是没有看明白,心想小僧此生与它无缘了,

又无高人,迷津终没有得到指点。时间就这么平静而有飞逝着,突然有一天无意当中看到一本叫

《linux内核探秘:深入解析文件系统和设备驱动的框架与设计》书,里面有一个最简单的文件系统(aufs)的实现,又激起我研究linux文件系统

的欲望。发现aufs的实现仅仅有两百多行,正由于它的简单,分析起来容易,同时也涉及到了linux文件系统的各个方面,分析之后,对文件系统

的基本概念有了最基本的认识,为后面的学习打下了基础,在此把整个学习的过程做个记录,如果对大家有帮助,我就很荣幸了。

  回顾来看,其实之前没有弄明白的主要原因在于着急,没有从基础的、简单的开始,一上来就直接看源代码,分析sysfs这些成熟的文件系统,

由于sysfs本身跟其他的东西错综盘旋在一起,增加了很多的难度,这样连续几天就会失去学习的信心,从而放弃,所谓心急吃不了热豆腐,欲速

则不达啊。正因为此,我们最开始先看一下aufs的实现,自己编译一波,感受一下,有个感性的认识,而不一上来就讲原理,我们要循序渐进,

下面就是aufs的实现。

aufs文件系统的实现源码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

#include <linux/module.h>

#include <linux/fs.h>

#include <linux/pagemap.h>

#include <linux/init.h>

#include <linux/namei.h>

#include <linux/cred.h>

#include <linux/mount.h>

//每个文件系统需要一个MAGIC number

#define AUFS_MAGIC  0x64668735

//aufs文件系统的挂载点

static struct vfsmount *aufs_mount;

//根据创建的aufs文件系统的 super_block创建具体的inode结构体

static struct inode *aufs_get_inode(struct super_block *sb, int mode,

                dev_t dev)

{

    struct inode *inode = new_inode(sb);

    if (inode) {

        inode->i_mode = mode;

        inode->i_uid = current_fsuid();

        inode->i_gid = current_fsgid();

        inode->i_blocks = 0;

        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;

        switch (mode & S_IFMT) {

            default:

                init_special_inode(inode, mode, dev);

                break;

            case S_IFREG:

                printk("create a file \n");

                break;

            case S_IFDIR:

                inode->i_op = &simple_dir_inode_operations;

                inode->i_fop = &simple_dir_operations;

                printk("creat a dir file \n");

                

                inode->__i_nlink++;

                break;

        }

    }

    return inode;

}

//把创建的inode和dentry结构体连接起来

static int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)

{

    struct inode * inode;

    int error = -EPERM;

    if (dentry->d_inode)

        return -EEXIST;

    inode = aufs_get_inode(dir->i_sb, mode, dev);

    if (inode) {

        d_instantiate(dentry, inode);

        dget(dentry);

        error = 0;

    }

    

    return error;

}

static int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)

{

    int res;

    res = aufs_mknod(dir, dentry, mode | S_IFDIR, 0);

    if (!res) {

        dir->__i_nlink++;

    }

    return res;

}

static int aufs_create(struct inode *dir, struct dentry *dentry, int mode)

{

    return aufs_mknod(dir, dentry, mode | S_IFREG, 0);

}

//根据父dentry、mode、name创建子dentry

static int aufs_create_by_name(const char *name, mode_t mode,

        struct dentry *parent, struct dentry **dentry)

{

    int error = 0;

    if (!parent) {

        if (aufs_mount && aufs_mount->mnt_sb) {

            parent = aufs_mount->mnt_sb->s_root;

        }

    }

    if (!parent) {

        printk("Ah! can not find a parent!\n");

        return -EFAULT;

    }

    *dentry = NULL;

    mutex_lock(&parent->d_inode->i_mutex);

    *dentry = lookup_one_len(name, parent, strlen(name));

    if (!IS_ERR(dentry)) {

        if ((mode & S_IFMT) == S_IFDIR)

            error = aufs_mkdir(parent->d_inode, *dentry, mode);

        else

            error = aufs_create(parent->d_inode, *dentry, mode);

    else

        error = PTR_ERR(dentry);

    mutex_unlock(&parent->d_inode->i_mutex);

    return error;

}

//在aufs文件系统中创建文件

struct dentry *aufs_create_file(const char *name, mode_t mode,

            struct dentry *parent, void *data,

            struct file_operations *fops)

{

    struct dentry *dentry = NULL;

    int error;

    printk("aufs: creating file ‘%s‘", name);

    

    error = aufs_create_by_name(name, mode, parent, &dentry);

    if (error) {

        dentry = NULL;

        goto exit;

    }

    if (dentry->d_inode) {

        if (data)

            dentry->d_inode->i_private = data;

        if (fops)

            dentry->d_inode->i_fop = fops;

    }

exit:

    return dentry;

}

//在aufs文件系统中创建一个文件夹

struct dentry *aufs_create_dir(const char *name, struct dentry *parent)

{

    return aufs_create_file(name, S_IFDIR | S_IRWXU | S_IRUGO, parent, NULL, NULL);

}

static int enabled = 1;

//对应于打开的aufs文件的读取方法

static ssize_t aufs_file_read(struct file *fle, char __user *buf, size_t nbytes, loff_t *ppos)

{

    char *s = enabled ? "aufs read enabled\n" "aufs read disabled\n";

    dump_stack();

    return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s));

}

//对应于打开的aufs文件的写入方法

static ssize_t aufs_file_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)

{

    int res = *buffer - ‘0‘;

    if (res)

        enabled = 1;

    else

        enabled = 0;

    return count;

}

//对应具体打开文件的文件操作方式

static struct file_operations aufs_file_operations = {

    .read = aufs_file_read,

    .write = aufs_file_write,

};

//用于填充aufs的super_block

static int aufs_fill_super(struct super_block *sb, void *data, int silent)

{

    static struct tree_descr debug_files[] = {{""}};

    return simple_fill_super(sb, AUFS_MAGIC, debug_files);

}

//创建aufs文件系统的对应的根目录的dentry

static struct dentry *aufs_get_sb(struct file_system_type *fs_type,

        int flags, const char *dev_name, void *data)

{

    return mount_single(fs_type, flags, data, aufs_fill_super);

}

//初始化aufs文件系统的 file_system_type结构,每个文件系统对应一个这样的结构体,主要用于提供具体文件系统的//的信息,以及操作的方法

static struct file_system_type aufs_type = {

    .name = "aufs",

    .mount = aufs_get_sb,

    .kill_sb = kill_litter_super,

};

//创建aufs文件系统,同时创建对应的文件夹和文件

static int __init aufs_init(void)

{

    int ret;

    struct dentry *pslot;

    

    ret = register_filesystem(&aufs_type);

    if (ret) {

        printk(KERN_ERR "aufs: cannot register file system\n");

        return ret;

    }

    aufs_mount = kern_mount(&aufs_type);

    if (IS_ERR(aufs_mount)) {

        printk(KERN_ERR "aufs: cannot mount file system\n");

        unregister_filesystem(&aufs_type);

        return ret;

    }

    pslot = aufs_create_dir("woman_star", NULL); //创建woman_star文件系统,返回所创建文件夹的dentry

    aufs_create_file("lbb", S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);//在对应的文件夹下,创建具体的文件

    aufs_create_file("fbb", S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);

    aufs_create_file("lj1", S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);

    pslot = aufs_create_dir("man_star", NULL);

    aufs_create_file("ldh", S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);

    aufs_create_file("lcw", S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);

    aufs_create_file("jw",  S_IFREG | S_IRUGO, pslot, NULL, &aufs_file_operations);

    return 0;

}

//卸载aufs文件系统

static void __exit aufs_exit(void)

{

    kern_unmount(aufs_mount);

    unregister_filesystem(&aufs_type);

    aufs_mount = NULL;

}

module_init(aufs_init);

module_exit(aufs_exit);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("This is a simple module");

MODULE_VERSION("Ver 0.1");

下面编译的Makefile文件:


1

2

3

4

5

6

7

8

9

ifneq ($(KERNELRELEASE),)

obj-m := aufs.o

else

KDIR := /lib/modules/$(shell uname -r)/build

all:

    make -C $(KDIR) M=$(shell pwd) modules

clean:

    rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

endif

程序编译后,我们通过insmod 命令加载模块,然后执行如下操作。

1.在根目录下创建一个目录:

mkdir aufs

2. 挂载文件系统:

mount -t aufs none aufs/

3. 列出文件系统的内容:

ls

通过查看看到了“woman_star”和“man_star”两个目录。同时里面又有对应的文件。

原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9024202.html

时间: 2025-01-10 02:20:53

话说文件系统——一个简单的文件系统(一)【转】的相关文章

一个简单的文件系统过滤驱动框架

很多人认为文件系统过滤驱动很复杂,其实也有一定道理,因为需要有很多细节需要考虑到,这是一个简单的文件系统过滤驱动,抛去了大部分细节,留下了一个简单的框架,其实这样文件系统过滤驱动就变得蛮简单的,很多接口可以不用实现,只要知道大致流程,其它都将会很清晰. #define DBG 1 #include <ntifs.h> #include "fsfilter.h" PDEVICE_OBJECT g_Cdo; PDRIVER_OBJECT g_MyDriver; NTSTATUS

[操作系统实践][简单的文件系统]

简单文件系统的实现 要求 内存中开辟一块虚拟磁盘空间作为文件存储分区,在其上实现一个简单的基于多级目录的单用户单任务系统中的文件系统. 在退出该文件系统的使用时,虚拟文件系统以一个文件的方式保存到磁盘中,以便下次可以把它恢复到内存的虚拟存储空间 实际实现 以上两点均实现 能处理绝对路径和相对路径的命令 例如 : cd /home/zy/Desktop/ 这样的绝对路径 cd ../hah/1/2 这样的相对路径 mkdir,rmdir,cd,creat,rm均支持 open_path 是open

攻城狮在路上(叁)Linux(十八)--- 文件系统的简单操作

本篇仅作为补漏. 一.查看磁盘和目录的容量:df  du df:列出文件系统的整体磁盘使用量. du:评估文件系统的磁盘使用量(常用于评估目录所占容量) 二.连接文件:ln 1.hard link:硬连接或实际连接 ln /etc/crontab crontab1; <== 创建硬连接 硬连接不创建文件(虽然使用ls命令时可以看到一个新的文件,但是两者的inode一致),仅是在目录block中增加一个文件名-inode的映射而已. 限制: A.不能跨文件系统. B.不能连接到目录(因为复杂度较高

Exynos4412从SD卡启动的简单网络文件系统制作

Exynos4412从SD卡启动的简单网络文件系统制作 1. 简介 嵌入式系统能够在开发板上正常运行,需要先进行系统配置,一个完整的嵌入式系统应该包含的几个部分::uboot,kernel,rootfs,appfs.这几部分在ARM板Flash上的位置关系如下图所示: 注:图片来源于韦东山老师的<嵌入式Linux应用开发完全手册> rootfs可以不用添加到开发板,而是部署到PC机上,开发板在运行完kernel,要挂载rootfs时,可以通过NFS网络挂载到设定好的PC机上的文件系统上. 操作

根文件系统的简单定制

1)关闭selinux修改文件/etc/selinux/configSELINUX=disabled2)关闭防火墙chkconfig iptables off关闭虚拟机防火墙: 关闭命令:  service iptables stop 永久关闭防火墙:chkconfig iptables offservice iptables stop3)设置密码passwd root+ <<EOFavt123456avt123456EOF4)启动sshdservice sshd start 根文件系统的简单

btrfs文件系统的简单管理及应用

一.btrfs的命令选项 mkfs.btrfs -L 'LABEL' 指定卷标 -d <type>: raid0,raid1, raid5, raid6, raid10, single   指明数据存储类型 -m <profile>: raid0,raid1, raid5, raid6, raid10, single, dup  指明源数据存储的机制 -O <feature> 指明在格式化时使用的特性 -O list-all: 列出支持的所有feature man bt

如何把一个数据存到文件系统中?是怎么存的?--【sky原创】

块设备文件: 表示文件系统高速缓存的设备,例如硬盘驱动器 设备文件: 表示非高速缓存的设备,例如磁带驱动器.鼠标和系统终端 那么如何把一个数据存到文件系统中?是怎么存的? 一般地,我们认为文件就是文件的数据信息,它存放在磁盘上,如果单纯的这样理解就错了 和每一个文件相关的信息都会放在索引节点上,比方说它是字符设备的话,就是字符设备文件,还有它的权限,属组,以及大小.更新时间等信息都属于文件的相关信息,如果一个文件的大小是1kb的话,那么实际拷贝文件的话,所需要的空间要大于1kb,因为它还要拷贝索

Hyperledger Fabric 建立一个简单网络

p { margin-bottom: 0.25cm; line-height: 120% } Building you first network 网络结构: 2个Orgnizations(每个Org包含2个peer节点)+1个solo ordering service 打开fabric-sample下的示例first-network p { margin-bottom: 0.25cm; line-height: 120% } 其中byfn.sh为启动这个网络的启动脚本,启动脚本中除建立一个包含

作业3:构造一个简单的Linux系统MenuOS 20135115臧文君

构造一个简单的Linux系统MenuOS 注:作者:臧文君,原创作品转载请注明出处,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内核源代码介绍 1.根目录 arch/x86目录下的代码是我们重点关注的,arch中包括支持不同CPU的源代码. init目录下包含内核启动相关的代码,如main.c(start_kernel函数相当于普通C程序的main函数,是Linux内核初始化的起点). ipc