📄 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>#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 + -