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

📄 super.c.bak

📁 一份精简的linux内核源代码
💻 BAK
字号:
/* *  linux/fs/super.c * *  (C) 1991  Linus Torvalds *//* * super.c contains code to handle the super-block tables. */#include <linux/config.h>#include <linux/sched.h>#include <linux/kernel.h>#include <asm/system.h>#include <errno.h>#include <sys/stat.h>int sync_dev(int dev);void wait_for_keypress(void);/* set_bit uses setb, as gas doesn't recognize setc */#define set_bit(bitnr,addr) ({ \  /* bt把指定位的值放入标志cf中,setb根据cf的值设置al*/register int __res __asm__("ax"); \__asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \__res; })struct super_block super_block[NR_SUPER]; /*超级块数组*//* this is initialized in init/main.c */int ROOT_DEV = 0;/* 根文件系统设备号 */static void lock_super(struct super_block * sb)/*加锁*/{	cli();	while (sb->s_lock)		sleep_on(&(sb->s_wait));	sb->s_lock = 1;	sti();}static void free_super(struct super_block * sb)/*解锁*/{	cli();	sb->s_lock = 0;	wake_up(&(sb->s_wait));	sti();}static void wait_on_super(struct super_block * sb)/*挂起*/{	cli();	while (sb->s_lock)		sleep_on(&(sb->s_wait));	sti();}struct super_block * get_super(int dev) /* 取指定设备的超级块(自超级块表中) */{	struct super_block * s;	if (!dev)		return NULL;	s = 0+super_block;	while (s < NR_SUPER+super_block)		if (s->s_dev == dev) {			wait_on_super(s);			if (s->s_dev == dev)				return s;			s = 0+super_block;		} else			s++;	return NULL;}void put_super(int dev) /* 释放指定设备的超级块(若该超级块对应着根文件系统或其某个i节点上装有其它文件系统,则不能释放) */{                       /* 置s_dev为0即释放内存超级块数组中的超级块,并释放位图所在缓冲块*/	struct super_block * sb;  /*超级块不用回写设备??*/	struct m_inode * inode;	int i;	if (dev == ROOT_DEV) {		printk("root diskette changed: prepare for armageddon\n\r");		return;	}	if (!(sb = get_super(dev)))		return;	if (sb->s_imount) {/* 若指定超级块的根i节点未处理过,则警告并退出 */		printk("Mounted disk changed - tssk, tssk\n\r");		return;	}	lock_super(sb);	sb->s_dev = 0; /* 置超级块空闲 */	for(i=0;i<I_MAP_SLOTS;i++)		brelse(sb->s_imap[i]);	for(i=0;i<Z_MAP_SLOTS;i++)		brelse(sb->s_zmap[i]);	free_super(sb);	return;}static struct super_block * read_super(int dev)/* 从设备上读入超级块置内存超级块数组中,并读入相应的位图块存于缓冲区中 */{	struct super_block * s;	struct buffer_head * bh;	int i,block;	if (!dev)		return NULL;	check_disk_change(dev);/*软盘 */	if (s = get_super(dev))		return s;	for (s = 0+super_block ;; s++) {		if (s >= NR_SUPER+super_block)			return NULL;		if (!s->s_dev)			break;	}	s->s_dev = dev;	s->s_isup = NULL;	s->s_imount = NULL;	s->s_time = 0;	s->s_rd_only = 0;	s->s_dirt = 0;	lock_super(s);	if (!(bh = bread(dev,1))) {		s->s_dev=0;		free_super(s);		return NULL;	}	*((struct d_super_block *) s) =		*((struct d_super_block *) bh->b_data);	brelse(bh);	if (s->s_magic != SUPER_MAGIC) {		s->s_dev = 0;		free_super(s);		return NULL;	}	for (i=0;i<I_MAP_SLOTS;i++)		s->s_imap[i] = NULL;	for (i=0;i<Z_MAP_SLOTS;i++)		s->s_zmap[i] = NULL;	block=2;	for (i=0 ; i < s->s_imap_blocks ; i++)/* 读入位图 */		if (s->s_imap[i]=bread(dev,block))			block++;		else			break;	for (i=0 ; i < s->s_zmap_blocks ; i++)		if (s->s_zmap[i]=bread(dev,block))			block++;		else			break;	if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {		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;	}	s->s_imap[0]->b_data[0] |= 1;/* 位图中第一位有特殊用途,置1 */	s->s_zmap[0]->b_data[0] |= 1;	free_super(s);	return s;}int sys_umount(char * dev_name)/* 卸载文件系统(成功返回0,出错返回出错码) ,dev_name为文件系统所在设备的设备名*/{	struct m_inode * inode;	struct super_block * sb;	int dev;	if (!(inode=namei(dev_name)))/* 根据设备文件名找到对应的i节点(即设备) */		return -ENOENT;	dev = inode->i_zone[0];/* 设备文件的设备号保存在其i节点的i_zone[0]中 */	if (!S_ISBLK(inode->i_mode)) {/*文件系统需存放在块设备上,否则返回错 */		iput(inode);		return -ENOTBLK;	}	iput(inode);	if (dev==ROOT_DEV)		return -EBUSY;	if (!(sb=get_super(dev)) || !(sb->s_imount))/* 未找到指定设备的超级块,或已找到但文件系统未安装 */		return -ENOENT;	if (!sb->s_imount->i_mount)/* 若超级块所指明的被安装到的i节点并没有置位其安装标志 */		printk("Mounted inode has i_mount=0\n");	for (inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++)/* 确保没有其它进程在使用该设备中的文件 */		if (inode->i_dev==dev && inode->i_count)				return -EBUSY;	sb->s_imount->i_mount=0; /*开始卸载文件系统 */	iput(sb->s_imount);/*释放被安装到的i节点 */	sb->s_imount = NULL;	iput(sb->s_isup);/* 释放根i节点 */	sb->s_isup = NULL;	put_super(dev);	sync_dev(dev);	return 0;}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;	if (!(dev_i=namei(dev_name)))/*由设备文件名得到设备文件i节点*/		return -ENOENT;	dev = dev_i->i_zone[0];/*获得设备号*/	if (!S_ISBLK(dev_i->i_mode)) {/*若不是块设备则出错退出(文件系统必须装在块设备上)*/		iput(dev_i);		return -EPERM;	}	iput(dev_i);	if (!(dir_i=namei(dir_name)))/*由目录名找到指定的i节点*/		return -ENOENT;	if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) {/*若目录i节点的引用次数>1或它为根文件系统的根目录则出错返回*/		iput(dir_i);		return -EBUSY;	}	if (!S_ISDIR(dir_i->i_mode)) {/*若非目录i节点则出错返回*/		iput(dir_i);		return -EPERM;	}	if (!(sb=read_super(dev))) {/*读入超级块*/		iput(dir_i);		return -EBUSY;	}	if (sb->s_imount) {/*该文件系统已安装到某个目录下,则出错退出*/		iput(dir_i);		return -EBUSY;	}	if (dir_i->i_mount) {/*若安装到的目录已安装了别的文件系统,则出错退出*/		iput(dir_i);		return -EPERM;	}	sb->s_imount=dir_i; /*设给文件系统的安装到目录*/	dir_i->i_mount=1;	dir_i->i_dirt=1;		/* NOTE! we don't iput(dir_i) */	return 0;			/* we do that in umount */}void mount_root(void)/*安装根文件系统(p463)*/{	int i,free;	struct super_block * p;	struct m_inode * mi;	if (32 != sizeof (struct d_inode))		panic("bad i-node size");	for(i=0;i<NR_FILE;i++)  /*初始化文件表(共64项,每一项代表一个文件),将所有文件项的引用次数置0*/		file_table[i].f_count=0;	if (MAJOR(ROOT_DEV) == 2) {/*若根文件系统在软盘上,则提示插入软盘*/		printk("Insert root floppy and press ENTER");		wait_for_keypress();	}	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");	if (!(mi=iget(ROOT_DEV,ROOT_INO)))/*读入根目录的i节点(inode.c)*/		panic("Unable to read root i-node");	mi->i_count += 3 ;	/*引用计数置为4*//* NOTE! it is logically used 4 times, not 1 */	p->s_isup = p->s_imount = mi; /*置超级块的被安装文件系统i节点和被安装到i节点字段设为该i节点*/	current->pwd = mi;/*置当前进程的工作目录和根目录为该i节点*/	current->root = mi;	free=0;	i=p->s_nzones;/*计算该文件系统所对应的块设备中的资源进行统计(计算空闲的数据块和i节点数)*/	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);	free=0;	i=p->s_ninodes+1;	while (-- i >= 0)		if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))			free++;	printk("%d/%d free inodes\n\r",free,p->s_ninodes);}

⌨️ 快捷键说明

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