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

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

文章分类

全部博文(124)

分类: 嵌入式

2011-12-23 16:16:39

摘要:

    本文深入源码分析了Coffee文件删除文件cfs_remove技术细节,包括remove_by_page、COFFEE_EXTENDED_WEAR_LEVELLING。


一、cfs_remove

    Coffee文件系统删除文件cfs_remove,删除成功返回0,否则返回-1。cfs_remove首先找到name对应的文件file指针(find_file函数),而后调用remove_by_page删除文件,源码如下:

  1. int cfs_remove(const char *name)
  2. {
  3.   struct file *file;

  4.   file = find_file(name);
  5.   if(file == NULL)
  6.   {
  7.     return - 1;
  8.   }

  9.   return remove_by_page(file->page, REMOVE_LOG, CLOSE_FDS, ALLOW_GC);
  10. }

    find_file函数用于找到文件名name对应的file指针。若name对应的文件file还驻留在内存(即还在coffee_files[COFFEE_MAX_OPEN_FILES]数组里),并且对应的物理文件是有效的,则直接返回file指针,否则扫描整个FLASH,将name对应文件file(在FLASH中但没缓存)缓存到内存(这一步得确保coffee_files数组有可用的项,否则返回空NULL,参见load_file函数)。详情见博文《Contiki学习笔记:Coffee文件系统打开文件cfs_open》二。这个有点纳闷了,删除文件,事先得把file_header缓存。


二、remove_by_page

    remove_by_page,删除微日志文件(如果有的话),将文件头file_header的flags中的O位(isolated,孤立)置1,更新file_header,将该文件关联的file_desc的flags设为COFFEE_FD_FREE和初始化file结构体,必要时(COFFEE_EXTENDED_WEAR_LEVELLING为0且gc_allowed为1)进行垃圾回收。

    值得一提的是,通过将文件头file_header的flags中的O位置1,虽表示文件已删除,但此时,文件占用的空间还不能被使用(还没擦写),只有垃圾回收处理后才能使用,而垃圾回收只有当存储空间不足时才执行。源码如下:

  1. //return remove_by_page(file->page, REMOVE_LOG, CLOSE_FDS, ALLOW_GC);
  2. static int remove_by_page(coffee_page_t page, int remove_log, int close_fds, int gc_allowed) //2.1
  3. {
  4.   struct file_header hdr;
  5.   int i;

  6.   read_header(&hdr, page);//read_header用于读取物理文件的元数据(即file_header)
  7.   if (!HDR_ACTIVE(hdr)) //若A为1,O为0,I为0,则HDR_ACTIVE返回真
  8.   {
  9.     return - 1;
  10.   }

  11.   /***删除微日志文件***/
  12.   if (remove_log && HDR_MODIFIED(hdr))
  13.   {
  14.     if (remove_by_page(hdr.log_page, !REMOVE_LOG, !CLOSE_FDS, !ALLOW_GC) < 0)
  15.     {
  16.       return - 1;
  17.     }
  18.   }

  19.   hdr.flags |= HDR_FLAG_OBSOLETE; //标志为失效页
  20.   write_header(&hdr, page); //更新物理的file_header
  21.   *gc_wait = 0;

  22.   /***将待删除文件相关联的file_desc中flags设为COFFEE_FD_FREE(一个文件可能被多次打开,如多线程)***/
  23.   if (close_fds)
  24.   {
  25.     for (i = 0; i < COFFEE_FD_SET_SIZE; i++)
  26.     {
  27.       if (coffee_fd_set[i].file != NULL && coffee_fd_set[i].file->page == page)
  28.       {
  29.         coffee_fd_set[i].flags = COFFEE_FD_FREE;
  30.       }
  31.     }
  32.   }

  33.   /***将待删除文件相关联的file初始化,变为可用***/
  34.   for (i = 0; i < COFFEE_MAX_OPEN_FILES; i++)
  35.   {
  36.     if (coffee_files[i].page == page)
  37.     {
  38.       coffee_files[i].page = INVALID_PAGE;
  39.       coffee_files[i].references = 0;
  40.       coffee_files[i].max_pages = 0;
  41.     }
  42.   }

  43.   /***没有配置COFFEE_EXTENDED_WEAR_LEVELLING且gc_allowed为1,则进行垃圾回收,见2.2***/
  44.   #if !COFFEE_EXTENDED_WEAR_LEVELLING
  45.     if (gc_allowed)
  46.     {
  47.       collect_garbage(GC_RELUCTANT);
  48.     }
  49.   #endif

  50.   return 0; //邮件成功返回0
  51. }

2.1 remove_by_page参数

    删除文件cfs_remove传给remove_by_page参数分别是file->page、REMOVE_LOG、CLOSE_FDS、ALLOW_GC,如下:

  1. //return remove_by_page(file->page, REMOVE_LOG, CLOSE_FDS, ALLOW_GC);

  2. #define REMOVE_LOG 1  //删除微日志文件
  3. #define CLOSE_FDS  1  //关闭FD,事实上是将file_desc的flags设为COFFEE_FD_FREE
  4. #define ALLOW_GC   1  //允许垃圾回收,得确保COFFEE_EXTENDED_WEAR_LEVELLING为0,才会进行垃圾回收

2.2 COFFEE_EXTENDED_WEAR_LEVELLING

    Coffee文件系统默认是配置了COFFEE_EXTENDED_WEAR_LEVELLING,源码如下。在本例,文件删除并没有立即进行垃圾回收,而是待到没有空间可用的时候再回收(可理解成批处理),显然这样做有一个明显的缺点,垃圾回收会占用比较长的时间。

  1. #ifndef COFFEE_EXTENDED_WEAR_LEVELLING
  2.   #define COFFEE_EXTENDED_WEAR_LEVELLING 1
  3. #endif

    系统提供了两种垃圾回收机制:GC_GREEDY和GC_RELUCTANT,前者垃圾回收过程中,擦除尽可能多的区(即贪心回收),后者擦除一个区后就停止,删除文件采用的是后一种。两种回收机制源代码如下:

  1. /* "Greedy" garbage collection erases as many sectors as possible. */
  2. #define GC_GREEDY 0
  3. /* "Reluctant" garbage collection stops after erasing one sector. */
  4. #define GC_RELUCTANT 1


参考资料:

[1] Tsiftes Nicolas,Dunkels Adam,He Zhitao.Enabling large-scale storage in sensor networks with the coffee file system[J].International Conference on Information Processing in Sensor Networks.2009,349-360

[2]

[3] Contiki源代码

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