⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 super.c

📁 linux 0.11 内核源码。kernel-011-src.tar
💻 C
📖 第 1 页 / 共 2 页
字号:
for (i=0 ; i < s->s_imap_blocks ; i++)if (s->s_imap[i]=bread(dev,block))block++;elsebreak;for (i=0 ; i < s->s_zmap_blocks ; i++)if (s->s_zmap[i]=bread(dev,block))block++;elsebreak;// 如果读出的位图逻辑块数不等于位图应该占有的逻辑块数,说明文件系统位图信息有问题,超级块// 初始化失败。因此只能释放前面申请的所有资源,返回空指针并退出。if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {// 释放i 节点位图和逻辑块位图占用的高速缓冲区。for(i=0;i<I_MAP_SLOTS;i++)brelse(s->s_imap[i]);for(i=0;i<Z_MAP_SLOTS;i++)brelse(s->s_zmap[i]);//释放上面选定的超级块数组中的项,并解锁该超级块项,返回空指针退出。s->s_dev=0;free_super(s);return NULL;}// 否则一切成功。对于申请空闲i 节点的函数来讲,如果设备上所有的i 节点已经全被使用,则查找// 函数会返回0 值。因此0 号i 节点是不能用的,所以这里将位图中的最低位设置为1,以防止文件// 系统分配0 号i 节点。同样的道理,也将逻辑块位图的最低位设置为1。s->s_imap[0]->b_data[0] |= 1;s->s_zmap[0]->b_data[0] |= 1;// 解锁该超级块,并返回超级块指针。free_super(s);return s;}//// 卸载文件系统的系统调用函数。// 参数dev_name 是设备文件名。int sys_umount(char * dev_name){struct m_inode * inode;struct super_block * sb;int dev;// 首先根据设备文件名找到对应的i 节点,并取其中的设备号。if (!(inode=namei(dev_name)))return -ENOENT;dev = inode->i_zone[0];// 如果不是块设备文件,则释放刚申请的i 节点dev_i,返回出错码。if (!S_ISBLK(inode->i_mode)) {iput(inode);return -ENOTBLK;}// 释放设备文件名的i 节点。iput(inode);// 如果设备是根文件系统,则不能被卸载,返回出错号。if (dev==ROOT_DEV)return -EBUSY;// 如果取设备的超级块失败,或者该设备文件系统没有安装过,则返回出错码。if (!(sb=get_super(dev)) || !(sb->s_imount))return -ENOENT;// 如果超级块所指明的被安装到的i 节点没有置位其安装标志,则显示警告信息。if (!sb->s_imount->i_mount)printk( "Mounted inode has i_mount=0\n");// 查找i 节点表,看是否有进程在使用该设备上的文件,如果有则返回忙出错码。for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)if (inode->i_dev==dev && inode->i_count)return -EBUSY;// 复位被安装到的i 节点的安装标志,释放该i 节点。sb->s_imount->i_mount=0;iput(sb->s_imount);// 置超级块中被安装i 节点字段为空,并释放设备文件系统的根i 节点,置超级块中被安装系统// 根i 节点指针为空。sb->s_imount = NULL;iput(sb->s_isup);sb->s_isup = NULL;// 释放该设备的超级块以及位图占用的缓冲块,并对该设备执行高速缓冲与设备上数据的同步操作。put_super(dev);sync_dev(dev);return 0;}//// 安装文件系统调用函数。// 参数dev_name 是设备文件名,dir_name 是安装到的目录名,rw_flag 被安装文件的读写标志。// 将被加载的地方必须是一个目录名,并且对应的i 节点没有被其它程序占用。int sys_mount(char * dev_name, char * dir_name, int rw_flag){struct m_inode * dev_i, * dir_i;struct super_block * sb;int dev;// 首先根据设备文件名找到对应的i 节点,并取其中的设备号。// 对于块特殊设备文件,设备号在i 节点的i_zone[0]中。if (!(dev_i=namei(dev_name)))return -ENOENT;dev = dev_i->i_zone[0];// 如果不是块设备文件,则释放刚取得的i 节点dev_i,返回出错码。if (!S_ISBLK(dev_i->i_mode)) {iput(dev_i);return -EPERM;}// 释放该设备文件的i 节点dev_i。iput(dev_i);// 根据给定的目录文件名找到对应的i 节点dir_i。if (!(dir_i=namei(dir_name)))return -ENOENT;// 如果该i 节点的引用计数不为1(仅在这里引用),或者该i 节点的节点号是根文件系统的节点// 号1,则释放该i 节点,返回出错码。if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) {iput(dir_i);return -EBUSY;}// 如果该节点不是一个目录文件节点,则也释放该i 节点,返回出错码。if (!S_ISDIR(dir_i->i_mode)) {iput(dir_i);return -EPERM;}// 读取将安装文件系统的超级块,如果失败则也释放该i 节点,返回出错码。if (!(sb=read_super(dev))) {iput(dir_i);return -EBUSY;}// 如果将要被安装的文件系统已经安装在其它地方,则释放该i 节点,返回出错码。if (sb->s_imount) {iput(dir_i);return -EBUSY;}// 如果将要安装到的i 节点已经安装了文件系统(安装标志已经置位),则释放该i 节点,返回出错码。if (dir_i->i_mount) {iput(dir_i);return -EPERM;}// 被安装文件系统超级块的“被安装到i 节点”字段指向安装到的目录名的i 节点。sb->s_imount=dir_i;// 设置安装位置i 节点的安装标志和节点已修改标志。/* 注意!这里没有iput(dir_i) */dir_i->i_mount=1; /* 这将在umount 内操作 */dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */return 0; /* we do that in umount */}//// 安装根文件系统。// 该函数是在系统开机初始化设置时(sys_setup())调用的。( kernel/blk_drv/hd.c, 157 )void mount_root(void){int i,free;struct super_block * p;struct m_inode * mi;// 如果磁盘i 节点结构不是32 个字节,则出错,死机。该判断是用于防止修改源代码时的不一致性。if (32 != sizeof (struct d_inode))panic( "bad i-node size");// 初始化文件表数组(共64 项,也即系统同时只能打开64 个文件),将所有文件结构中的引用计数// 设置为0。[??为什么放在这里初始化?]for(i=0;i<NR_FILE;i++)file_table[i].f_count=0;// 如果根文件系统所在设备是软盘的话,就提示“插入根文件系统盘,并按回车键”,并等待按键。if (MAJOR(ROOT_DEV) == 2) {printk( "Insert root floppy and press ENTER");wait_for_keypress();}// 初始化超级块数组(共8 项)。for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {p->s_dev = 0;p->s_lock = 0;p->s_wait = NULL;}// 如果读根设备上超级块失败,则显示信息,并死机。if (!(p=read_super(ROOT_DEV)))panic( "Unable to mount root");//从设备上读取文件系统的根i 节点(1),如果失败则显示出错信息,死机。if (!(mi=iget(ROOT_DEV,ROOT_INO)))panic( "Unable to read root i-node");// 该i 节点引用次数递增3 次。因为下面266-268 行上也引用了该i 节点。mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 *//* 注意!从逻辑上讲,它已被引用了4 次,而不是1 次 */// 置该超级块的被安装文件系统i 节点和被安装到的i 节点为该i 节点。p->s_isup = p->s_imount = mi;// 设置当前进程的当前工作目录和根目录i 节点。此时当前进程是1 号进程。current->pwd = mi;current->root = mi;// 统计该设备上空闲块数。首先令i 等于超级块中表明的设备逻辑块总数。free=0;i=p->s_nzones;// 然后根据逻辑块位图中相应比特位的占用情况统计出空闲块数。这里宏函数set_bit()只是在测试// 比特位,而非设置比特位。"i&8191"用于取得i 节点号在当前块中的偏移值。"i>>13"是将i 除以// 8192,也即除一个磁盘块包含的比特位数。while (-- i >= 0)if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))free++;// 显示设备上空闲逻辑块数/逻辑块总数。printk( "%d/%d free blocks\n\r",free,p->s_nzones);// 统计设备上空闲i 节点数。首先令i 等于超级块中表明的设备上i 节点总数+1。加1 是将0 节点// 也统计进去。free=0;i=p->s_ninodes+1;// 然后根据i 节点位图中相应比特位的占用情况计算出空闲i 节点数。while (-- i >= 0)if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))free++;// 显示设备上可用的空闲i 节点数/i 节点总数。printk( "%d/%d free inodes\n\r",free,p->s_ninodes);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -