千家信息网

linux1.2.13 file结构体管理是怎样的

发表于:2024-11-14 作者:千家信息网编辑
千家信息网最后更新 2024年11月14日,本篇内容介绍了"linux1.2.13 file结构体管理是怎样的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能
千家信息网最后更新 2024年11月14日linux1.2.13 file结构体管理是怎样的

本篇内容介绍了"linux1.2.13 file结构体管理是怎样的"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

操作系统为进程维护了打开的文件列表,每个进程维护了一个file数组字段(struct file * fd[NR_OPEN]);每个元素指向一个file结构体。每个file结构体有一个字段指向inode结构体,inode管理这个文件的内容、权限等信息。这里分析的是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 #include #include
struct file * first_file;int nr_files = 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){ // 如果要删除的节点是第一个节点,则更新头指针,指向下一个节点 if (first_file == file) first_file = first_file->f_next; // 如果被删除的节点后面还有节点,则需要更新下一个节点的prev指针,指向当前节点的上一个节点 if (file->f_next) file->f_next->f_prev = file->f_prev; // 同理,更新上一个节点的next指针,指向被删除节点的下一个节点 if (file->f_prev) file->f_prev->f_next = file->f_next; // 置空 file->f_next = file->f_prev = NULL;}
// file插入链表,成为最后一个节点static void put_last_free(struct file *file){ // 保证file脱离了原来的链表 remove_file_free(file); // 插入链表,但是不更新头指针first_file,所以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;}
void grow_files(void){ struct file * file; int i; // 申请一页内存 file = (struct file *) get_free_page(GFP_KERNEL);
if (!file) return; // i=PAGE_SIZE/sizeof(struct file),即一页可以存多少个节点,更新最大节点数 nr_files+=i= PAGE_SIZE/sizeof(struct file); /* 当前是初始化的时候,先初始化一个节点,需要初始化的节点数减一,执行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是链表的总节点数 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; f->f_version = ++event; return f; } // 没有找到空闲节点,扩容,再找 if (nr_files < NR_FILE) { grow_files(); goto repeat; } return NULL;}

从图中我们可以看出,系统维护了一个双向循环的链表,保存了一系列已使用和未使用的file结构体。first_file指针执行第一个空闲的节点,进程申请file结构体的时候就把该节点放到链表结尾。first_file指针指向下一个空闲节点。如果没有空闲节点了,就会自动扩容。

"linux1.2.13 file结构体管理是怎样的"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0