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

📄 bitmap.c

📁 一份精简的linux内核源代码
💻 C
字号:
/* *  linux/fs/bitmap.c * *  (C) 1991  Linus Torvalds *//* bitmap.c contains the code that handles the inode and block bitmaps */#include <string.h>#include <linux/sched.h>#include <linux/kernel.h>#define clear_block(addr) \ /* 清除块中内容 */__asm__("cld\n\t" \	"rep\n\t" \	"stosl" \	::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")#define set_bit(nr,addr) ({\ /* 把addr+nr处的bit位置位,并返回该值 */register int res __asm__("ax"); \__asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \res;})#define clear_bit(nr,addr) ({\ /* 把addr+nr处的bit位复位,并返回该值的反 */register int res __asm__("ax"); \__asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \res;})#define find_first_zero(addr) ({ \  /*寻找子addr起的第一个为0的比特位,并返回其偏移值 */int __res; \__asm__("cld\n" \	"1:\tlodsl\n\t" \	"notl %%eax\n\t" \	"bsfl %%eax,%%edx\n\t" \	"je 2f\n\t" \	"addl %%edx,%%ecx\n\t" \	"jmp 3f\n" \	"2:\taddl $32,%%ecx\n\t" \	"cmpl $8192,%%ecx\n\t" \	"jl 1b\n" \	"3:" \	:"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \__res;})void free_block(int dev, int block) /* 释放块 */{	struct super_block * sb;	struct buffer_head * bh;	if (!(sb = get_super(dev))) /* 找到设备的超级块 */		panic("trying to free block on nonexistent device");	if (block < sb->s_firstdatazone || block >= sb->s_nzones)/* 判断数据块是否越界*/		panic("trying to free block not in datazone");	bh = get_hash_table(dev,block);	if (bh) { /* 释放缓冲区中对应的缓冲块 */		if (bh->b_count != 1) {			printk("trying to free block (%04x:%d), count=%d\n",				dev,block,bh->b_count);			return;		}		bh->b_dirt=0;		bh->b_uptodate=0;		brelse(bh);	}	block -= sb->s_firstdatazone - 1 ;/* 复位块位图中的相应位 */	if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {		printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);		panic("free_block: bit already cleared");	}	sb->s_zmap[block/8192]->b_dirt = 1;/*置相应块的位图块所缓冲块为已修改 */}int new_block(int dev)/* 向设备申请一个数据块,并在内存中申请一缓冲块与该块对应以备后用 */{	struct buffer_head * bh;	struct super_block * sb;	int i,j;	if (!(sb = get_super(dev))) /* 找到设备的超级块 */		panic("trying to get new block from nonexistant device");	j = 8192; /* 在设备的逻辑位图上搜索第一个0值比特位 */	for (i=0 ; i<8 ; i++)		if (bh=sb->s_zmap[i])			if ((j=find_first_zero(bh->b_data))<8192)				break;	if (i>=8 || !bh || j>=8192)		return 0;	if (set_bit(j,bh->b_data))/* 置位该块对应的位图中的比特位 */		panic("new_block: bit already set");	bh->b_dirt = 1;/*置位缓冲区中的位图块为已修改 */	j += i*8192 + sb->s_firstdatazone-1;/* 数据块号转实际块号 */	if (j >= sb->s_nzones)		return 0;	if (!(bh=getblk(dev,j))) /* 申请一缓冲块 */		panic("new_block: cannot get block");	if (bh->b_count != 1) 		panic("new block: count is != 1");	clear_block(bh->b_data); /* 清缓冲块数据 */	bh->b_uptodate = 1;	bh->b_dirt = 1;	brelse(bh); /* 释放该缓冲块(此时内存中有一干净,未锁定,未被引用的缓冲块与设备上的块相对应) */	return j;}void free_inode(struct m_inode * inode)/* 释放i节点 */{	struct super_block * sb;	struct buffer_head * bh;	if (!inode)		return;	if (!inode->i_dev) {/* 若i节点上的设备号字段为0,说明该i节点没有使用,于是用0清空i节点所占内存区 */		memset(inode,0,sizeof(*inode));		return;	}	if (inode->i_count>1) {		printk("trying to free inode with count=%d\n",inode->i_count);		panic("free_inode");	}	if (inode->i_nlinks)		panic("trying to free inode with links");	if (!(sb = get_super(inode->i_dev)))		panic("trying to free inode on nonexistent device");	if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)/* i_num(i节点号) */		panic("trying to free inode 0 or nonexistant inode");	if (!(bh=sb->s_imap[inode->i_num>>13]))		panic("nonexistent imap in superblock");	if (clear_bit(inode->i_num&8191,bh->b_data))/*复位i节点位图中对应的比特位 */		printk("free_inode: bit already cleared.\n\r");	bh->b_dirt = 1;	memset(inode,0,sizeof(*inode));/* 清除i节点结构(内存中) */}struct m_inode * new_inode(int dev)/* 新建i节点(在内存i节点表中获取一空闲项,从i节点位图中找一个空闲i节点) */{	struct m_inode * inode;	struct super_block * sb;	struct buffer_head * bh;	int i,j;	if (!(inode=get_empty_inode()))/* 从内存i节点表中获取一个空闲i节点项(inode.c,194) */		return NULL;	if (!(sb = get_super(dev)))/* 找到设备的超级块 */		panic("new_inode with unknown device");	j = 8192;	for (i=0 ; i<8 ; i++)/* 在i节点位图中找一空闲i节点 */		if (bh=sb->s_imap[i])			if ((j=find_first_zero(bh->b_data))<8192)				break;	if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {		iput(inode);/* 若未在i节点位图中找到空闲位,则放回刚才在内存i节点表中申请的i节点结构 */		return NULL;	}	if (set_bit(j,bh->b_data))//* 置位i节点位图中对应的比特位 */		panic("new_inode: bit already set");	bh->b_dirt = 1;	inode->i_count=1;/* 引用计数 */	inode->i_nlinks=1;/* 文件目录项链接数 */	inode->i_dev=dev;	inode->i_uid=current->euid;	inode->i_gid=current->egid;	inode->i_dirt=1;	inode->i_num = j + i*8192;	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;	return inode;}

⌨️ 快捷键说明

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