?? inode.c
字號:
#include <string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/system.h>
struct m_inode inode_table[NR_INODE]={{0,},};
static void read_inode(struct m_inode * inode);
static void write_inode(struct m_inode * inode);
static inline void wait_on_inode(struct m_inode * inode)
{
cli();
while (inode->i_lock)
sleep_on(&inode->i_wait); //在sched.c中定義
sti();
}
static inline void lock_inode(struct m_inode * inode)
{
cli();
while (inode->i_lock)
sleep_on(&inode->i_wait);
inode->i_lock=1;
sti();
}
static inline void unlock_inode(struct m_inode * inode)
{
inode->i_lock=0;
wake_up(&inode->i_wait); //在sched.c中定義
}
void sync_inodes(void)
{
int i;
struct m_inode * inode;
inode = 0+inode_table;
for(i=0 ; i<NR_INODE ; i++,inode++) {
wait_on_inode(inode);
if (inode->i_dirt && !inode->i_pipe)
write_inode(inode);
}
}
static int _bmap(struct m_inode * inode,int block,int create) //文件的硬盤映射
{
struct buffer_head * bh;
int i;
if (block<0)
panic("_bmap: block<0");
if (block >= 7+512+512*512) //此塊是否超過了最大的文件影像所表示的塊
panic("_bmap: block>big");
if (block<7) {
if (create && !inode->i_zone[block]) //如果是要創建,并且該直接塊是null的
if (inode->i_zone[block]=new_block(inode->i_dev)) { //建立新塊,將找到的塊放入i_zone中
inode->i_ctime=CURRENT_TIME; //修改時間
inode->i_dirt=1; //要求寫盤
}
return inode->i_zone[block];
}
block -= 7;
if (block<512) { //如果此塊位于一級間接塊
if (create && !inode->i_zone[7])
if (inode->i_zone[7]=new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
if (!inode->i_zone[7])
return 0;
if (!(bh = bread(inode->i_dev,inode->i_zone[7]))) //將一級間接塊讀入緩沖區
return 0;
i = ((unsigned short *) (bh->b_data))[block]; //在一級間接塊數據區中找到相應塊號
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block]=i; //將找到的實際塊寫入一級間接塊數據區
bh->b_dirt=1;
}
brelse(bh);
return i;
}
block -= 512; //如果是二級間接塊
if (create && !inode->i_zone[8])
if (inode->i_zone[8]=new_block(inode->i_dev)) {
inode->i_dirt=1;
inode->i_ctime=CURRENT_TIME;
}
if (!inode->i_zone[8])
return 0;
if (!(bh=bread(inode->i_dev,inode->i_zone[8])))
return 0;
i = ((unsigned short *)bh->b_data)[block>>9];
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block>>9]=i;
bh->b_dirt=1;
}
brelse(bh);
if (!i)
return 0;
if (!(bh=bread(inode->i_dev,i)))
return 0;
i = ((unsigned short *)bh->b_data)[block&511];
if (create && !i)
if (i=new_block(inode->i_dev)) {
((unsigned short *) (bh->b_data))[block&511]=i;
bh->b_dirt=1;
}
brelse(bh);
return i;
}
int bmap(struct m_inode * inode,int block)
{
return _bmap(inode,block,0);
}
int create_block(struct m_inode * inode, int block)
{
return _bmap(inode,block,1);
}
void iput(struct m_inode * inode) //釋放該節點及該節點使用的所有塊(在內存map中)
{
if (!inode)
return;
wait_on_inode(inode);
if (!inode->i_count)
panic("iput: trying to free free inode");
if (inode->i_pipe) { //如果該節點是一個管道
wake_up(&inode->i_wait);
if (--inode->i_count) //如果此節點是共享的,直接返回
return;
free_page(inode->i_size); //如果沒有進程用此節點,釋放該頁
inode->i_count=0;
inode->i_dirt=0;
inode->i_pipe=0;
return;
}
if (!inode->i_dev || inode->i_count>1) {
inode->i_count--;
return;
}
repeat:
if (!inode->i_nlinks) {
truncate(inode); //釋放此節點的所有直接和間接塊的map
free_inode(inode); //在s_imap表中清除該節點
return;
}
if (inode->i_dirt) {
write_inode(inode); /* we can sleep - so do again */
wait_on_inode(inode);
goto repeat;
}
inode->i_count--;
return;
}
static volatile int last_allocated_inode = 0;
struct m_inode * get_empty_inode(void)
{
struct m_inode * inode;
int inr;
while (1) {
inode = NULL;
inr = last_allocated_inode;
do { //這個循環是在inode_table中取得一個內存節點
if (!inode_table[inr].i_count) {
inode = inr + inode_table;
break;
}
inr++;
if (inr>=NR_INODE)
inr=0;
} while (inr != last_allocated_inode);
if (!inode) { //如果節點為空,那么出錯
for (inr=0 ; inr<NR_INODE ; inr++)
printk("%04x: %6d\t",inode_table[inr].i_dev,
inode_table[inr].i_num);
panic("No free inodes in mem");
}
last_allocated_inode = inr;
wait_on_inode(inode);
while (inode->i_dirt) { //如果節點是臟的,那么寫盤
write_inode(inode);
wait_on_inode(inode);
}
if (!inode->i_count)
break;
}
memset(inode,0,sizeof(*inode)); //將此節點初始化為0
inode->i_count = 1; //標記已分配
return inode;
}
struct m_inode * get_pipe_inode(void)
{
struct m_inode * inode;
if (!(inode = get_empty_inode())) //為管道取一個空的節點
return NULL;
if (!(inode->i_size=get_free_page())) { //為這個節點分配內存
inode->i_count = 0;
return NULL;
}
inode->i_count = 2; /* sum of readers/writers */
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; //初始化管道為0
inode->i_pipe = 1; //標記該節點是一個管道
return inode;
}
struct m_inode * iget(int dev,int nr)
{
struct m_inode * inode, * empty;
if (!dev)
panic("iget with dev==0");
empty = get_empty_inode(); //取一個空閑的內存節點
inode = inode_table; //inode指向inode_table[0]
while (inode < NR_INODE+inode_table) {
if (inode->i_dev != dev || inode->i_num != nr) { //尋找是否有dev和nr的內存節點
inode++;
continue;
}
wait_on_inode(inode); //等待釋放此節點
if (inode->i_dev != dev || inode->i_num != nr) {
inode = inode_table;
continue;
}
inode->i_count++;
if (empty)
iput(empty);
return inode;
}
//以下代碼是如果在當前的inode_table中沒有現成的,所要執行的
if (!empty)
return (NULL);
inode=empty;
inode->i_dev = dev;
inode->i_num = nr;
read_inode(inode);
return inode;
}
static void read_inode(struct m_inode * inode)
{
struct super_block * sb;
struct buffer_head * bh;
int block;
lock_inode(inode);
sb=get_super(inode->i_dev); //取得相應的i_dev所在的超級塊
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
(inode->i_num-1)/INODES_PER_BLOCK; //計算出塊號
if (!(bh=bread(inode->i_dev,block)))
panic("unable to read i-node block"); //讀取節點所在的塊進入buffer
*(struct d_inode *)inode =
((struct d_inode *)bh->b_data)
[(inode->i_num-1)%INODES_PER_BLOCK]; //計算出該節點在這個塊的位移
brelse(bh);
unlock_inode(inode);
}
static void write_inode(struct m_inode * inode)
{
struct super_block * sb;
struct buffer_head * bh;
int block;
lock_inode(inode);
sb=get_super(inode->i_dev); //get_super在fs.h中定義
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
(inode->i_num-1)/INODES_PER_BLOCK;
if (!(bh=bread(inode->i_dev,block)))
panic("unable to read i-node block");
((struct d_inode *)bh->b_data)
[(inode->i_num-1)%INODES_PER_BLOCK] =
*(struct d_inode *)inode;
bh->b_dirt=1;
inode->i_dirt=0;
brelse(bh);
unlock_inode(inode);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -