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

📄 bitmap.c

📁 在VC平台下调试通过的linux 0.11文件系统代码! 对学习文件系统实现的朋友很有帮助
💻 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>
#include "fs.h"

//// 将指定地址(addr)处的一块内存清零。嵌入汇编程序宏。
// 输入:eax = 0,ecx = 数据块大小BLOCK_SIZE/4,edi = addr。

static void clear_block(char *addr) 
{
	int i ;
	for (i = 0;i < BLOCK_SIZE/4; i++)
		addr[i] = 0;
}

/*#define clear_block(addr) \__asm__("cld\n\t" \	"rep\n\t" \	"stosl" \	::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")*/
static int set_bit(int nr, char * addr)
{
	char * p;
	int t,x;
	p = addr + nr/8;
	x = *p;
	t = 1 &(x >> nr%8);
	*p |= 1 << (nr%8);
	return t;
}

/*#define set_bit(nr,addr) ({\register int res __asm__("ax"); \__asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \res;})*/
static int clear_bit(int nr, char *addr)
{	
	char * p;
	int t,x;
	p = addr + nr/8;
	x = *p;
	t = 1 &(x >> nr%8);
	*p &= ~(1 << (nr%8));
	return t;

}


/*#define clear_bit(nr,addr) ({\register int res __asm__("ax"); \__asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \"=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \res;})*/

static int find_first_zero(char * addr)
{
int i = 0;
	unsigned char t;
	while (i < 1024)
	{
		if (addr[i] != -1)
			break;

		i++;
	}


	if (i >= 1024)
		return 0;
	t = addr[i];
	if (!(t & (1)))
		return i * 8;
	if (!(t & (2)))
		return i * 8 + 1;
	if (!(t & (4)))
		return i * 8 + 2;
	if (!(t & (8)))
		return i * 8 + 3;
	if (!(t & (16)))
		return i * 8 + 4;
	if (!(t & (32)))
		return i * 8 + 5;
	if (!(t & (64)))
		return i * 8 + 6;
	if (!(t & (128)))
		return i * 8 + 7;
		
	return 0;
}

/*#define find_first_zero(addr) ({ \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");

	//从buffer的hash表中找到该块,释放之。	bh = get_hash_table(dev,block);	if (bh) {		if (bh->b_count != 1) {			panic("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);	}

	//修改该块在bitmap中的对应为为0。	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");	}

	//设置刚修改过的bitmap块为dirty	sb->s_zmap[block/8192]->b_dirt = 1;}int new_block(int dev){	struct buffer_head * bh;	struct super_block * sb;	int i,j;
	//更具superblock找到第一个空闲块	if (!(sb = get_super(dev)))		panic("trying to get new block from nonexistant device");	j = 8192;	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");

	//设置该bit对应的块已修改	bh->b_dirt = 1;

	//换算该bit对应的逻辑块号	j += i*8192 + sb->s_firstdatazone-1;	if (j >= sb->s_nzones)		return 0;

	//从buffer中找到该块对应的buffer_head	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){	struct super_block * sb;	struct buffer_head * bh;
	//首先判断参数的合法性	if (!inode)		return;	if (!inode->i_dev) {		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");



	//得到超级块,判断该inode是否在设备有效范围中	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)		panic("trying to free inode 0 or nonexistant inode");
	if (!(bh=sb->s_imap[inode->i_num>>13]))		panic("nonexistent imap in superblock");


	//复位该inode对应的inode bitmap中对应位	if (clear_bit(inode->i_num&8191,bh->b_data))		printk("free_inode: bit already cleared.\n\r");

	//设置该inode bitmap所在的buffer dirt	bh->b_dirt = 1;

	//清零该inode。	memset(inode,0,sizeof(*inode));}struct m_inode * new_inode(int dev){	struct m_inode * inode;	struct super_block * sb;	struct buffer_head * bh;	int i,j;
	//从inode_table(在内存中)中找到一个空闲的inode	if (!(inode=get_empty_inode()))		return NULL;
	//根据superblock,inode 的bitmap,找到第一个空闲块	if (!(sb = get_super(dev)))		panic("new_inode with unknown device");	j = 8192;	for (i=0 ; i<8 ; i++)		if (bh=sb->s_imap[i])			if ((j=find_first_zero(bh->b_data))<8192)				break;

			//如果没有空闲的inode,返回	if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {		iput(inode);		return NULL;	}

	//设置该块对应的inode bitmap 中的bit	if (set_bit(j,bh->b_data))		panic("new_inode: bit already set");

	//初始化该inode	bh->b_dirt = 1;	inode->i_count=1;	inode->i_nlinks=1;	inode->i_dev=dev;	inode->i_uid= 0 ;//current->euid;	inode->i_gid= 0; //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 + -