?? inode.c
字號:
{ inode->i_count--; return; }// 如果是塊設備文件的i 節點,此時邏輯塊字段0 中是設備號,則刷新該設備。并等待i 節點解鎖。 if (S_ISBLK (inode->i_mode)) { sync_dev (inode->i_zone[0]); wait_on_inode (inode); }repeat:// 如果i 節點的引用計數大于1,則遞減1。 if (inode->i_count > 1) { inode->i_count--; return; }// 如果i 節點的鏈接數為0,則釋放該i 節點的所有邏輯塊,并釋放該i 節點。 if (!inode->i_nlinks) { truncate (inode); free_inode (inode); return; }// 如果該i 節點已作過修改,則更新該i 節點,并等待該i 節點解鎖。 if (inode->i_dirt) { write_inode (inode); /* we can sleep - so do again */ wait_on_inode (inode); goto repeat; }// i 節點引用計數遞減1。 inode->i_count--; return;}//// 從i 節點表(inode_table)中獲取一個空閑i 節點項。// 尋找引用計數count 為0 的i 節點,并將其寫盤后清零,返回其指針。struct m_inode *get_empty_inode (void){ struct m_inode *inode; static struct m_inode *last_inode = inode_table; // last_inode 指向i 節點表第一項。 int i; do {// 掃描i 節點表。 inode = NULL; for (i = NR_INODE; i; i--) {// 如果last_inode 已經指向i 節點表的最后1 項之后,則讓其重新指向i 節點表開始處。 if (++last_inode >= inode_table + NR_INODE) last_inode = inode_table;// 如果last_inode 所指向的i 節點的計數值為0,則說明可能找到空閑i 節點項。讓inode 指向// 該i 節點。如果該i 節點的已修改標志和鎖定標志均為0,則我們可以使用該i 節點,于是退出循環。 if (!last_inode->i_count) { inode = last_inode; if (!inode->i_dirt && !inode->i_lock) break; } }// 如果沒有找到空閑i 節點(inode=NULL),則將整個i 節點表打印出來供調試使用,并死機。 if (!inode) { for (i = 0; i < NR_INODE; i++) printk ("%04x: %6d\t", inode_table[i].i_dev, inode_table[i].i_num); panic ("No free inodes in mem"); }// 等待該i 節點解鎖(如果又被上鎖的話)。 wait_on_inode (inode);// 如果該i 節點已修改標志被置位的話,則將該i 節點刷新,并等待該i 節點解鎖。 while (inode->i_dirt) { write_inode (inode); wait_on_inode (inode); } } while (inode->i_count); // 如果i 節點又被其它占用的話,則重新尋找空閑i 節點。// 已找到空閑i 節點項。則將該i 節點項內容清零,并置引用標志為1,返回該i 節點指針。 memset (inode, 0, sizeof (*inode)); inode->i_count = 1; return inode;}//// 獲取管道節點。返回為i 節點指針(如果是NULL 則失敗)。// 首先掃描i 節點表,尋找一個空閑i 節點項,然后取得一頁空閑內存供管道使用。// 然后將得到的i 節點的引用計數置為2(讀者和寫者),初始化管道頭和尾,置i 節點的管道類型表示。struct m_inode *get_pipe_inode (void){ struct m_inode *inode; if (!(inode = get_empty_inode ())) // 如果找不到空閑i 節點則返回NULL。 return NULL; if (!(inode->i_size = get_free_page ())) { // 節點的i_size 字段指向緩沖區。 inode->i_count = 0; // 如果已沒有空閑內存,則 return NULL; // 釋放該i 節點,并返回NULL。 } inode->i_count = 2; /* sum of readers/writers *//* 讀/寫兩者總計 */ PIPE_HEAD (*inode) = PIPE_TAIL (*inode) = 0; // 復位管道頭尾指針。 inode->i_pipe = 1; // 置節點為管道使用的標志。 return inode; // 返回i 節點指針。}//// 從設備上讀取指定節點號的i 節點。// nr - i 節點號。struct m_inode *iget (int dev, int nr){ struct m_inode *inode, *empty; if (!dev) panic ("iget with dev==0");// 從i 節點表中取一個空閑i 節點。 empty = get_empty_inode ();// 掃描i 節點表。尋找指定節點號的i 節點。并遞增該節點的引用次數。 inode = inode_table; while (inode < NR_INODE + inode_table) {// 如果當前掃描的i 節點的設備號不等于指定的設備號或者節點號不等于指定的節點號,則繼續掃描。 if (inode->i_dev != dev || inode->i_num != nr) { inode++; continue; }// 找到指定設備號和節點號的i 節點,等待該節點解鎖(如果已上鎖的話)。 wait_on_inode (inode);// 在等待該節點解鎖的階段,節點表可能會發生變化,所以再次判斷,如果發生了變化,則再次重新// 掃描整個i 節點表。 if (inode->i_dev != dev || inode->i_num != nr) { inode = inode_table; continue; }// 將該i 節點引用計數增1。 inode->i_count++; if (inode->i_mount) { int i;// 如果該i 節點是其它文件系統的安裝點,則在超級塊表中搜尋安裝在此i 節點的超級塊。如果沒有// 找到,則顯示出錯信息,并釋放函數開始獲取的空閑節點,返回該i 節點指針。 for (i = 0; i < NR_SUPER; i++) if (super_block[i].s_imount == inode) break; if (i >= NR_SUPER) { printk ("Mounted inode hasn't got sb\n"); if (empty) iput (empty); return inode; }// 將該i 節點寫盤。從安裝在此i 節點文件系統的超級塊上取設備號,并令i 節點號為1。然后重新// 掃描整個i 節點表,取該被安裝文件系統的根節點。 iput (inode); dev = super_block[i].s_dev; nr = ROOT_INO; inode = inode_table; continue; }// 已經找到相應的i 節點,因此放棄臨時申請的空閑節點,返回該找到的i 節點。 if (empty) iput (empty); return inode; }// 如果在i 節點表中沒有找到指定的i 節點,則利用前面申請的空閑i 節點在i 節點表中建立該節點。// 并從相應設備上讀取該i 節點信息。返回該i 節點。 if (!empty) return (NULL); inode = empty; inode->i_dev = dev; inode->i_num = nr; read_inode (inode); return inode;}//// 從設備上讀取指定i 節點的信息到內存中(緩沖區中)。static voidread_inode (struct m_inode *inode){ struct super_block *sb; struct buffer_head *bh; int block;// 首先鎖定該i 節點,取該節點所在設備的超級塊。 lock_inode (inode); if (!(sb = get_super (inode->i_dev))) panic ("trying to read inode without dev");// 該i 節點所在的邏輯塊號 = (啟動塊+超級塊) + i 節點位圖占用的塊數 + 邏輯塊位圖占用的塊數 +// (i 節點號-1)/每塊含有的i 節點數。 block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num - 1) / INODES_PER_BLOCK;// 從設備上讀取該i 節點所在的邏輯塊,并將該inode 指針指向對應i 節點信息。 if (!(bh = bread (inode->i_dev, block))) panic ("unable to read i-node block"); *(struct d_inode *) inode = ((struct d_inode *) bh->b_data)[(inode->i_num - 1) % INODES_PER_BLOCK];// 最后釋放讀入的緩沖區,并解鎖該i 節點。 brelse (bh); unlock_inode (inode);}//// 將指定i 節點信息寫入設備(寫入緩沖區相應的緩沖塊中,待緩沖區刷新時會寫入盤中)。static voidwrite_inode (struct m_inode *inode){ struct super_block *sb; struct buffer_head *bh; int block;// 首先鎖定該i 節點,如果該i 節點沒有被修改過或者該i 節點的設備號等于零,則解鎖該i 節點,// 并退出。 lock_inode (inode); if (!inode->i_dirt || !inode->i_dev) { unlock_inode (inode); return; }// 獲取該i 節點的超級塊。 if (!(sb = get_super (inode->i_dev))) panic ("trying to write inode without device");// 該i 節點所在的邏輯塊號 = (啟動塊+超級塊) + i 節點位圖占用的塊數 + 邏輯塊位圖占用的塊數 +// (i 節點號-1)/每塊含有的i 節點數。 block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num - 1) / INODES_PER_BLOCK;// 從設備上讀取該i 節點所在的邏輯塊。 if (!(bh = bread (inode->i_dev, block))) panic ("unable to read i-node block");// 將該i 節點信息復制到邏輯塊對應該i 節點的項中。 ((struct d_inode *) bh->b_data) [(inode->i_num - 1) % INODES_PER_BLOCK] = *(struct d_inode *) inode;// 置緩沖區已修改標志,而i 節點修改標志置零。然后釋放該含有i 節點的緩沖區,并解鎖該i 節點。 bh->b_dirt = 1; inode->i_dirt = 0; brelse (bh); unlock_inode (inode);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -