程序14-20 linux/include/linux/fs.h


  1 /*

  2  * This file has definitions for some important file table

  3  * structures etc.

  4  */

    /*

     * 本文件含有某些重要文件表结构的定义等。

     */

  5

  6 #ifndef _FS_H

  7 #define _FS_H

  8

  9 #include <sys/types.h>    // 类型头文件。定义了基本的系统数据类型。

 10

 11 /* devices are as follows: (same as minix, so we can use the minix

 12  * file system. These are major numbers.)

 13  *

 14  * 0 - unused (nodev)

 15  * 1 - /dev/mem

 16  * 2 - /dev/fd

 17  * 3 - /dev/hd

 18  * 4 - /dev/ttyx

 19  * 5 - /dev/tty

 20  * 6 - /dev/lp

 21  * 7 - unnamed pipes

 22  */

    /*

     * 系统所含的设备如下:(与minix系统的一样,所以我们可以使用minix

     * 文件系统。以下这些是主设备号。)

     *

     * 0 - 没有用到(nodev

     * 1 - /dev/mem         内存设备。

     * 2 - /dev/fd          软盘设备。

     * 3 - /dev/hd          硬盘设备。

     * 4 - /dev/ttyx        tty串行终端设备。

     * 5 - /dev/tty         tty终端设备。

     * 6 - /dev/lp          打印设备。

     * 7 - unnamed pipes    没有命名的管道。

     */

 23

 24 #define IS_SEEKABLE(x) ((x)>=1 && (x)<=3)      // 判断设备是否是可以寻找定位的。

 25

 26 #define READ 0

 27 #define WRITE 1

 28 #define READA 2         /* read-ahead - don't pause */

 29 #define WRITEA 3        /* "write-ahead" - silly, but somewhat useful */

 30

 31 void buffer_init(long buffer_end);              // 高速缓冲区初始化函数。

 32

 33 #define MAJOR(a) (((unsigned)(a))>>8)           // 取高字节(主设备号)。

 34 #define MINOR(a) ((a)&0xff)                     // 取低字节(次设备号)。

 35

 36 #define NAME_LEN 14                             // 名字长度值。

 37 #define ROOT_INO 1                              // i节点。

 38

 39 #define I_MAP_SLOTS 8                           // i节点位图槽数。

 40 #define Z_MAP_SLOTS 8                           // 逻辑块(区段块)位图槽数。

 41 #define SUPER_MAGIC 0x137F                      // 文件系统魔数。

 42

 43 #define NR_OPEN 20                              // 进程最多打开文件数。

 44 #define NR_INODE 32                             // 系统同时最多使用I节点个数。

 45 #define NR_FILE 64                              // 系统最多文件个数(文件数组项数)。

 46 #define NR_SUPER 8                              // 系统所含超级块个数(超级块数组项数)。

 47 #define NR_HASH 307                             // 缓冲区Hash表数组项数值。

 48 #define NR_BUFFERS nr_buffers                   // 系统所含缓冲块个数。初始化后不再改变。

 49 #define BLOCK_SIZE 1024                         // 数据块长度(字节值)。

 50 #define BLOCK_SIZE_BITS 10                      // 数据块长度所占比特位数。

 51 #ifndef NULL

 52 #define NULL ((void *) 0)

 53 #endif

 54

    // 每个逻辑块可存放的i节点数。

 55 #define INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct d_inode)))

    // 每个逻辑块可存放的目录项数。

 56 #define DIR_ENTRIES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct dir_entry)))

 57

    // 管道头、管道尾、管道大小、管道空?、管道满?、管道头指针递增。

 58 #define PIPE_READ_WAIT(inode) ((inode).i_wait)

 59 #define PIPE_WRITE_WAIT(inode) ((inode).i_wait2)

 60 #define PIPE_HEAD(inode) ((inode).i_zone[0])

 61 #define PIPE_TAIL(inode) ((inode).i_zone[1])

 62 #define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))

 63 #define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode))

 64 #define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1))

 65

 66 #define NIL_FILP        ((struct file *)0)   // 空文件结构指针。

 67 #define SEL_IN          1

 68 #define SEL_OUT         2

 69 #define SEL_EX          4

 70

 71 typedef char buffer_block[BLOCK_SIZE];       // 块缓冲区。

 72

    // 缓冲块头数据结构。(极为重要!!!)

    // 在程序中常用bh来表示buffer_head类型的缩写。

 73 struct buffer_head {

 74         char * b_data;                  /* pointer to data block (1024 bytes) */ //指针。

 75         unsigned long b_blocknr;        /* block number */       // 块号。

 76         unsigned short b_dev;           /* device (0 = free) */  // 数据源的设备号。

 77         unsigned char b_uptodate;       // 更新标志:表示数据是否已更新。

 78         unsigned char b_dirt;           /* 0-clean,1-dirty */ //修改标志:0未修改,1已修改.

 79         unsigned char b_count;          /* users using this block */   // 使用的用户数。

 80         unsigned char b_lock;           /* 0 - ok, 1 -locked */  // 缓冲区是否被锁定。

 81         struct task_struct * b_wait;    // 指向等待该缓冲区解锁的任务。

 82         struct buffer_head * b_prev;    // hash队列上前一块(这四个指针用于缓冲区的管理)。

 83         struct buffer_head * b_next;    // hash队列上下一块。

 84         struct buffer_head * b_prev_free;   // 空闲表上前一块。

 85         struct buffer_head * b_next_free;   // 空闲表上下一块。

 86 };

 87

    // 磁盘上的索引节点(i节点)数据结构。

 88 struct d_inode {

 89         unsigned short i_mode;        // 文件类型和属性(rwx)

 90         unsigned short i_uid;         // 用户id(文件拥有者标识符)。

 91         unsigned long i_size;         // 文件大小(字节数)。

 92         unsigned long i_time;         // 修改时间(自1970.1.1:0算起,秒)。

 93         unsigned char i_gid;          // id(文件拥有者所在的组)

 94         unsigned char i_nlinks;       // 链接数(多少个文件目录项指向该i节点)。

 95         unsigned short i_zone[9];     // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。

                                          // zone是区的意思,可译成区段,或逻辑块。

 96 };

 97

    // 这是在内存中的i节点结构。前7项与d_inode完全一样。

 98 struct m_inode {

 99         unsigned short i_mode;        // 文件类型和属性(rwx)

100         unsigned short i_uid;         // 用户id(文件拥有者标识符)。

101         unsigned long i_size;         // 文件大小(字节数)。

102         unsigned long i_mtime;        // 修改时间(自1970.1.1:0算起,秒)。

103         unsigned char i_gid;          // id(文件拥有者所在的组)

104         unsigned char i_nlinks;       // 文件目录项链接数。

105         unsigned short i_zone[9];     // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。

106 /* these are in memory also */

107         struct task_struct * i_wait;  // 等待该i节点的进程。

108         struct task_struct * i_wait2;   /* for pipes */

109         unsigned long i_atime;        // 最后访问时间。

110         unsigned long i_ctime;        // i节点自身修改时间。

111         unsigned short i_dev;         // i节点所在的设备号。

112         unsigned short i_num;         // i节点号。

113         unsigned short i_count;       // i节点被使用的次数,0表示该i节点空闲。

114         unsigned char i_lock;         // 锁定标志。

115         unsigned char i_dirt;         // 已修改()标志。

116         unsigned char i_pipe;         // 管道标志。

117         unsigned char i_mount;        // 安装标志。

118         unsigned char i_seek;         // 搜寻标志(lseek)

119         unsigned char i_update;       // 更新标志。

120 };

121

    // 文件结构(用于在文件句柄与i节点之间建立关系)

122 struct file {

123         unsigned short f_mode;        // 文件操作模式(RW位)

124         unsigned short f_flags;       // 文件打开和控制的标志。

125         unsigned short f_count;       // 对应文件引用计数值。

126         struct m_inode * f_inode;     // 指向对应i节点。

127         off_t f_pos;                  // 文件位置(读写偏移值)。

128 };

129

    // 内存中磁盘超级块结构。

130 struct super_block {

131         unsigned short s_ninodes;       // 节点数。

132         unsigned short s_nzones;        // 逻辑块数。

133         unsigned short s_imap_blocks;   // i节点位图所占用的数据块数。

134         unsigned short s_zmap_blocks;   // 逻辑块位图所占用的数据块数。

135         unsigned short s_firstdatazone; // 第一个数据逻辑块号。

136         unsigned short s_log_zone_size; // log(数据块数/逻辑块)。(以2为底)。

137         unsigned long s_max_size;       // 文件最大长度。

138         unsigned short s_magic;         // 文件系统魔数。

139 /* These are only in memory */

140         struct buffer_head * s_imap[8]; // i节点位图缓冲块指针数组(占用8块,可表示64M)

141         struct buffer_head * s_zmap[8]; // 逻辑块位图缓冲块指针数组(占用8块)。

142         unsigned short s_dev;           // 超级块所在的设备号。

143         struct m_inode * s_isup;        // 被安装的文件系统根目录的i节点。(isup-super i)

144         struct m_inode * s_imount;      // 被安装到的i节点。

145         unsigned long s_time;           // 修改时间。

146         struct task_struct * s_wait;    // 等待该超级块的进程。

147         unsigned char s_lock;           // 被锁定标志。

148         unsigned char s_rd_only;        // 只读标志。

149         unsigned char s_dirt;           // 已修改()标志。

150 };

151

    // 磁盘上超级块结构。上面125-132行完全一样。

