文档库

最新最全的文档下载
当前位置:文档库 > 文件系统

文件系统

文件系统实验

一实验目的

1.加深对进程的理解,理解内核是对进程如何管理的

2.了解进程的几个状态,和他们相互切换的方法

3.掌握常见的调度算法原理,对系统的性能有什么影响

二准备知识

1. linux文件系统概述

文件系统指文件存在的物理空间。在Linux系统中,每个分区都是一个文件系统,都有自己的目录层次结构。Linux的最重要特征之一就是支持多种文件系统,这样它更加灵活,并可以和许多其它种操作系统共存。

Virtual File System(虚拟文件系统)使得Linux可以支持多个不同的文件系统。由于系统已将Linux文件系统的所有细节进行了转换,所以Linux 核心的其它部分及系统中运行的程序将看到统一的文件系统。Linux的虚拟文件系统允许用户同时能透明地安装许多不同的文件系统。虚拟文件系统是为Linux用户提供快速且高效的文件访问服务而设计的。

随着Linux的不断发展,它所支持的文件格式系统也在迅速扩充。特别是Linux 2.4内核正式推出后,出现了大量新的文件系统,其中包括日志文件系统ext3、ReiserFS、XFSJFS和其它文件系统。Linux系统核心可以支持十多种文件系统类型:JFS、 ReiserFS、ext、ext2、ext3、ISO9660、XFS、Minx、MSDOS、UMSDOS、VFAT、NTFS、HPFS、NFS、SMB、SysV、PROC 等.

2.文件系统的创建

这个过程是存储设备建立文件系统的过程,一般也被称为格式化或初始化,通过一些初始化工具来进行。当重新建立Linux核心时安装程序会询问是否需要所有可支持的文件系统。核心重建时文件系统启动代码包含了所有那些编入核心的文件系统的初始化例程。另外Linux文件系统可构造成模块, 此时它们会仅在需要时加载或者使用insmod来载入。当文件系统模块被加载时, 它将向核心注册并在卸载时撤除注册。每个文件系统的初始化例程还将向虚拟文件系统注册,它用一个包含文件系统名称和指向其VFS超块读例程的指针的file_system_type结构表示。每个file_system_type结构包含下列信息:

Superblock read routine

此例程载文件系统的一个实例被安装时由VFS调用。

File System name

文件系统的名称如ext2。

Device needed

文件系统是否需要设备支持。并不是所有的文件系统都需要设备来保存它。例如/proc文件系统不需要块设备支持。

3.挂载(mount)

文件系统只有挂载才能使用,Unix类的操作系统如此,Window也是一样;在Windows更直观一些,具体内部机制我们不太了解。但Unix类的操作系统是通过mount进行的,挂载文件系统时要有挂载点,比如我们在安装Linux的过程中,有时会提示我们分区,然后建立文件系统,接着是问你的挂载点是什么,我们大多选择的是/ 。我们在Linux系统的使用过程中,也会挂载其它的硬盘分区,也要选中挂载点,挂载点通常是一个空置的目录,最好是我们自建的空置目录.如下的一个mount命令mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom

mount命令将传递三个参数给核心:文件系统名,包含文件系统的

物理块设备以及此新文件系统要安装到的已存在的目录名4.EXT2文件系统

象很多文件系统一样, EXT2建立在数据被保存在数据块中的文件内这个前提下。这些数据块长度相等且这个长度可以变化,某个EXT2文件系统的块大小在创建(使用mke2fs)时设置。每个文件的大小和刚好大于它的块大小正数倍相等。如果块大小为1024字节而一个1025字节长的文件将占据两个1024字节大小的块。这样你不得不浪费差不多一般的空间。

