bitmap.c ( File view )

  • By 2010-08-31
  • View(s):24
  • Download(s):2
  • Point(s): 1
			/*
* linux/fs/bitmap.c
*
* (C) 1991 Linus Torvalds
*/

/* bitmap.c contains the code that handles the inode and block bitmaps */
/* bitmap.c 程序含有处理i 节点和磁盘块位图的代码 */
#include <string.h>		// 字符串头文件。主要定义了一些有关字符串操作的嵌入函数。
// 主要使用了其中的memset()函数。
#include <linux/sched.h>	// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,
// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。
#include <linux/kernel.h>	// 内核头文件。含有一些内核常用函数的原形定义。

//// 将指定地址(addr)处的一块内存清零。嵌入汇编程序宏。
// 输入:eax = 0,ecx = 数据块大小BLOCK_SIZE/4,edi = addr。
#define clear_block(addr) \
__asm__( "cld\n\t" \		// 清方向位。
"rep\n\t" \			// 重复执行存储数据(0)。
"stosl"::"a" (0), "c" (BLOCK_SIZE / 4), "D" ((long) (addr)):"cx", "di")
//// 置位指定地址开始的第nr 个位偏移处的比特位(nr 可以大于32!)。返回原比特位(0 或1)。
// 输入:%0 - eax(返回值),%1 - eax(0);%2 - nr,位偏移值;%3 - (addr),addr 的内容。
#define set_bit(nr,addr) ({
\
register int res __asm__( "ax"); \
__asm__ __volatile__( "btsl %2,%3\n\tsetb %%al": \
"=a" (res): "" (0), "r" (nr), "m" (*(addr))); \
res;
})
//// 复位指定地址开始的第nr 位偏移处的比特位。返回原比特位的反码(1 或0)。
// 输入:%0 - eax(返回值),%1 - eax(0);%2 - nr,位偏移值;%3 - (addr),addr 的内容。
#define clear_bit(nr,addr) ({
\
register int res __asm__( "ax"); \
__asm__ __volatile__( "btrl %2,%3\n\tsetnb %%al": \
"=a" (res): "" (0), "r" (nr), "m" (*(addr))); \
res;
})
//// 从addr 开始寻找第1 个0 值比特位。
// 输入:%0 - ecx(返回值);%1 - ecx(0);%2 - esi(addr)。
// 在addr 指定地址开始的位图中寻找第1 个是0 的比特位,并将其距离addr 的比特位偏移值返回。
#define find_first_zero(addr) ({
 \
int __res; \
__asm__( "cld\n" \		// 清方向位。
  "1:\tlodsl\n\t" \		// 取[esi]??eax。
  "notl %%eax\n\t" \		// eax 中每位取反。
  "bsfl %%eax,%%edx\n\t" \	// 从位0 扫描eax 中是1 的第1 个位,其偏移值??edx。
  "je 2f\n\t" \			// 如果eax 中全是0,则向前跳转到标号2 处(40 行)。
  "addl %%edx,%%ecx\n\t" \	// 偏移值加入ecx(ecx 中是位图中首个是0 的比特位的偏移值)
  "jmp 3f\n" \			// 向前跳转到标号3 处(结束)。
  "2:\taddl $32,%%ecx\n\t" \	// 没有找到0 比特位,则将ecx 加上1 个长字的位偏移量32。
  "cmpl $8192,%%ecx\n\t" \	// 已经扫描了8192 位(1024 字节)了吗?
  "jl 1b\n" \			// 若还没有扫描完1 块数据,则向前跳转到标号1 处,继续。
  "3:" \			// 结束。此时ecx 中是位偏移量。
: "=c" (__res): "c" (0), "S" (addr):"ax", "dx", "si");
__res;

}

)
//// 释放设备dev 上数据区中的逻辑块block。
// 复位指定逻辑块block 的逻辑块位图比特位。
// 参数:dev 是设备号,block 是逻辑块号(盘块号)。
     void free_block (int dev, int block)
     {

       struct super_block *sb;
       struct buffer_head *bh;

// 取指定设备dev 的超级块,如果指定设备不存在,则出错死机。
       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");
// 从hash 表中寻找该块数据。若找到了则判断其有效性,并清已修改和更新标志,释放该数据块。
// 该段代码的主要用途是如果该逻辑块当前存在于高速缓冲中,就释放对应的缓冲块。
       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 在数据区开始算起的数据逻辑块号(从1 开始计数)。然后对逻辑块(区块)位图进行操作,
// 复位对应的比特位。若对应比特位原来即是0,则出错,死机。
       block -= sb->s_firstdatazone - 1;	// block = block - ( -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;
     
}

////向设备dev 申请一个逻辑块(盘块,区块)。返回逻辑块号(盘块号)。
// 置位指定逻辑块block 的逻辑块位图比特位。
int new_block (int dev)
{

  struct buffer_head *bh;
  struct super_block *sb;
  int i, j;

// 从设备dev 取超级块,如果指定设备不存在,则出错死机。
  if (!(sb = get_super (dev)))
    panic ("trying to get new block from nonexistant device");
// 扫描逻辑块位图,寻找首个0 比特位,寻找空闲逻辑块,获取放置该逻辑块的块号。
  j = 8192;
  for (i = 0; i < 8; i++)
    if (bh = sb->s_zmap[i])
      if ((j = find_first_zero (bh->b_data)) < 8192)
	break;
// 如果全部扫描完还没找到(i>=8 或j>=8192)或者位图所在的缓冲块无效(bh=NULL)则 返回0,
// 退出(没有空闲逻辑块)。
  if (i >= 8 || !bh || j >= 8192)
    return 0;
// 设置新逻辑块对应逻辑块位图中的比特位,若对应比特位已经置位,则出错,死机。
  if (set_bit (j, bh->b_data))
    panic ("new_block: bit already set");
// 置对应缓冲区块的已修改标志。如果新逻辑块大于该设备上的总逻辑块数,则说明指定逻辑块在
// 对应设备上不存在。申请失败,返回0,退出。
  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");
// 新块的引用计数应为1。否则死机。
  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;

}

//// 释放指定的i 节点。
// 复位对应i 节点位图比特位。
void free_inode (struct m_inode *inode)
{

  struct super_block *sb;
  struct buffer_head *bh;

// 如果i 节点指针=NULL,则退出。
  if (!inode)
    return;
// 如果i 节点上的设备号字段为0,说明该节点无用,则用0 清空对应i 节点所占内存区,并返回。
  if (!inode->i_dev)
    {

      memset (inode, 0, sizeof (*inode));
      return;
    
}
// 如果此i 节点还有其它程序引用,则不能释放,说明内核有问题,死机。
  if (inode->i_count > 1)
    {

      printk ("trying to free inode with count=%d\n", inode->i_count);
      panic ("free_inode");
    
}
// 如果文件目录项连接数不为0,则表示还有其它文件目录项在使用该节点,不应释放,而应该放回等。
  if (inode->i_nlinks)
    panic ("trying to free inode with links");
// 取i 节点所在设备的超级块,测试设备是否存在。
  if (!(sb = get_super (inode->i_dev)))
    panic ("trying to free inode on nonexistent device");
// 如果i 节点号=0 或大于该设备上i 节点总数,则出错(0 号i 节点保留没有使用)。
  if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
    panic ("trying to free inode 0 or nonexistant inode");
// 如果该i 节点对应的节点位图不存在,则出错。
  if (!(bh = sb->s_imap[inode->i_num >> 13]))
    panic ("nonexistent imap in superblock");
// 复位i 节点对应的节点位图中的比特位,如果该比特位已经等于0,则出错。
  if (clear_bit (inode->i_num & 8191, bh->b_data))
    printk ("free_inode: bit already cleared.\n\r");
// 置i 节点位图所在缓冲区已修改标志,并清空该i 节点结构所占内存区。
  bh->b_dirt = 1;
  memset (inode, 0, sizeof (*inode));

}

//// 为设备dev 建立一个新i 节点。返回该新i 节点的指针。
// 在内存i 节点表中获取一个空闲i 节点表项,并从i 节点位图中找一个空闲i 节点。
struct m_inode *new_inode (int dev)
{

