file_table.c 文件分析 linux1_0\linux\fs\file_table.c

/*
 *  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;          //文件位置为0

//文件双向链表插入文件点,并把first_file指向当前文件点。
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;
}

//双向链表删除文件点
static void remove_file_free(struct file *file)
{
	//如果first_file点被删,first_file 往下移
	if (first_file == file)
		first_file = first_file->f_next;

	//下个链表点指向前链表点
	if (file->f_next)
		file->f_next->f_prev = file->f_prev;

	//前个链表点指向下个链表点
	if (file->f_prev)
		file->f_prev->f_next = file->f_next;

	//当前删除点向前,向后指针指为空
	file->f_next = file->f_prev = NULL;
}

//把链表点放到双向链表最后
static void put_last_free(struct file *file)
{
	remove_file_free(file);
	file->f_prev = first_file->f_prev;
	file->f_prev->f_next = file;
	file->f_next = first_file;
	file->f_next->f_prev = file;
}

//根据申请的页,生成N个文件点,并同时插入双向链表
void grow_files(void)
{
	struct file * file;
	int i;

	//分配空页
	file = (struct file *) get_free_page(GFP_KERNEL);  

	//分配失败返回
	if (!file)
		return;

	//每页生成n个文件链表点
	nr_files+=i= PAGE_SIZE/sizeof(struct file);

	//如果不存在头节点的话,设定头节点; file 指向往下移动,个数i减1
	if (!first_file)
		file->f_next = file->f_prev = first_file = file++, i--;

	//挨个插入列表
	for (; i ; i--)
		insert_file_free(file++);
}

//文件链表初始化
unsigned long file_table_init(unsigned long start, unsigned long end)
{
	first_file = NULL;
	return start;
}

//获取空的文件链表点
struct file * get_empty_filp(void)
{
	int i;
	struct file * f;

    //不存在first_file,分配链表空间
	if (!first_file)
		grow_files();
repeat:
	for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
        //存在为记录的链表点,把该链表放到最后,并
		if (!f->f_count) {
			//从链表中移除
			remove_file_free(f);
			//链表点初始化为空
			memset(f,0,sizeof(*f));
			//把链表放到最后
			put_last_free(f);
			//记录使用数
			f->f_count = 1;
			//返回分配的链表点
			return f;
		}
	//如果没有找到空链表点,并且 链表数小于NR_FILE(1024);在生成链表点
	if (nr_files < NR_FILE) {
		//按页空间生成链表点
		grow_files();
		goto repeat;
	}
	//已经分配链表点大于NR_FILE(1024) 返回空
	return NULL;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值