我们通常需要在CPU的内存利用率和磁盘空间使用上进行折中。而大多数操作系统,包括Linux在内,为了减少CPU的工作负载而被迫选择相对较低的磁盘空间利用率。并不是文件中每个块都包含数据,其中有些块被用来包含描叙此文件系统结构的信息。EXT2通过一个inode结构来描叙文件系统中文件并确定此文件系统的拓扑结构。 inode结构描叙文件中数据占据哪个块以及文件的存取权限、文件修改时间及文件类型。EXT2文件系统中的每个文件用一个inode来表示且每个inode有唯一的编号。文件系统中所有的inode都被保存在inode表中。 EXT2目录仅是一个包含指向其目录入口指针的特殊文件(也用inode表示系统)。

(1)The EXT2 Inode

在EXT2文件系统中inode是基本块;文件系统中的每个文件与目录由唯一的inode来描叙。每个数据块组的EXT2 inode被保存在inode

表中, 同时还有一个位图被系统用来跟踪已分配和未分配的inode。

它包含以下几个域:

mode

它包含两类信息;inode描叙的内容以及用户使用权限。EXT2中的inode可以表示一个文件、目录、符号连接、块设备、字符设备或FIFO。

Owner Information

表示此文件或目录所有者的用户和组标志符。文件系统根据它可以进行正确的存取。

Size

以字节计算的文件尺寸。

Timestamps

inode创建及最后一次被修改的时间。

Datablocks

指向此inode描叙的包含数据的块指针。前12个指针指向包含由inode描叙的物理块, 最后三个指针包含多级间接指针。例如两级间接指针指向一块指针,而这些指针又指向一些数据块。这意味着访问文件尺寸小于或等于12个数据块的文件将比访问大文件快得多。

EXT2 inode还可以描叙特殊设备文件。虽然它们不是真正的文件, 但可以通过它们访问设备。所有那些位于/dev中的设备文件可用来存取Linux设备。例如mount程序可把设备文件作为参数。

(2)EXT2 超块

超块中包含了描叙文件系统基本尺寸和形态的信息。文件系统管理器利用它们来使用和维护文件系统。通常安装文件系统时只读取数据块组0中的超块,但是为了防止文件系统被破坏, 每个数据块组都包含了复制拷贝。超块包含如下信息:

Magic Number

文件系统安装软件用来检验是否是一个真正的EXT2文件系统超块。Revision Level

这个主从修订版本号让安装代码能判断此文件系统是否支持只存在于某个特定版本文件系统中的属性。同时它还是特性兼容标志以帮助安装代码判断此文件系统的新特性是否可以安全使用。

Mount Count and Maximum Mount Count

系统使用它们来决定是否应对此文件系统进行全面检查。每次文件系统安装时此安装记数将递增,当它等于最大安装记数时系统将显示一条警告信息“maxumal mount count reached, running e2fsck is recommended”。

Block Group Number

超块的拷贝。

Block Size

以字节记数的文件系统块大小,如1024字节。

Blocks per Group

每个组中块数目,当文件系统创建时此块大小被固定下来。

Free Blocks

文件系统中空闲块数。

Free Inodes

文件系统中空闲Inode数。

First Inode

文件系统中第一个inode号。EXT2根文件系统中第一个inode将是指向'/'目录

的目录入口。

(3)组描述符

每个数据块组都拥有一个描叙它结构的组描述符。象超块一样,所有数据块组中的组描叙符被复制到每个数据块组中以防文件系统

崩溃。每个组描叙符包含以下信息:

Blocks Bitmap

对应此数据块组的块分配位图的块号。在块分配和回收时使用。

Inode Bitmap

对应此数据块组的inode分配位图的块号。在inode分配和回收时使用。

Inode Table

对应数据块组的inode表的起始块号。每个inode用下面的EXT2 inode结构

来表示。

Free blocks count, Free Inodes count, Used directory count

组描叙符放置在一起形成了组描叙符。

每个数据块组在超块拷贝后包含整个组描叙符表。EXT2文件系统仅使用第一个拷贝(在数据块组0中)。其它拷贝都象超块拷贝一样用

来防止主拷贝被破坏。

三实验内容

