Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1641107
  • 博文数量: 124
  • 博客积分: 4078
  • 博客等级: 中校
  • 技术积分: 3943
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 11:28
个人简介

新博客:http://sparkandshine.net/

文章分类

全部博文(124)

分类: 嵌入式

2012-01-07 16:52:30

摘要:

    本文重在讲述file和file_header的联系与区别,首先分别分析了file与file_header结构体,而后介绍两者的联系,最后分析几组易混的成员变量,包括page与log_page、file与file_header的flags、deprecated_eof_hint与end、record_count与log_records。


一、file

结构体file源码如下:

  1. struct file
  2. {
  3.   cfs_offset_t end;
  4.   coffee_page_t page;
  5.   coffee_page_t max_pages;
  6.   int16_t record_count;
  7.   uint8_t references;
  8.   uint8_t flags;
  9. };

end

    指向存放文件的最后一个字节的偏移量,当打开一个文件时,Coffee用蛮力法找到文件末尾(file_header是不存储文件末尾的位置,因为文件长度经常改变)。详情见博文《Contiki学习笔记:Coffee文件系统打开文件cfs_open》。

page

    指向物理文件的第一页,即存放文件元数据file_header的页。通常的用法如下:

  1. //用法1:static struct file *find_file(const char *name)
  2. read_header(&hdr, coffee_files[i].page); //读取文件元数据file_header到hdr

  3. //用法2:static int remove_by_page(coffee_page_t page, int remove_log, int close_fds, int gc_allowed)
  4. coffee_files[i].page = INVALID_PAGE;//将file->page标识为INVALID_PAGE,表示该缓存file项可分配给其他文件用
  5. #define INVALID_PAGE ((coffee_page_t)-1//注1

max_pages

    max_pages含义跟file_header->max_pages相同,即为该文件保留的页面数,加载文件load_file函数将file_headermax_pages赋给file的max_pages。

record_count

    record_count表示实际的微日志记录数量,不同于file_header的log_records。

references

    Contiki提供类多线程编程环境,会有这样的情况,多个线程同时打开一个文件,需要记录引用次数。打开文件cfs_open引用次数++,关闭文件cfs_close引用次数--。

flags

    flags两种取值:0和COFFEE_FILE_MODIFIED,即标识该文件是否含有微日志文件。详情见博文《Contiki学习笔记:Coffee文件系统flags标志位》。

注1:

    这里用了个小技巧,使得程度更具移植性。因为在cfs-coffee.arch.h,coffee_page_t有可能是8位,也有可能是16位,源码如下:

  1. #if COFFEE_PAGES <= 127
  2.   #define coffee_page_t u8_t
  3. #elif COFFEE_PAGES <= 0x7FFF
  4.   #define coffee_page_t u16_t
  5. #endif

    把INVALID_PAGE定义为coffee_page_t-1,如果coffee_page_t是8位,那么INVALID_PAGE为0xFF,如果coffee_page_t是16位,那么INVALID_PAGE为0xFFFF,可以自适应coffee_page_t类型的变化,更具移植性。关于这个技巧可参见博文《具有可移植的无穷大定义》。


二、file_header

结构体file_header源码如下:

  1. struct file_header
  2. {
  3.   coffee_page_t log_page;
  4.   uint16_t log_records;
  5.   uint16_t log_record_size;
  6.   coffee_page_t max_pages;
  7.   uint8_t deprecated_eof_hint;
  8.   uint8_t flags;
  9.   char name[COFFEE_NAME_LENGTH];
  10. };

log_page

    不同于file->page,log_page指向微日志的第一页(如果配置了微日志)。

log_records

    表示日志可以容纳的记录数量(log records denotes the number of records that the log can hold)

log_record_size

    log_record_size表示微日志文件大小,如果为0,则设置成默认值(见cfs-coffee-arch.h文件配置#define COFFEE_LOG_SIZE 128)。

max_pages

    max_pages指为文件保留着页面数(The max pages field specifies the amount of pages that have been reserved for the file)

deprecated_eof_hint

    因为文件头不能存储文件长度(缘于文件长度经常变化着),所以用deprecated_eof_hint指向文件的最后一个字节。文件关闭时,如果文件长度增加则需更新deprecated_eof_hint。事实上,纵观源码,deprecated_eof_hint都没用到,而是用file->end存储文件末尾的位置(打开文件时,用蛮力法扫描得到该文件的末尾位置)。

flags

    flags反映了文件当前状态(The flag field tells us the current state),用了6个位,分别是ALOMIV,详情请见博文《Contiki学习笔记:Coffee文件系统flags标志位》。

name

    文件名,其中文件长度COFFEE_NAME_LENGTH可配置,在contiki/cpu/平台(如arm/stm32f103)/cfs-coffee-arch.h。


三、file与file_header联系

3.1 联系

    file_header存放物理文件的元数据(即描述该物理文件),而file可以理解成物理文件元数据的内存表示,但又不是完全缓存,因为file与file_header成员变量差别甚大。为了提高性能,Contiki具体是这样做的:所有打开的文件都通过文件描述符fd(非负整数,类似于Linux)引用,将file_desc组织成一个数组file_desc coffee_fd_set[COFFEE_FD_SET_SIZE],每个fd对应于一个file_desc(以数组下标的形式),每个file_desc对应于一个file。通过数组file_desc coffee_fd_set[COFFEE_FD_SET_SIZE]下标(即文件描述符fd)就可以访问file,而file存储物理文件的一些信息,这样也就可以访问物理文件了。

3.2 page与log_page

    file_page是指向物理文件的第一页,即存放文件元数据file_header的页。而file_header->log_pages指向微日志的第一页(如果配置了微日志)。

3.3 file与file_header的flags

    file_header->flags记录的是整个物理文件的相关信息(即元数据),而file->flags只用来标识文件是否有微日志存在。详情请见博文《Contiki学习笔记:Coffee文件系统flags标志位》。

3.4 deprecated_eof_hint与end

    file_header->deprecated_eof_hint与file->end都存储文件的末尾的位置,但事实上,纵观源码,file_header->deprecated_eof_hint是没有用到的(这点与官方论文有出入),也就是说物理上没有存储文件的末尾位置,而是每次打开文件时,通过蛮力扫描,得到文件末尾位置,存入file->end。

3.5 record_count与log_records

    这两个关系,我也不是搞得很清楚。给我感觉就是,file_header->log_records是指文件创建时的指定的微日志记录数量,默认的情况会是COFFEE_LOG_SIZE/log_record_size(log_record_size默认情况会是COFFEE_PAGE_SIZE,见adjust_log_config函数)。而file->record_count是实际上的微日志记录数量。

阅读(3256) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~