  struct m_inode *inode;
  struct super_block *sb;
  struct buffer_head *bh;
  int i, j;

// 从内存i 节点表(inode_table)中获取一个空闲i 节点项(inode)。
  if (!(inode = get_empty_inode ()))
    return NULL;
// 读取指定设备的超级块结构。
  if (!(sb = get_super (dev)))
    panic ("new_inode with unknown device");
// 扫描i 节点位图,寻找首个0 比特位,寻找空闲节点,获取放置该i 节点的节点号。
  j = 8192;
  for (i = 0; i < 8; i++)
    if (bh = sb->s_imap[i])
      if ((j = find_first_zero (bh->b_data)) < 8192)
	break;
// 如果全部扫描完还没找到,或者位图所在的缓冲块无效(bh=NULL)则 返回0,退出(没有空闲i 节点)。
  if (!bh || j >= 8192 || j + i * 8192 > sb->s_ninodes)
    {

      iput (inode);
      return NULL;
    
}
// 置位对应新i 节点的i 节点位图相应比特位,如果已经置位,则出错。
  if (set_bit (j, bh->b_data))
    panic ("new_inode: bit already set");
// 置i 节点位图所在缓冲区已修改标志。
  bh->b_dirt = 1;
// 初始化该i 节点结构。
  inode->i_count = 1;		// 引用计数。
  inode->i_nlinks = 1;		// 文件目录项链接数。
  inode->i_dev = dev;		// i 节点所在的设备号。
  inode->i_uid = current->euid;	// i 节点所属用户id。
  inode->i_gid = current->egid;	// 组id。
  inode->i_dirt = 1;		// 已修改标志置位。
  inode->i_num = j + i * 8192;	// 对应设备中的i 节点号。
  inode->i_mtime = inode->i_atime = inode->i_ctime = C
...
...
(Not finished, please download and read the complete file)
			
...
Expand> <Close

Want complete source code? Download it here

Point(s): 1

Download
0 lines left, continue to read
Sponsored links

File list

Tips: You can preview the content of files by clicking file names^_^
Name Size Date
linux0.00 B0% 04-10-07
<boot>0.00 B04-10-07 15:01
bootsect.s12.49 kB08-01-04 21:38
head.s13.22 kB08-01-04 21:38
setup.s12.42 kB08-01-04 21:38
<fs>0.00 B04-10-07 15:01
bitmap.c8.46 kB02-09-04 13:12
block_dev.c3.95 kB02-09-04 13:12
buffer.c17.71 kB02-09-04 13:12
char_dev.c4.09 kB02-09-04 13:12
exec.c18.90 kB02-09-04 13:12
fcntl.c3.33 kB02-09-04 13:12
file_dev.c4.82 kB02-09-04 13:12
file_table.c209.00 B02-09-04 13:12
inode.c14.92 kB02-09-04 13:12
ioctl.c1.94 kB02-09-04 13:12
Makefile6.80 kB08-01-04 21:45
namei.c37.20 kB02-09-04 13:12
open.c10.00 kB02-09-04 13:12
pipe.c5.42 kB02-09-04 13:12
read_write.c5.86 kB02-09-04 13:12
stat.c2.69 kB02-09-04 13:12
super.c13.57 kB02-09-04 13:12
truncate.c2.46 kB02-09-04 13:12
<include>0.00 B04-10-07 15:01
a.out.h8.22 kB02-09-04 13:14
<asm>0.00 B04-10-07 15:01
io.h772.00 B02-09-04 13:14
memory.h1.03 kB08-01-04 22:13
segment.h2.50 kB02-09-04 13:14
system.h4.08 kB02-09-04 13:14
const.h589.00 B02-09-04 13:14
ctype.h1.68 kB02-09-04 13:14
errno.h2.30 kB02-09-04 13:14
fcntl.h3.30 kB02-09-04 13:14
<linux>0.00 B04-10-07 15:01
config.h2.16 kB02-09-04 13:14
fs.h9.72 kB02-09-04 13:14
hdreg.h2.94 kB02-09-04 13:14
head.h760.00 B02-09-04 13:14
kernel.h1.44 kB02-09-04 13:14
mm.h473.00 B02-09-04 13:14
sched.h13.25 kB02-09-04 13:14
sys.h5.41 kB02-09-04 13:14
tty.h3.93 kB02-09-04 13:14
signal.h4.01 kB02-09-04 13:14
stdarg.h1.77 kB02-09-04 13:14
stddef.h378.00 B02-09-04 13:14
string.h21.75 kB02-09-04 13:14
<sys>0.00 B04-10-07 15:01
stat.h2.37 kB02-09-04 13:14
times.h377.00 B02-09-04 13:14
types.h1.10 kB02-09-04 13:14
utsname.h423.00 B02-09-04 13:14
wait.h1.48 kB02-09-04 13:14
termios.h13.58 kB02-09-04 13:14
time.h1.81 kB02-09-04 13:14
unistd.h9.21 kB02-09-04 13:14
utime.h392.00 B02-09-04 13:14
<init>0.00 B04-10-07 15:01
main.c12.52 kB02-09-04 13:12
<kernel>0.00 B04-10-07 15:01
asm.s5.10 kB08-01-04 22:48
<blk_drv>0.00 B04-10-07 15:01
blk.h5.69 kB02-09-04 13:14
floppy.c23.49 kB02-09-04 13:12
hd.c17.14 kB02-09-04 13:12
ll_rw_blk.c7.59 kB02-09-04 13:12
Makefile4.25 kB08-01-04 22:53
ramdisk.c6.13 kB02-09-04 13:12
<chr_drv>0.00 B04-10-07 15:01
console.c30.91 kB02-09-04 13:12
keyboard.S21.04 kB08-01-04 22:59
Makefile4.81 kB08-01-04 22:59
rs_io.s5.75 kB08-01-04 22:59
serial.c2.91 kB02-09-04 13:12
tty_io.c18.40 kB02-09-04 13:12
tty_ioctl.c10.70 kB02-09-04 13:12
exit.c8.08 kB02-09-04 13:12
fork.c6.78 kB15-07-07 22:10
<math>0.00 B04-10-07 15:01
Makefile3.21 kB08-01-04 23:01
math_emulate.c2.08 kB02-09-04 13:12
mktime.c2.72 kB02-09-04 13:12
panic.c952.00 B02-09-04 13:12
printk.c1.75 kB02-09-04 13:12
sched.c18.57 kB16-07-07 21:23
signal.c5.61 kB02-09-04 13:12
sys.c7.62 kB02-09-04 13:12
system_call.s12.53 kB08-01-04 22:48
traps.c8.29 kB04-10-07 14:57
vsprintf.c9.96 kB02-09-04 13:12
<lib>0.00 B04-10-07 15:01
close.c397.00 B02-09-04 13:12
ctype.c1.72 kB02-09-04 13:12
dup.c401.00 B02-09-04 13:12
errno.c66.00 B02-09-04 13:12
execve.c607.00 B02-09-04 13:12
Makefile4.83 kB08-01-04 22:30
malloc.c13.50 kB02-09-04 13:12
open.c1.22 kB02-09-04 13:12
setsid.c382.00 B02-09-04 13:12
string.c199.00 B02-09-04 13:12
wait.c774.00 B02-09-04 13:12
write.c545.00 B02-09-04 13:12
_exit.c616.00 B02-09-04 13:12
Makefile8.58 kB08-01-04 22:21
<mm>0.00 B04-10-07 15:01
Makefile2.91 kB08-01-04 22:34
memory.c25.10 kB02-09-04 13:12
page.s842.00 B08-01-04 22:34
<tools>0.00 B04-10-07 15:01
build.c8.12 kB02-09-04 13:12
...
Sponsored links

bitmap.c (286.77 kB)

Need 1 point
Your Point(s)

Your Point isn't enough.

Get point immediately by PayPal

More(Debit card / Credit card / PayPal Credit / Online Banking)

Submit your source codes. Get more point

LOGIN

Don't have an account? Register now
Need any help?
Mail to: support@codeforge.com

切换到中文版?

CodeForge Chinese Version
CodeForge English Version

Where are you going?

^_^"Oops ...

Sorry!This guy is mysterious, its blog hasn't been opened, try another, please!
OK

Warm tip!

CodeForge to FavoriteFavorite by Ctrl+D