152 struct d_super_block {

153         unsigned short s_ninodes;       // 节点数。

154         unsigned short s_nzones;        // 逻辑块数。

155         unsigned short s_imap_blocks;   // i节点位图所占用的数据块数。

156         unsigned short s_zmap_blocks;   // 逻辑块位图所占用的数据块数。

157         unsigned short s_firstdatazone; // 第一个数据逻辑块。

158         unsigned short s_log_zone_size; // log(数据块数/逻辑块)。(以2为底)。

159         unsigned long s_max_size;       // 文件最大长度。

160         unsigned short s_magic;         // 文件系统魔数。

161 };

162

    // 文件目录项结构。

163 struct dir_entry {

164         unsigned short inode;           // i节点号。

165         char name[NAME_LEN];            // 文件名,长度NAME_LEN=14

166 };

167

168 extern struct m_inode inode_table[NR_INODE];     // 定义i节点表数组(32项)。

169 extern struct file file_table[NR_FILE];          // 文件表数组(64项)。

170 extern struct super_block super_block[NR_SUPER]; // 超级块数组(8项)。

171 extern struct buffer_head * start_buffer;        // 缓冲区起始内存位置。

172 extern int nr_buffers;                           // 缓冲块数。

173

    //// 磁盘操作函数原型。

    // 检测驱动器中软盘是否改变。

174 extern void check_disk_change(int dev);

    // 检测指定软驱中软盘更换情况。如果软盘更换了则返回1,否则返回0

175 extern int floppy_change(unsigned int nr);

    // 设置启动指定驱动器所需等待的时间(设置等待定时器)。

176 extern int ticks_to_floppy_on(unsigned int dev);

    // 启动指定驱动器。

177 extern void floppy_on(unsigned int dev);

    // 关闭指定的软盘驱动器。

178 extern void floppy_off(unsigned int dev);

 

    //// 以下是文件系统操作管理用的函数原型。

    // i节点指定的文件截为0

179 extern void truncate(struct m_inode * inode);

    // 刷新i节点信息。

180 extern void sync_inodes(void);

    // 等待指定的i节点。

181 extern void wait_on(struct m_inode * inode);

    // 逻辑块(区段,磁盘块)位图操作。取数据块block在设备上对应的逻辑块号。

182 extern int bmap(struct m_inode * inode,int block);

    // 创建数据块block在设备上对应的逻辑块,并返回在设备上的逻辑块号。

183 extern int create_block(struct m_inode * inode,int block);

    // 获取指定路径名的i节点号。

184 extern struct m_inode * namei(const char * pathname);

    // 取指定路径名的i节点,不跟随符号链接。

185 extern struct m_inode * lnamei(const char * pathname);

    // 根据路径名为打开文件操作作准备。

186 extern int open_namei(const char * pathname, int flag, int mode,

187         struct m_inode ** res_inode);

    // 释放一个i节点(回写入设备)

188 extern void iput(struct m_inode * inode);

    // 从设备读取指定节点号的一个i节点。

189 extern struct m_inode * iget(int dev,int nr);

    // i节点表(inode_table)中获取一个空闲i节点项。

190 extern struct m_inode * get_empty_inode(void);

    // 获取(申请一)管道节点。返回为i节点指针(如果是NULL则失败)。

191 extern struct m_inode * get_pipe_inode(void);

    // 在哈希表中查找指定的数据块。返回找到块的缓冲头指针。

192 extern struct buffer_head * get_hash_table(int dev, int block);

    // 从设备读取指定块(首先会在hash表中查找)。

193 extern struct buffer_head * getblk(int dev, int block);

    // /写数据块。

194 extern void ll_rw_block(int rw, struct buffer_head * bh);

    // /写数据页面,即每次4块数据块。

195 extern void ll_rw_page(int rw, int dev, int nr, char * buffer);

    // 释放指定缓冲块。

196 extern void brelse(struct buffer_head * buf);

    // 读取指定的数据块。

197 extern struct buffer_head * bread(int dev,int block);

    // 4块缓冲区到指定地址的内存中。

198 extern void bread_page(unsigned long addr,int dev,int b[4]);

    // 读取头一个指定的数据块,并标记后续将要读的块。

199 extern struct buffer_head * breada(int dev,int block,...);

    // 向设备dev申请一个磁盘块(区段,逻辑块)。返回逻辑块号

200 extern int new_block(int dev);

    // 释放设备数据区中的逻辑块(区段,磁盘块)block。复位指定逻辑块block的逻辑块位图比特位。

201 extern void free_block(int dev, int block);

    // 为设备dev建立一个新i节点,返回i节点号。

202 extern struct m_inode * new_inode(int dev);

    // 释放一个i节点(删除文件时)。

203 extern void free_inode(struct m_inode * inode);

    // 刷新指定设备缓冲区。

204 extern int sync_dev(int dev);

    // 读取指定设备的超级块。

205 extern struct super_block * get_super(int dev);

206 extern int ROOT_DEV;

207

    // 安装根文件系统。

208 extern void mount_root(void);

209

210 #endif

211