(莱昂氏unix源代码分析导读-43) 文件系统的mount

                         By cszhao1980

当一个设备被mount进系统,就会在“mount表”中占据一个表项,mount表的定义如下:

0272: struct mount

0273: {

0274:     int m_dev     /* device mounted */

0275:     int *m_bufp;   /* pointer to superblock */

0276:     int *m_inodp;  /* pointer to mounted on inode */

0277: } mount[NMOUNT];     

 

m_dev记录被mount设备的设备号;

m_bufp指向一个缓存,其内容是设备的“超级块”;

m_inodep指向所谓的“mount on inode,我们会在后面的讨论中对其进一步了解。

 

首先,我们来看一看root设备是怎样被mount进系统的。

首先,rootdev的定义如下:

4695: int rootdev {(0<<8)|0};

显然,其设备号为0,即我们的RK磁盘设备。

 

然后,在main()函数中调用iinit()函数——它负责把rootdev Load进系统:

1615:    iinit();                    

 

6922: iinit()

6923: {

6924:     register *cp, *bp;

6925:

6926:     (*bdevsw[rootdev.d_major].d_open)(rootdev, 1);

6927:     bp = bread(rootdev, 1);

6928:     cp = getblk(NODEV);

6929:     if(u.u_error)

6930:         panic("iinit");

6931:     bcopy(bp->b_addr, cp->b_addr, 256);

6932:     brelse(bp);

6933:     mount[0].m_bufp = cp;

6934:     mount[0].m_dev = rootdev;

6935:     cp = cp->b_addr;

6936:     cp->s_flock = 0;

6937:     cp->s_ilock = 0;

6938:     cp->s_ronly = 0;

6939:     time[0] = cp->s_time[0];

6940:     time[1] = cp->s_time[1];

6941: }

 

如果您对上一章的内容比较清楚的话,iinit()函数就显得很简单了:

(1)         利用块设备表调用rootdevRK磁盘)的d_open函数,如果您还记得的话,

                   该函数是个空函数,也就是说对RK磁盘来说,无需进行open操作,就直接可用;

(2)         然后,调用bread()函数将rootdev#1块(即超级块)读入缓存;

(3)         接着它又调用getblk(NODEV)申请了一个“空闲设备”缓存——该缓存没有与任何

                    实际设备相关连。接着将超级块的内容通过bcopy函数,拷贝到给缓存中。

(4)         调用brelse函数,将rootdev缓存送还AV队列;

(5)         mount表的#0表项分配给rootdev,其m_dev设置为rootdev0),而m_bufp指向装

                   有超级块内容的“空闲设备”缓存;

(6)         接下来的操作就跟超级块的内容有关了,我们接下来就看一下超级块。

 

超级块的内容如下所示:

5561: struct filsys

5562: {

5563:     int s_isize;      /* size in blocks of I list */

5564:     int s_fsize;      /* size in blocks of entire volume */

5565:     int s_nfree;      /* number of in core free blocks (0-100) */

5566:

5567:     int s_free[100];   /* in core free blocks */

5568:     int s_ninode;     /* number of in core I nodes (0-100) */

5569:     int s_inode[100];  /* in core free I nodes */

5570:     char s_flock;     /* lock during free list manipulation */

5571:     char s_ilock;     /* lock during I list manipulation */

5572:     char s_fmod;     /* super block modified flag */

5573:     char s_ronly;     /* mounted read-only flag */

5574:     int s_time[2];     /* current date of last update */

5575:     int pad[50];

5576: };

内容不少,我们先了解其中几项:

(1)         s_isize:即有多少个块是用来存放inde列表的;

(2)         s_fsize:整个文件系统共有多少个块;

(3)         s_ninode:读入内存的inode项数;

(4)         s_inode[100]:存放读入内存的indode项;

 

在上述操作中,并没有设置mount数组项中所谓的“mount oninode指针——这时因为rootdev

mount是很“自然”的事,它的文件系统根目录,直接变成了系统根目录,没有mount点之说。

 

下面我们来看smount ()函数——它用来处理mount sys call,即通过该函数可以将一个设备mount到系统中。

mount的过程和上述过程类似,莱昂解释的也比较清晰,我只简单说几点。

 

1. 参数传递

smount有三个参数,都通过.u_arg[]数组传递:

(1)         u_arg[0] (u.dirp) ——指向一个Path name字符串,该Path name的文件inode-i_dev为要mount

                  设备的设备号;smount会调用getmdev()函数来得到设备id

                 (该文件应该为一设备描述文件,也许就是“特殊块设备”(IFBLK)文件);

(2)         u_arg[1] ——指向“要mount到的”目录的Path name

(3)         u_arg[2] —— read only flag

 

2.  mount

mount到的目录被称为mount点,该目录的inode会设置IMOUNT标志。

 

3.  IFBLK/ IFCHR分别为特殊块设备、特殊字符设备标志;

 

很自然的,我们接下来看一下sumount函数,即unmount sys call的处理函数。

我们基本上可以将其理解为smount的“反”函数,即:

(1)         将该设备从系统mount表中删除;

(2)         mount点的IMOUNT标志清除;

(3)         释放该文件系统的超级块。

 

除此之外,还需要注意两点:

(1)         unmount设备时,会Loop系统的inode数组,如果数组项中有该设备上的文件

                 (即该文件处理active状态),则禁止unmount设备;

(2)         在所有操作之前,调用update()进行了文件系统更新。

 

update7201)执行三种更新:

(1)         Loop mount表,将每个文件系统的超级块(内存中的)的内容写回磁盘;

(2)         Loop inode数组,将inode写回磁盘;

(3)         调用bflush,将“延迟写”块写入磁盘。

 

 

博客地址:http://blog.csdn.net/cszhao1980

博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值