ext2文件系统应该说是Linux正宗的文件系统,早期的Linux都是用ext2,但随着技术的发展,大多Linux的发行版本目前并不用这个文件系统了;比如Redhat和Fedora 大多都建议用ext3 ,ext3文件系统是由ext2发展而来的。本实验的内容是要添加一个类似于ext2的自定义文件系统myext2。、myext2文件系统的物理格式定义与ext2基本一致,它是ext2的定制版本,它只支持原来ext2文件系统的部分操作,以及修改部分操作。

四实验指导

方法一:(适合2.6 kernel)

(1)、用编辑器(如:gedit)的替换命令,把myext2目录下所有的.c和.h文件中,将原来的“ext2”替换成“myext2”,将原来的“EXT2”替换成“MYEXT2”。

别忘了把ext2.h文件名改成myext2.h。注意大小写。

(2)、用gedit编辑器替换命令,把include/linux目录下myext2_fs.h和myext2_fs_sb.h 文件中,将原来的“ext2”替换成“myext2”,将原来的“EXT2”替换成“MYEXT2”。注意大小写。

(3)、在include/asm/bitops.h文件倒数第4行添加如下代码:

#define myext2_set_bit_atomic(lock,nr,addr) \

test_and_set_bit((nr),(unsigned long*)addr)

#define myext2_clear_bit_atomic(lock,nr, addr) \

test_and_clear_bit((nr),(unsigned long*)addr)

(4)、在include/asm-generic/bitops/ext2-atomic.h文件倒数第2行添加如下代码:#define myext2_set_bit_atomic(lock, nr, addr) \

({ \

int ret; \

spin_lock(lock); \

ret = myext2_set_bit((nr), (unsigned long *)(addr)); \

spin_unlock(lock); \

ret; \

})

#define myext2_clear_bit_atomic(lock, nr, addr) \

({ \

int ret; \

spin_lock(lock); \

ret = myext2_clear_bit((nr), (unsigned long *)(addr)); \

spin_unlock(lock); \

ret; \

})

(5)、在include/asm-generic/bitops/ext2-non-atomic.h文件倒数第17行添加如下代码:

#define myext2_set_bit(nr,addr) \

generic___test_and_set_le_bit((nr),(unsigned long *)(addr))

#define myext2_clear_bit(nr,addr) \

generic___test_and_clear_le_bit((nr),(unsigned long *)(addr))

#define myext2_test_bit(nr,addr) \

generic_test_le_bit((nr),(unsigned long *)(addr))

#define myext2_find_first_zero_bit(addr, size) \

generic_find_first_zero_le_bit((unsigned long *)(addr), (size))

#define myext2_find_next_zero_bit(addr, size, off) \

generic_find_next_zero_le_bit((unsigned long *)(addr), (size), (off))

(6).修改fs/myext2/Makefile文件改成:

obj-$(CONFIG_MY EXT2_FS) += myext2.o

my ext2-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ ioctl.o namei.o super.o symlink.o

