您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“l(fā)inux1.2.13 file結構體管理是怎樣的”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!
操作系統(tǒng)為進程維護了打開的文件列表,每個進程維護了一個file數(shù)組字段(struct file * fd[NR_OPEN]);每個元素指向一個file結構體。每個file結構體有一個字段指向inode結構體,inode管理這個文件的內(nèi)容、權限等信息。這里分析的是file結構體的管理。
下面是file結構體的定義
struct file { mode_t f_mode; loff_t f_pos; unsigned short f_flags; unsigned short f_count; off_t f_reada; struct file *f_next, *f_prev; int f_owner; /* pid or -pgrp where SIGIO should be sent */ struct inode * f_inode; struct file_operations * f_op; unsigned long f_version; void *private_data; /* needed for tty driver, and maybe others */};
下面是對file結構體的管理,當進程打開一個文件的時候,就可能需要從中申請一個file結構體。
/*
* linux/fs/file_table.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
struct file * first_file;
int nr_files = 0;
// 雙向循環(huán)鏈表,first_file指向頭指針,頭插法插入一個節(jié)點
static void insert_file_free(struct file *file)
{
file->f_next = first_file;
file->f_prev = first_file->f_prev;
file->f_next->f_prev = file;
file->f_prev->f_next = file;
first_file = file;
}
// 刪除一個節(jié)點
static void remove_file_free(struct file *file)
{
// 如果要刪除的節(jié)點是第一個節(jié)點,則更新頭指針,指向下一個節(jié)點
if (first_file == file)
first_file = first_file->f_next;
// 如果被刪除的節(jié)點后面還有節(jié)點,則需要更新下一個節(jié)點的prev指針,指向當前節(jié)點的上一個節(jié)點
if (file->f_next)
file->f_next->f_prev = file->f_prev;
// 同理,更新上一個節(jié)點的next指針,指向被刪除節(jié)點的下一個節(jié)點
if (file->f_prev)
file->f_prev->f_next = file->f_next;
// 置空
file->f_next = file->f_prev = NULL;
}
// file插入鏈表,成為最后一個節(jié)點
static void put_last_free(struct file *file)
{
// 保證file脫離了原來的鏈表
remove_file_free(file);
// 插入鏈表,但是不更新頭指針first_file,所以file成為最后一個節(jié)點
file->f_prev = first_file->f_prev;
file->f_prev->f_next = file;
file->f_next = first_file;
file->f_next->f_prev = file;
}
void grow_files(void)
{
struct file * file;
int i;
// 申請一頁內(nèi)存
file = (struct file *) get_free_page(GFP_KERNEL);
if (!file)
return;
// i=PAGE_SIZE/sizeof(struct file),即一頁可以存多少個節(jié)點,更新最大節(jié)點數(shù)
nr_files+=i= PAGE_SIZE/sizeof(struct file);
/*
當前是初始化的時候,先初始化一個節(jié)點,需要初始化的節(jié)點數(shù)減一,執(zhí)行insert_file_free
前需要保證first_file非空,見insert_file_free中的first_file
*/
if (!first_file)
file->f_next = file->f_prev = first_file = file++, i--;
// 形成一個鏈表
for (; i ; i--)
insert_file_free(file++);
}
// file鏈表初始化
unsigned long file_table_init(unsigned long start, unsigned long end)
{
first_file = NULL;
return start;
}
// 獲取一個可以的file結構體
struct file * get_empty_filp(void)
{
int i;
struct file * f;
if (!first_file)
grow_files();
repeat:
// nr_files是鏈表的總節(jié)點數(shù)
for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
// 找到空閑的節(jié)點
if (!f->f_count) {
// 脫離鏈表
remove_file_free(f);
// 清空內(nèi)存
memset(f,0,sizeof(*f));
// 插入鏈表末尾
put_last_free(f);
// 標記已使用
f->f_count = 1;
f->f_version = ++event;
return f;
}
// 沒有找到空閑節(jié)點,擴容,再找
if (nr_files < NR_FILE) {
grow_files();
goto repeat;
}
return NULL;
}
從圖中我們可以看出,系統(tǒng)維護了一個雙向循環(huán)的鏈表,保存了一系列已使用和未使用的file結構體。first_file指針執(zhí)行第一個空閑的節(jié)點,進程申請file結構體的時候就把該節(jié)點放到鏈表結尾。first_file指針指向下一個空閑節(jié)點。如果沒有空閑節(jié)點了,就會自動擴容。
“l(fā)inux1.2.13 file結構體管理是怎樣的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。