linux组态文件,设计模式在Linux文件系统中的简单实现

设计模式在Linux文件系统中的简单实现

注:这边文章是为了学习设计模式而写的,并不具有实际的意义。仅仅作为学习设计模式的一个参考。

Linux中的文件系统,设备驱动,和实际设备间的结构关系如下图所示:

567be4db16c480a1525811f9851113b8.gif

用户对设备上的数据进行I/O访问,都要先把I/O请求传递到VFS层,然后再通过实际的文件系统,最终传递到设备的驱动程序中。因为,Linux内核是由C语言和汇编语言来实现的,所以不可能像面向对象语言那样仅仅通过类的继承来就很方便的传递消息。正是由于这点,内核里仅仅使用了函数指针来达到这个目的。这里不再继续讲述文件系统间的函数指针的实现方式,因为只要看过内核源代码的人都应该了解这一点,这是学习内核的最起码的基础。

例如:

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png980 struct file_operations 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png981         struct module *owner;

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png982         loff_t (*llseek) (struct file *, loff_t, int);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png983         ssize_t (*read) (struct file *, char *, size_t, loff_t *);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png984         ssize_t (*write) (struct file *, const char *, size_t, loff_t *);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png985         int (*readdir) (struct file *, void *, filldir_t);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png986         unsigned int (*poll) (struct file *, struct poll_table_struct *);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png987         int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png988         int (*mmap) (struct file *, struct vm_area_struct *);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png… …

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

对于VFS层,只提供类似于上面文件操作结构体中的函数接口,那么,这些函数的具体实现都被包含在实际的文件系统中。VFS层只是根据被访问的inode,找到实际文件系统的文件操作函数表,表中的函数指针已经指向实际文件系统中对应的操作函数。这样做的目的就是为了方便用户在日后能添加一个新类型的文件系统到linux内核的源代码,而不用去修改VFS层的代码。这一点上还有点儿面向对象设计的味道,其实我认为,C语言中的函数指针是最能贴近面向对象设计的一个技术了,只是操作起来没有像C++语言那样方面,而且可读性不是很好。

为了学习设计模式,我把linux的文件系统设计中的一些极其简单的东西用设计模式来重新组织一下,因为我工作中接触的文件系统主要是xfs,所以文中的大部分设计都是基于xfs文件系统。

文件系统的挂载(mount)

今天,我就先拿文件系统的mount操作开刀。

首先看一下mount操作的简单流程:

sys_mount //mount指定的设备

|-- copy_mount_options

|-- do_mount

// 开始进入到VFS层

//REMOUNT选项被指定的时候

|-- do_remount

|-- do_remount_sb   //检查是否只读打开等

|-- fsync_super //调用s_op->write_super

|-- s_op->remount_fs //实施再mount处理

//BIND选项被指定的时候

|-- do_lookback

//REMOUNT/BIND以外的选项被指定的时候

|-- do_add_mount //mountpoint检查和读入super_block

|-- do_kernel_mount //权限检查

|-- get_sb_nodev //读入super_block

|-- fs_type->read_super //调用实际的super_block函数

// 下面进入到XFS文件系统层

|-- linvfs_read_super

|-- xfs_parseargs

|-- sb->s_op = &linvfs_sops;

|-- VFSOPS_MOUNT

|-- vfsops->vfs_mount

xfs_vfsmount

xfs_mount

xfs_cmountfs

xfs_readsb

xfs_mountfs

上面的函数调用关系中的函数的意思这里不做详细说明。

在mount文件系统的关键地点就是从实际的文件系统上读取该文件系统的超级块,上面的调用关系的转折点就是fs_type->read_super函数,从这一刻开始就是开始做实际的操作。

但是,对于设计VFS层的设计人员来说,他并不知道今后,其他的开发人员会添加什么样的文件系统。也就是说,他不知道fs_type->read_super应该指向哪一个实际的读取超级块的函数。如果利用行为模式中的command模式,就可以实现这一点。

对于command模式中的主要角色是,Invoker,Command,ConcreteCommand,Receiver这四种。再利用这种设计模式时,VFS的设计人员就可以把VFS层作为命令的invoker,VFS层的一个函数操作(函数指针,例如,mount, read, write)就作为command, 而当用户想为内核再添加一个新型的文件系统时,,receiver就是该用户实际编写的文件系统,另外,用户还需要编写concrete_command作为调用实际的函数的接口。这种模式的结构如下:

82167d09d2029ecbc83891d9dfcc9102.png

所以,对于VFS层的设计人员只需要设计Invoker(VFS类),Command类,在接受到来自用户空间的I/O请求时,只需要简单的调用Command类的Execute函数就可,而不用关心,该函数具体的是调用哪一个文件系统的实际操作函数。而设计实际文件系统的开发人员只需要从Command类派生一个具体的子类并重载Execute函数,就可以跟VFS层的接口对接。这样,就降低了VFS类和实际文件系统类的耦合,并提高VFS类和实际文件系本身的内聚,这正符合设计模式的思想。

简单的代码如下:

1

cbef093dcc044b2793832001e2365e43.pngclass mount

2

cbef093dcc044b2793832001e2365e43.png

3

cbef093dcc044b2793832001e2365e43.png

4

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

5

df37983f39daa189b8c814e01a6a9011.png

6

df37983f39daa189b8c814e01a6a9011.png

7

df37983f39daa189b8c814e01a6a9011.pngprotected:

8

df37983f39daa189b8c814e01a6a9011.png

9

df37983f39daa189b8c814e01a6a9011.png

10

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       mount() 

918e8df969f9f8c8d002f25cda86cade.png{}

11

df37983f39daa189b8c814e01a6a9011.png

12

df37983f39daa189b8c814e01a6a9011.png

13

df37983f39daa189b8c814e01a6a9011.pngpublic:       

14

df37983f39daa189b8c814e01a6a9011.png

15

df37983f39daa189b8c814e01a6a9011.png

16

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       virtual ~mount() 

918e8df969f9f8c8d002f25cda86cade.png{}

17

df37983f39daa189b8c814e01a6a9011.png

18

df37983f39daa189b8c814e01a6a9011.png

19

df37983f39daa189b8c814e01a6a9011.png       virtual void execute() = 0;

20

df37983f39daa189b8c814e01a6a9011.png

21

df37983f39daa189b8c814e01a6a9011.png

22

0ac3a2d53663ec01c7f7225264eeefae.png};

23

cbef093dcc044b2793832001e2365e43.png

24

cbef093dcc044b2793832001e2365e43.png

25

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.pngclass vfs 

918e8df969f9f8c8d002f25cda86cade.png{

26

df37983f39daa189b8c814e01a6a9011.png

27

df37983f39daa189b8c814e01a6a9011.png

28

df37983f39daa189b8c814e01a6a9011.pngpublic:

29

df37983f39daa189b8c814e01a6a9011.png

30

df37983f39daa189b8c814e01a6a9011.png

31

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvfs() 

918e8df969f9f8c8d002f25cda86cade.png{}

32

df37983f39daa189b8c814e01a6a9011.png

33

df37983f39daa189b8c814e01a6a9011.png

34

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvoid vfs_mount() 

918e8df969f9f8c8d002f25cda86cade.png{

35

df37983f39daa189b8c814e01a6a9011.png

36

df37983f39daa189b8c814e01a6a9011.png

37

df37983f39daa189b8c814e01a6a9011.png       mount* mnt = new xfs_mount(new xfs());

38

df37983f39daa189b8c814e01a6a9011.png

39

df37983f39daa189b8c814e01a6a9011.png

40

df37983f39daa189b8c814e01a6a9011.png       mnt->execute();

41

df37983f39daa189b8c814e01a6a9011.png

42

df37983f39daa189b8c814e01a6a9011.png

43

4a5daaec04350a363f186a4d2c5ed6ce.png}

44

df37983f39daa189b8c814e01a6a9011.png

45

df37983f39daa189b8c814e01a6a9011.png

46

0ac3a2d53663ec01c7f7225264eeefae.png};

47

cbef093dcc044b2793832001e2365e43.png

48

cbef093dcc044b2793832001e2365e43.png

49

cbef093dcc044b2793832001e2365e43.png

50

cbef093dcc044b2793832001e2365e43.png

51

cbef093dcc044b2793832001e2365e43.pngclass xfs

52

cbef093dcc044b2793832001e2365e43.png

53

cbef093dcc044b2793832001e2365e43.png

54

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

55

df37983f39daa189b8c814e01a6a9011.png

56

df37983f39daa189b8c814e01a6a9011.png

57

df37983f39daa189b8c814e01a6a9011.pngpublic:

58

df37983f39daa189b8c814e01a6a9011.png

59

df37983f39daa189b8c814e01a6a9011.png

60

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       xfs() 

918e8df969f9f8c8d002f25cda86cade.png{}

61

df37983f39daa189b8c814e01a6a9011.png

62

df37983f39daa189b8c814e01a6a9011.png

63

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       void do_mount() 

918e8df969f9f8c8d002f25cda86cade.png{

64

df37983f39daa189b8c814e01a6a9011.png

65

df37983f39daa189b8c814e01a6a9011.png

66

df37983f39daa189b8c814e01a6a9011.png              cout <

67

df37983f39daa189b8c814e01a6a9011.png

68

df37983f39daa189b8c814e01a6a9011.png

69

4a5daaec04350a363f186a4d2c5ed6ce.png       }

70

df37983f39daa189b8c814e01a6a9011.png

71

df37983f39daa189b8c814e01a6a9011.png

72

0ac3a2d53663ec01c7f7225264eeefae.png};

73

cbef093dcc044b2793832001e2365e43.png

74

cbef093dcc044b2793832001e2365e43.png

75

cbef093dcc044b2793832001e2365e43.png

76

cbef093dcc044b2793832001e2365e43.png

77

cbef093dcc044b2793832001e2365e43.pngclass xfs_mount : public mount

78

cbef093dcc044b2793832001e2365e43.png

79

cbef093dcc044b2793832001e2365e43.png

80

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

81

df37983f39daa189b8c814e01a6a9011.png

82

df37983f39daa189b8c814e01a6a9011.png

83

df37983f39daa189b8c814e01a6a9011.pngpublic:

84

df37983f39daa189b8c814e01a6a9011.png

85

df37983f39daa189b8c814e01a6a9011.png

86

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       xfs_mount(xfs* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

87

df37983f39daa189b8c814e01a6a9011.png

88

df37983f39daa189b8c814e01a6a9011.png

89

df37983f39daa189b8c814e01a6a9011.png              _xfs = filesystem;

90

df37983f39daa189b8c814e01a6a9011.png

91

df37983f39daa189b8c814e01a6a9011.png

92

4a5daaec04350a363f186a4d2c5ed6ce.png       }

93

df37983f39daa189b8c814e01a6a9011.png

94

df37983f39daa189b8c814e01a6a9011.png

95

df37983f39daa189b8c814e01a6a9011.png       

96

df37983f39daa189b8c814e01a6a9011.png

97

df37983f39daa189b8c814e01a6a9011.png

98

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       void execute() 

918e8df969f9f8c8d002f25cda86cade.png{

99

df37983f39daa189b8c814e01a6a9011.png

100

df37983f39daa189b8c814e01a6a9011.png

101

df37983f39daa189b8c814e01a6a9011.png              _xfs->do_mount();

102

df37983f39daa189b8c814e01a6a9011.png

103

df37983f39daa189b8c814e01a6a9011.png

104

4a5daaec04350a363f186a4d2c5ed6ce.png       }      

105

df37983f39daa189b8c814e01a6a9011.png

106

df37983f39daa189b8c814e01a6a9011.png

107

df37983f39daa189b8c814e01a6a9011.pngprivate:

108

df37983f39daa189b8c814e01a6a9011.png

109

df37983f39daa189b8c814e01a6a9011.png

110

df37983f39daa189b8c814e01a6a9011.png       xfs* _xfs;

111

df37983f39daa189b8c814e01a6a9011.png

112

df37983f39daa189b8c814e01a6a9011.png

113

df37983f39daa189b8c814e01a6a9011.png

114

df37983f39daa189b8c814e01a6a9011.png

115

0ac3a2d53663ec01c7f7225264eeefae.png};

116

cbef093dcc044b2793832001e2365e43.png

117

cbef093dcc044b2793832001e2365e43.png

但是,上述的代码中,vfs类的设计有一个很大的问题,

1

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.pngclass vfs 

918e8df969f9f8c8d002f25cda86cade.png{

2

df37983f39daa189b8c814e01a6a9011.png

3

df37983f39daa189b8c814e01a6a9011.png

4

df37983f39daa189b8c814e01a6a9011.pngpublic:

5

df37983f39daa189b8c814e01a6a9011.png

6

df37983f39daa189b8c814e01a6a9011.png

7

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvfs() 

918e8df969f9f8c8d002f25cda86cade.png{}

8

df37983f39daa189b8c814e01a6a9011.png

9

df37983f39daa189b8c814e01a6a9011.png

10

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvoid vfs_mount() 

918e8df969f9f8c8d002f25cda86cade.png{

11

df37983f39daa189b8c814e01a6a9011.png

12

df37983f39daa189b8c814e01a6a9011.png

13

df37983f39daa189b8c814e01a6a9011.png       mount* mnt = new xfs_mount(new xfs());

14

df37983f39daa189b8c814e01a6a9011.png

15

df37983f39daa189b8c814e01a6a9011.png

16

df37983f39daa189b8c814e01a6a9011.png       mnt->execute();

17

df37983f39daa189b8c814e01a6a9011.png

18

df37983f39daa189b8c814e01a6a9011.png

19

4a5daaec04350a363f186a4d2c5ed6ce.png}

20

df37983f39daa189b8c814e01a6a9011.png

21

df37983f39daa189b8c814e01a6a9011.png

22

0ac3a2d53663ec01c7f7225264eeefae.png};

23

cbef093dcc044b2793832001e2365e43.png

在vfs_mount函数的设计里,设计人员根据不知道mount的子类的名字,而且,实际的文件系统类的名字他就更不知道了,而且,这两个类的实例化应该由实际文件系统设计者来创建。所以,这里不能这样实现。那么,VFS层怎么能得到已经创建xfs_mount和xfs类的实例呢?这个也并不难,我们可以个把xfs_mount和xfs类看作是一个具体的产品(product),只需要在VFS层设计一个抽象的工厂类和一些抽象的产品类,这样就可以利用工厂方法把xfs_mount和xfs类的实例化延迟到,实际文件系统设计者编写的具体的工厂类中。所以,在vfs_mount()中,只需要得到一个具体的工厂类,就可以很轻松的创建了xfs_mount和xfs类了。而具体的工厂类是在内核初始化是被创建的,VFS层设计者只需要根据特定的参数来查找这个具体的工厂类的实例。那么在上述代码中加入工厂方法后的简单代码如下:

首先为xfs类设计抽象产品类,

cbef093dcc044b2793832001e2365e43.pngclass fs

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprotected:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       fs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       virtual ~fs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png       //virtual const char* get_fstype() = 0;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

因为要把xfs作为具体的产品,所以,它需要从fs类派生。

cbef093dcc044b2793832001e2365e43.pngclass xfs : public fs

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       xfs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       void do_mount() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png              cout <

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

4a5daaec04350a363f186a4d2c5ed6ce.png       }

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

而mount类则作为xfs_mount类的抽象产品,这里就不用重复设计了。接下来,为设计抽象工厂类。

cbef093dcc044b2793832001e2365e43.pngclass fs_factory

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngprotected:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       fs_factory() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       virtual ~fs_factory() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       virtual const char* get_fstype() = 0;

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       virtual mount* getmount() = 0;

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

vfs类的改写后的例子如下:

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.pngclass vfs 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvfs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.pngvoid vfs_mount(const char* fstype) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       mount* mnt = search_factory(fstype);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       mnt->execute();

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

4a5daaec04350a363f186a4d2c5ed6ce.png}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png       mount* search_factory(const char* fstype);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

而具体的xfs工厂类,则是在内核启动时,由模块初始化程序来创建具体的实例。这个实例应该被记录在内核的一个工厂列表中,这样在VFS层根据要挂载文件系统的类型(fstype)来从这个列表中搜索该实例。

那么,xfs文件系统设计者应该编写的具体工厂如下:

cbef093dcc044b2793832001e2365e43.pngclass xfs_factory : fs_factory

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       xfs_factory() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png       mount* getmount() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png              return xfs_mount(new xfs());

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

4a5daaec04350a363f186a4d2c5ed6ce.png       }

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

到此为止,文件系统的mount操作的基本框架都搭好了,umount操作的设计跟这个也差不多。

