📄 bitmap.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 + -