my ext2-$(CONFIG_MY EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o my ext2-$(CONFIG_MY EXT2_FS_POSIX_ACL) += acl.o

my ext2-$(CONFIG_MY EXT2_FS_SECURITY) += xattr_security.o

my ext2-$(CONFIG_MY EXT2_FS_XIP) += xip.o

即把ext2改成myext2

(7).在fs/kconfig文件的第70行增加如下内容,即复制原ext2选项,改成myext2。

config MYEXT2_FS

tristate "MY Second extended fs support"

help

MYExt2 is a standard Linux file system for hard disks.

To compile this file system support as a module, choose M here: the

module will be called ext2. Be aware however that the file system

of your root partition (the one containing the directory /) cannot

be compiled as a module, and so this could be dangerous.

If unsure, say Y.

config MYEXT2_FS_XATTR

bool "MYExt2 extended attributes"

depends on MYEXT2_FS

help

Extended attributes are name:value pairs associated with inodes by

the kernel or by users (see the attr(5) manual page, or visit

for details).

If unsure, say N.

config MYEXT2_FS_POSIX_ACL

bool "MYExt2 POSIX Access Control Lists"

depends on MYEXT2_FS_XATTR

select MYFS_POSIX_ACL

help

Posix Access Control Lists (ACLs) support permissions for users and groups beyond the owner/group/world scheme.

To learn more about Access Control Lists, visit the Posix ACLs for

Linux website .

If you don't know what Access Control Lists are, say N

config MYEXT2_FS_SECURITY

bool "MYExt2 Security Labels"

depends on MYEXT2_FS_XATTR

help

Security labels support alternative access control models

implemented by security modules like SELinux. This option

enables an extended attribute handler for file security

labels in the ext2 filesystem.

If you are not using a security module that requires using

extended attributes for file security labels, say N.

config MYEXT2_FS_XIP

bool "Ext2 execute in place support"

depends on MYEXT2_FS

help

Execute in place can be used on memory-backed block devices. If you enable this option, you can select to mount block devices which are capable of this feature without using the page cache.

If you do not use a block device that is capable of using this,

or if unsure, say N.

(8)、编译内核、重新启动

◆# make menuconfig

●把file system->MY Second extended fs support选项设置成“*”

◆# make

◆# make modules_install

◆# make install

◆启动内核

方法二:(适合2.4 kernel)

例如,

---linux/include/linux/myext2_fs.h.orig

+++linux/include/linux/myext2_fs.h

……

***************

*** 65,76 ****

/* First non-reserved inode for old ext2 filesystems */

-#define EXT2_GOOD_OLD_FIRST_INO 11

+#define MYEXT2_GOOD_OLD_FIRST_INO 11

/*

* The second extended file system magic number

*/

-#define EXT2_SUPER_MAGIC 0xEF53

+#define MYEXT2_SUPER_MAGIC 0xEF53

/*

* Maximal count of links to a file

*/

-#define EXT2_LINK_MAX 32000

+#define MYEXT2_LINK_MAX 32000

……

***************

*** 217,217 ****

-struct ext2_inode {

+struct myext2_inode {

……

再如:

---linux/fs/myext2/namei.c.orig

+++linux/fs/myext2/namei.c

……

***************

*** 95,107 ****

-static int ext2_create (struct inode * dir, struct dentry * dentry, int mode) +static int myext2_create (struct inode * dir, struct dentry * dentry, int mode) {

- struct inode * inode = ext2_new_inode (dir, mode);

+ struct inode * inode = myext2_new_inode (dir, mode);

int err = PTR_ERR(inode);

if (!IS_ERR(inode)) {

- inode->i_op = &ext2_file_inode_operations;

- inode->i_fop = &ext2_file_operations;

- inode->i_mapping->a_ops = &ext2_aops;

+ inode->i_op = &myext2_file_inode_operations;

+ inode->i_fop = &myext2_file_operations;

+ inode->i_mapping->a_ops = &myext2_aops;

mark_inode_dirty(inode);

- err = ext2_add_nondir(dentry, inode);

+ err = myext2_add_nondir(dentry, inode);

}

return err;

}

……

其它代码的修改类似。

关于具体文件系统部分的代码是修改完了,我们还需要修改操作系统中所有文件系统都需要的两个数据结构:struct super_block和struct inode。Linux要支持的文件系统,必须在这两个结构中的两个union中分别有所登记。因此,必须将myext2的信息也添加到这两个union中:

---linux/include/linux/fs.h.orig

+++linux/include/linux/fs.h

***************

*** 481,485 ****

struct minix_inode_info minix_i;

struct ext2_inode_info ext2_i;

+ struct myext2_inode_info myext2_i;

struct ext3_inode_info ext3_i;

***************

*** 727,731 ****

struct minix_sb_info minix_sb;

struct ext2_sb_info ext2_sb;

+ struct myext2_sb_info myext2_sb;

struct ext3_sb_info ext3_sb;

好了,源代码的修改工作到此结束。接下来就是第三步工作——编译源代码。首先要把myext2加到编译选项中去,以便在做make menuconfig的时候,可以将该选项加上去。做这项工作需要修改三个文件:

---linux/Documentation/Configure.help.orig

+++linux/Documentation/Configure.help

……

***************

*** 14016,14023 ****

be compiled as a module, and so this could be dangerous. Most

everyone wants to say Y here.

+My Second extended fs support

+CONFIG_MYEXT2_FS

+ This is the test of adding a self-defined filesystem.

Ext3 journalling file system support (EXPERIMENTAL)

在上面这段程序中添加了关于myext2的帮助,也就是在做make menuconfig的时候可以查看该选项的有关帮助的内容。

---linux/fs/Config.in.orig

+++linux/fs/Config.in

***************

*** 79,84 ****

tristate 'Second extended fs support' CONFIG_EXT2_FS

+tristate 'My Second extended fs support' CONFIG_MYEXT2_FS

+

tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS]

在上面这段程序中添加关于myext2配置宏,将编译选项和宏关联起来。

---linux/fs/Makefile.orig

+++linux/fs/Makefile

***************

*** 30,32 ****

subdir-$(CONFIG_EXT2_FS) += ext2

+subdir-$(CONFIG_MYEXT2_FS) += myext2

subdir-$(CONFIG_ZLIB_FS_INFLATE) += inflate_fs

在上面这段程序中,添加了myext2目录,将宏与源代码目录关联起来。

完成这些之后,已经成功地将源代码与编译选项关联。但是不要忘了,还有fs/myext2目录下的Makefile:

---linux/fs/myext2/Makefile.orig

+++linux/fs/myext2/Makefile

***************

*** 10,10 ****

-O_TARGET := ext2.o

+O_TARGET := myext2.o

上面Makefile的修改是为了防止在连接的时候,myext2的目标文件与ext2的目标文件冲突。

一切都准备就绪了,只等编译连接生成内核文件:

#make menuconfig

# 配置myext2

#make dep

#make clean

#make bzImage

编译成功,在连接的时候出现以下错误:

fs/fs.o: In function `myext2_free_blocks':

fs/fs.o(.text+0x263a5): undefined reference to `myext2_clear_bit'

fs/fs.o: In function `myext2_new_block':

fs/fs.o(.text+0x26674): undefined reference to `myext2_test_bit'

fs/fs.o(.text+0x26697): undefined reference to `myext2_find_next_zero_bit'

fs/fs.o(.text+0x26701): undefined reference to `myext2_find_next_zero_bit'

fs/fs.o(.text+0x26847): undefined reference to `myext2_find_first_zero_bit'

fs/fs.o(.text+0x26899): undefined reference to `myext2_test_bit'

fs/fs.o(.text+0x26932): undefined reference to `myext2_set_bit'

fs/fs.o(.text+0x26a3a): undefined reference to `myext2_set_bit'

fs/fs.o: In function `myext2_free_inode':

fs/fs.o(.text+0x27ca2): undefined reference to `myext2_clear_bit'

fs/fs.o: In function `myext2_new_inode':

fs/fs.o(.text+0x27f8a): undefined reference to `myext2_find_first_zero_bit'

fs/fs.o(.text+0x27fa8): undefined reference to `myext2_set_bit'

make: *** [vmlinux] Error 1

只要编译不出现问题,连接错误还是比较好办的。从显示出来的错误分析,估计是缺了这些函数的定义。根据逆向思维方法,只要在Linux源代码中搜索ext2_clear_bit,ext2_test_bit 等函数,找到它们之后,同样复制一份,改成myext2_cear_bit,myext2_test_bit等函数名就可以了。对这些函数逐个击破,先来搜索ext2_clear_bit。在include/asm/bitops.h中可以发现这些函数群。全部把它们复制一份再修改掉

---linux/include/asm/bitops.h.orig

+++linux/include/asm/bitops.h

***************

*** 369,379****

#define ext2_set_bit __test_and_set_bit

#define ext2_clear_bit __test_and_clear_bit

#define ext2_test_bit test_bit

#define ext2_find_first_zero_bit find_first_zero_bit

#define ext2_find_next_zero_bit find_next_zero_bit

+#define myext2_set_bit __test_and_set_bit

+#define myext2_clear_bit __test_and_clear_bit

+#define myext2_test_bit test_bit

+#define myext2_find_first_zero_bit find_first_zero_bit

+#define myext2_find_next_zero_bit find_next_zero_bit

添加完了以后,保存,退出。回到linux目录下,再次做make bzImage(这次不用做make clean和make dep了)。

第一部分工作——克隆ext2文件系统已经完成了。要把这些指令单独拎出来,放到linux/include/asm下,因为asm这个目录是一个连接,不同的计算机类型是不同的,在Intel

x86的机器上一般是连接到linux/include/asm-i386下。

添加的myext2文件系统是否可以正常使用呢?下面来对添加的myext2文件系统进行一下测试:

#dd if=/dev/zero of=myfs bs=1M count=1

#mkfs.ext2 myfs

#mount –t myext2 –o loop ./myfs /mnt

#mount

/dev/hda3 on / type ext2 (rw)

none on /proc type proc (rw)

/root/myfile on /mnt myext2 (rw,loop=/dev/loop0)

#umount /mnt

#mount –t ext2 –o loop ./myfs /mnt

#mount

/dev/hda3 on / type ext2 (rw)

none on /proc type proc (rw)

/root/myfile on /mnt ext2 (rw,loop=/dev/loop0)

#

对上面的命令我们逐一解释:

第一条dd if=/dev/zero of=myfs bs=1M count=1:

创建大小为1M的,名字为myfs的,内容全为0的文件。

第二条mkfs.ext2 myfs:

将myfs格式化成ext2文件系统。从理论上来看,myext2和ext2是完全一致的,当然除了名字外,所以,下面我们可以试着用myext2文件系统格式去mount我们刚刚做出来的ext2文件系统。

第三条mount –t myext2 –o loop ./myfs /mnt:

将myfs通过loop设备mount到/mnt目录下。请注意,我们用的参数是-t myext2,也就是用myext2文件系统格式去mount的,发现这样mount是可以的,也就证明了新内核已经支持我们的新文件系统myext2。

第四条mount:

用来检查当前的系统的mount情况。注意最后一行,发现我们的myext2已经被内核所认可,证明我们前面的实验是完全成功的!

第五条umount /mnt:

将原来的mount的文件系统umount下来,准备下一步测试。

第六条mount –t ext2 –o loop ./myfs /mnt:

将myfs通过loop设备mount到/mnt目录下。这次我们用的参数是-t ext2,这样做的目的是再来检查一下myext2和ext2是否完全一致,发现这样mount是可以的。也证明了ext2和myext2是一致的。

第七条mount:

检查结果证明我们的推测是完全正确的。

2.修改myext2的magic number

有了上面的成功基础后,这部分相对来讲就简单一些了。我们找到myext2的magic

number,并将其改为0x6666:

---linux/include/linux/myext2_fs.h.orig

+++linux/include/linux/myext2_fs.h

***************

*** 71,71 ****

-#define MYEXT2_SUPER_MAGIC 0xEF53

+#define MYEXT2_SUPER_MAGIC 0x6666

然后,再用make bzImage重新编译内核。

在测试这个部分之前,需要写个小程序,来修改创建的myext2文件系统的magic number。因为它必须和内核中记录myext2文件系统的magic number匹配,myext2文件系统才能被正确地mount。

假设这个程序经过编译后产生的可执行程序名字为changeMN。

下面开始测试:

#dd if=/dev/zero of=myfs bs=1M count=1

#mkfs.ext2 myfs

#./changeMN myfs

#mount –t myext2 –o loop ./myfs /mnt

#mount

/dev/hda3 on / type ext2 (rw)

none on /proc type proc (rw)

/root/myfile on /mnt myext2 (rw,loop=/dev/loop0)

#umount /mnt

#mount –t ext2 –o loop ./myfs /mnt

mount: wrong fs type, bad option, bad superblock on /dev/loop0,

or too many mounted file systems

#

第一、二条就不再解释了,我们从第三条开始:

第三条./changeMN myfs:

调用changeMN将myfs的magic number改掉。

第四、五条也不解释了,证明了我们的实验结果是正确的。

第六条也不需要解释了。

第八、九条这次我们试图用-t ext2去mount myext2文件系统,发现是失败的,因为它们的magic number不再匹配了。也可以测试一下,用-t myext2去mount ext2文件系统,可以得到相同的结果。

3. 修改文件系统操作

myext2只是一个实验性质的文件系统,我们希望它只要能支持简单的文件操作即可。因此在完成了myext2的总体框架以后,我们来看看如何修改掉myext2支持的一些操作,来加深对操作系统对文件系统的操作的理解。在创建自己的文件系统中,也会遇到希望自己创建的文件系统有自身特色的操作。下面我们以裁减myext2的mknod操作为例,了解这个过

程的实现流程。

Linux将所有的对块设备、字符设备和命名管道的操作,都看成对文件的操作。mknod 操作是用来产生那些块设备、字符设备和命名管道所对应的节点文件。在ext2文件系统中它的实现函数如下:

fs/ext2/namei.c

109 static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)

110 {

111 struct inode * inode = ext2_new_inode (dir, mode);

112 int err = PTR_ERR(inode);

113 if (!IS_ERR(inode)) {

114 init_special_inode(inode, mode, rdev);

115 mark_inode_dirty(inode);

116 err = ext2_add_nondir(dentry, inode);

117 }

118 return err;

119 }

它定义在结构ext2_dir_inode_operations中:

linux/fs/ext2/namei.c

338 struct inode_operations ext2_dir_inode_operations = {

339 create: ext2_create,

340 lookup: ext2_lookup,

341 link: ext2_link,

342 unlink: ext2_unlink,

343 symlink: ext2_symlink,

344 mkdir: ext2_mkdir,

345 rmdir: ext2_rmdir,

346 mknod: ext2_mknod,

347 rename: ext2_rename,

348 };

当然,从ext2克隆过去的myext2的myext2_mknod,以及myext2_dir_inode_operations 和上面的程序是一样的。

对于mknod函数,我们在myext2中作如下修改:

fs/myext2/namei.c

static int myext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)

{

printk(“<1>haha, mknod is not supported by myext2! you’ve been cheated!\n”);

return –EPERM;

}

添加的程序中:

第一行打印信息,说明mknod操作不被支持。

第二行将错误号为EPERM的结果返回给shell,即告诉shell,在myext2文件系统中,maknod不被支持。

修改完毕,然后重新编译内核。以新生成的内核重新启动计算机,我们在shell下执行

如下测试程序:

#mount –t myext2 –o loop ./myfs /mnt

#cd /mnt

#mknod myfifo p

haha, mknod is not supported by myext2! You’ve been cheated!

mknod: `myfifo': Operation not permitted

#

第一行命令:将myfs mount到/mnt目录下。

第二行命令:进入/mnt目录,也就是进入myfs这个myext2文件系统。

第三行命令:执行创建一个名为myfifo的命名管道的命令。

第四、五行是执行结果:第四行是我们添加的myext2_mknod函数的printk的结果;第五行是返回错误号EPERM结果给shell,shell捕捉到这个错误后打出的出错信息。需要注意的是,printk打印出来的信息不一定能在终端上显示出来,但是可以通过命令dmesg|tail 来观察。

如果还需要定制其它的操作,可以按照上面讲的原理和步骤来完成。