设计模式在Linux文件系统中的简单实现(源代码实现1)

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png/**///

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png下面是他的全部实现代码:仅作为参考。

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#ifndef __KERNEL_H

cbef093dcc044b2793832001e2365e43.png#define __KERNEL_H

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#include 

cbef093dcc044b2793832001e2365e43.png#include 

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngusing namespace std;

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngclass mount;

cbef093dcc044b2793832001e2365e43.pngclass umount;

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngclass dev

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    dev(int major, int minor) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _major = major;

df37983f39daa189b8c814e01a6a9011.png        _minor = minor;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    int getMajor() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        return _major;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    int getMinor() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        return _minor;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    int _major;

df37983f39daa189b8c814e01a6a9011.png    int _minor;

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngclass fs

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprotected:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    fs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    virtual ~fs() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    virtual const char* get_fstype() = 0;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngclass fs_factory

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprotected:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    fs_factory() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    virtual ~fs_factory() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    virtual const char* get_fstype() = 0;

df37983f39daa189b8c814e01a6a9011.png    virtual mount* getmount(dev* device) = 0;

df37983f39daa189b8c814e01a6a9011.png    virtual umount* getumount(dev* device) = 0;

df37983f39daa189b8c814e01a6a9011.png    virtual bool lookup_dev(dev* device) = 0;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png/**//* ---------------- kernel code -------------------------- */

cbef093dcc044b2793832001e2365e43.pngclass kernel

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    list _fslist;

df37983f39daa189b8c814e01a6a9011.png    list _devlist;

df37983f39daa189b8c814e01a6a9011.png    const char* _parameter;    // boot parameter

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    kernel(const char* para) : _parameter(para) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        cout <

918e8df969f9f8c8d002f25cda86cade.png" <

df37983f39daa189b8c814e01a6a9011.png        cout <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void register_fs(fs_factory* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _fslist.push_back(filesystem);

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void register_dev(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _devlist.push_back(device);

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    fs_factory* get_fs(const char* fstype) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        list::iterator iter = _fslist.begin();

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        for (; iter != _fslist.end(); ++ iter) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            if (strcmp(fstype, (*iter)->get_fstype()) == 0)

df37983f39daa189b8c814e01a6a9011.png                return *iter;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        return 0;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    fs_factory* get_fs(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        list::iterator iter = _fslist.begin();

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        for (; iter != _fslist.end(); ++ iter) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            if ((*iter)->lookup_dev(device))

df37983f39daa189b8c814e01a6a9011.png                return *iter;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        return 0;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    ~kernel() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        //free all filesystem;

4a5daaec04350a363f186a4d2c5ed6ce.png    };

df37983f39daa189b8c814e01a6a9011.png    

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png#endif

cbef093dcc044b2793832001e2365e43.png

设计模式在Linux文件系统中的简单实现(源代码实现2)

cbef093dcc044b2793832001e2365e43.png#ifndef __XFS_H

cbef093dcc044b2793832001e2365e43.png#define __XFS_H

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#include 

cbef093dcc044b2793832001e2365e43.png#include "mount.h"

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngusing namespace std;

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png/**//* ----------------- real filesystem layer -------------------- */

cbef093dcc044b2793832001e2365e43.pngclass xfs : public fs

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    xfs(dev* device) : _fstype("xfs") 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _dev = device;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png        

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void do_mount() 

918e8df969f9f8c8d002f25cda86cade.png{        

df37983f39daa189b8c814e01a6a9011.png        cout <getMajor()

df37983f39daa189b8c814e01a6a9011.png            <getMinor() <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void do_umount() 

918e8df969f9f8c8d002f25cda86cade.png{        

df37983f39daa189b8c814e01a6a9011.png        cout <getMajor()

df37983f39daa189b8c814e01a6a9011.png            <getMinor() <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png        

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    const char* get_fstype() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        return _fstype;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    dev* get_dev() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        return _dev;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    const char* _fstype;

df37983f39daa189b8c814e01a6a9011.png    dev* _dev;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png// concrete factory for xfs

cbef093dcc044b2793832001e2365e43.pngclass xfs_factory : public fs_factory

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    xfs_factory() : _fstype("xfs") 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        cout <

918e8df969f9f8c8d002f25cda86cade.png                [OK]" <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png        

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    const char* get_fstype() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        return _fstype;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    bool lookup_dev(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        list::iterator iter = _xfslist.begin();

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        for (; iter != _xfslist.end(); ++ iter) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            // there, only compare dev's address because of simplying.

df37983f39daa189b8c814e01a6a9011.png            // future, need to override operator '==' function for dev class.

df37983f39daa189b8c814e01a6a9011.png            if ((*iter)->get_dev() == device)

df37983f39daa189b8c814e01a6a9011.png                return true;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        return false;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // instance xfs filesystem.

df37983f39daa189b8c814e01a6a9011.png    mount* getmount(dev* device);

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    umount* getumount(dev* device);

df37983f39daa189b8c814e01a6a9011.png

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    const char* _fstype;

df37983f39daa189b8c814e01a6a9011.png    list _xfslist;

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void add_fs(xfs* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _xfslist.push_back(filesystem);

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // lookup xfs filesystem on the device.

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    xfs* search_xfs(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        list::iterator iter = _xfslist.begin();

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        for (; iter != _xfslist.end(); ++ iter) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            // there, only compare dev's address because of simplying.

df37983f39daa189b8c814e01a6a9011.png            // future, need to override operator '==' function for dev class.

df37983f39daa189b8c814e01a6a9011.png            if ((*iter)->get_dev() == device)

df37983f39daa189b8c814e01a6a9011.png                return *iter;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        return 0;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png#endif

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png 

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#ifndef __MOUNT_H

cbef093dcc044b2793832001e2365e43.png#define __MOUNT_H

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#include "xfs.h"

cbef093dcc044b2793832001e2365e43.png    

cbef093dcc044b2793832001e2365e43.png// base class for command pattern

cbef093dcc044b2793832001e2365e43.pngclass mount

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprotected:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    mount() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.pngpublic:    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    virtual ~mount() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    virtual void execute() = 0;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png    

cbef093dcc044b2793832001e2365e43.pngclass xfs_mount : public mount

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    xfs_mount(xfs* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _xfs = filesystem;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void execute() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _xfs->do_mount();

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    xfs* _xfs;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngclass umount

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngprotected:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    umount() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.pngpublic:    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    virtual ~umount() 

918e8df969f9f8c8d002f25cda86cade.png{}

df37983f39daa189b8c814e01a6a9011.png    virtual void execute() = 0;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png    

cbef093dcc044b2793832001e2365e43.pngclass xfs_umount : public umount

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    xfs_umount(xfs* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _xfs = filesystem;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void execute() 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _xfs->do_umount();

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    xfs* _xfs;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.pngmount* xfs_factory::getmount(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png    xfs* fs = new xfs(device);

df37983f39daa189b8c814e01a6a9011.png    add_fs(fs);

df37983f39daa189b8c814e01a6a9011.png    return new xfs_mount(fs);

0ac3a2d53663ec01c7f7225264eeefae.png}

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.pngumount* xfs_factory::getumount(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png    return new xfs_umount(search_xfs(device));

0ac3a2d53663ec01c7f7225264eeefae.png}

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#endif

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png

设计模式在Linux文件系统中的简单实现(源代码实现3)

cbef093dcc044b2793832001e2365e43.png#include 

cbef093dcc044b2793832001e2365e43.png#include 

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.png#include "kernel.h"

cbef093dcc044b2793832001e2365e43.png#include "mount.h"

cbef093dcc044b2793832001e2365e43.png#include "xfs.h"

cbef093dcc044b2793832001e2365e43.png

cbef093dcc044b2793832001e2365e43.pngusing namespace std;

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png/**//* ----------------- vfs layer ------------------- */

cbef093dcc044b2793832001e2365e43.pngclass vfs

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.pngpublic:

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    vfs(kernel* knl) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _kernel = knl;

df37983f39daa189b8c814e01a6a9011.png        cout <

918e8df969f9f8c8d002f25cda86cade.png                    [OK]" <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    void register_fs(fs_factory* filesystem) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        _kernel->register_fs(filesystem);

df37983f39daa189b8c814e01a6a9011.png        cout <

918e8df969f9f8c8d002f25cda86cade.png                [OK]" <

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    bool do_mount(const char* fstype, dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        // command for real filesystem.

df37983f39daa189b8c814e01a6a9011.png        fs_factory* fs = _kernel->get_fs(fstype);        

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        if (!fs) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            cout <

df37983f39daa189b8c814e01a6a9011.png                <

df37983f39daa189b8c814e01a6a9011.png            return false;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        mount* mnt = fs->getmount(device);

df37983f39daa189b8c814e01a6a9011.png        mnt->execute();

df37983f39daa189b8c814e01a6a9011.png        delete mnt;

df37983f39daa189b8c814e01a6a9011.png        return true;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png    bool do_umount(dev* device) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png        //command for real filesystem.

df37983f39daa189b8c814e01a6a9011.png        fs_factory* fs = _kernel->get_fs(device);        

f70a0fde2b51b7dd92a70e712e540cf6.png

edb48e6f68462ea23d9a824f01de40c5.png        if (!fs) 

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png            cout <getMajor() <

df37983f39daa189b8c814e01a6a9011.png                device->getMinor() <

df37983f39daa189b8c814e01a6a9011.png            return false;

4a5daaec04350a363f186a4d2c5ed6ce.png        }

df37983f39daa189b8c814e01a6a9011.png        umount* mnt = fs->getumount(device);

df37983f39daa189b8c814e01a6a9011.png        mnt->execute();

df37983f39daa189b8c814e01a6a9011.png        delete mnt;

df37983f39daa189b8c814e01a6a9011.png        return true;

4a5daaec04350a363f186a4d2c5ed6ce.png    }

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.pngprivate:

df37983f39daa189b8c814e01a6a9011.png    kernel* _kernel;

df37983f39daa189b8c814e01a6a9011.png

0ac3a2d53663ec01c7f7225264eeefae.png};

cbef093dcc044b2793832001e2365e43.png

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png/**//* main */

cbef093dcc044b2793832001e2365e43.pngint main(int argc, char *argv[])

2f88ce130b654eb5dc6788e02dbcfc90.png

dbf989d57862681739b642d8621fe1f0.png

918e8df969f9f8c8d002f25cda86cade.png{

df37983f39daa189b8c814e01a6a9011.png    // kernel boot code

df37983f39daa189b8c814e01a6a9011.png    kernel* knl = new kernel("video=vesafb:ywrap,mtrr splash=silent vga=0x317");

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // create device

df37983f39daa189b8c814e01a6a9011.png    dev* dev1 = new dev(8, 1);

df37983f39daa189b8c814e01a6a9011.png    knl->register_dev(dev1);

df37983f39daa189b8c814e01a6a9011.png    dev* dev2 = new dev(8, 2);

df37983f39daa189b8c814e01a6a9011.png    knl->register_dev(dev2);

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // create vfs

df37983f39daa189b8c814e01a6a9011.png    vfs* filesystem = new vfs(knl);

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // register xfs filesystem

df37983f39daa189b8c814e01a6a9011.png    filesystem->register_fs(new xfs_factory());

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    // wait real filesystem is mounted

df37983f39daa189b8c814e01a6a9011.png    // 

918e8df969f9f8c8d002f25cda86cade.png 

918e8df969f9f8c8d002f25cda86cade.png.

df37983f39daa189b8c814e01a6a9011.png    filesystem->do_mount(argv[1], dev1);

df37983f39daa189b8c814e01a6a9011.png    

df37983f39daa189b8c814e01a6a9011.png    return 0;

0ac3a2d53663ec01c7f7225264eeefae.png}

cbef093dcc044b2793832001e2365e43.png

编译方法和执行结果:

lymons@d3 ~/kernel

$ g++ mount.cpp -o mount

lymons@d3 ~/kernel

$ ./mount.exe xfs

booting BASE kernel, please waiting ...

with video=vesafb:ywrap,mtrr splash=silent vga=0x317

create VFS layer ...                                    [OK]

create XFS filesystem  ...                              [OK]

register XFS filesystem  ...                            [OK]

mounted a XFS filesystem for device[8,1].

$ ./mount.exe cxfs

booting BASE kernel, please waiting ...

with video=vesafb:ywrap,mtrr splash=silent vga=0x317

create VFS layer ...                                    [OK]

create XFS filesystem  ...                              [OK]

register XFS filesystem  ...                            [OK]

ERR: kernel not supporting filesystem type "cxfs"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值