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

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

文章分类

全部博文(124)

分类: 嵌入式

2011-12-24 18:27:58

摘要:

    Coffee文件系统多处地方出现flags,包括file_header->flags、file_desc->flags、file_desc->io_flags、file->flags,含义不相同,本文整理这些flags。


一、cfs_open的flags

    Coffee打开文件cfs_open函数需要指定flags,flags可以取CFS_READ、CFS_WRITE、CFS_APPEND之一或者组合,宏定义如下:

  1. //int cfs_open(const char *name, int flags)
  2. #define CFS_READ 1
  3. #define CFS_WRITE 2
  4. #define CFS_APPEND 4

    CFS_READ、CFS_WRITE、CFS_APPEND正好对应于COFFEE_FD_READ、COFFEE_FD_WRITE、COFFEE_FD_APPEND。纵观源代码,后3个都没用到,而是用前3个代替,看以下cfs_open函数语句就懂了:

  1. //int cfs_open(const char *name, int flags)
  2. fdp->flags |= flags;


二、file_desc->flags

    file_desc->flags存储文件访问权限,系统定义了四个值:COFFEE_FD_FREE、COFFEE_FD_READ、FFEE_FD_WRITE、COFFEE_FD_APPEND,源代码如下:

  1. #define COFFEE_FD_FREE 0x0
  2. #define COFFEE_FD_READ 0x1
  3. #define COFFEE_FD_WRITE 0x2
  4. #define COFFEE_FD_APPEND 0x4

    事实上,后3个都没用到,而是用CFS_READ、CFS_WRITE、CFS_APPEND代替。系统缓存file_desc组织成一个数组coffee_fd_set[COFFEE_FD_SET_SIZE],当coffee_fd_set[i]->flags为COFFEE_FD_FREE,表示该FD可使用。


三、file->flags

    file的flags只有两种取值:0和COFFEE_FILE_MODIFIED,将物理文件缓存时(load_file函数,详情见博文《Contiki学习笔记:Coffee文件系统打开文件cfs_open》2.5),如果物理文件元数据file_header的flags的M位为1的话(即物理文件被修改,日志存在),则file->flags设为COFFEE_FILE_MODIFIED,否则设为0。部分代码如下:

  1. //load_file函数部分代码

  2. file->flags = 0;
  3. if(HDR_MODIFIED(*hdr))
  4. {
  5.   file->flags |= COFFEE_FILE_MODIFIED; //如果文件被修改(表示日志存在),#define COFFEE_FILE_MODIFIED 0x1
  6. }

再看下面的代码就很清楚了,如果file->flags为COFFEE_FILE_MODIFIED,返回真。

  1. #define FILE_MODIFIED(file) ((file)->flags & COFFEE_FILE_MODIFIED)

  2. #define COFFEE_FILE_MODIFIED 0x1


四、file_desc->io_flags

4.1 COFFEE_IO_SEMANTICS

如果定义了COFFEE_IO_SEMANTICS,则在file_desc结构体会多一个成员变量io_flags,源码如下:

  1. struct file_desc
  2. {
  3.   cfs_offset_t offset;
  4.   struct file *file;
  5.   uint8_t flags;
  6.   #if COFFEE_IO_SEMANTICS
  7.     uint8_t io_flags;
  8.   #endif
  9. };

    配置了COFFEE_IO_SEMANTICS可以优化某些存储设备的文件访问(optimize file access on certain storage types),系统默认没有配置COFFEE_IO_SEMANTICS,源码如下:

4.2 file_desc->io_flags

    系统定义了io_flags两个值,即CFS_COFFEE_IO_FLASH_AWARE和CFS_COFFEE_IO_FIRM_SIZE。

(1)CFS_COFFEE_IO_FLASH_AWARE

  1. /*Instruct Coffee that the access pattern to this file is adapted to flash I/O semantics by design, and Coffee should therefore not invoke its own micro logs when file modifications occur.This semantical I/O setting is useful when implementing flash storage algorithms on top of Coffee. */

  2. #define CFS_COFFEE_IO_FLASH_AWARE 0x1

CFS_COFFEE_IO_FLASH_AWARE没看懂,需要阅读更多代码,后续补充。

(2)CFS_COFFEE_IO_FIRM_SIZE

  1. /* A case when this is necessary is when the file has a firm size limit,and a safeguard is needed to protect against writes beyond this limit. */

  2. #define CFS_COFFEE_IO_FIRM_SIZE 0x2

    如果写入文件超过预留的大小,Coffee不会继续扩展文件。当文件有固定大小限制时,设置CFS_COFFEE_IO_FIRM_SIZE可以保护写超过。

    file_desc的io_flags可以通过cfs_coffee_set_io_semantics()函数来设置,源码如下,其中法flag是CFS_COFFEE_IO_FLASH_AWARE和CFS_COFFEE_IO_FIRM_SIZE两者之一或全部。源码如下:

  1. #if COFFEE_IO_SEMANTICS
  2.   int cfs_coffee_set_io_semantics(int fd, unsigned flags)
  3.   {
  4.     if(!FD_VALID(fd))
  5.     {
  6.       return - 1;
  7.     }

  8.     coffee_fd_set[fd].io_flags |= flags;

  9.     return 0;
  10.   }
  11. #endif


五、file_header->flags

    file_header的flags反应了物理文件的状态,用了6位,分别是ALOMIV。但官方论文[1]与实际源码各位的位置不同,不过不影响分析,忠于源码就是了。file_header的flags两种版本示意图如下:

图1 file_header的flags两种版本


A(allocated)

    如果该位被设置,表示文件正在使用。反之,当前页及所有保留页(直到下一个逻辑区的边界)是空闲的。

O(obsolete)

    当文件被删除时,O标记保留页是无效的(obsolete)[2]。不是吧,这些页不用擦除就可以直接使用的,怎么说也应该标记成空闲free?

M(modified)

    资料[1][2]居然没提这个标志,得根据源代码推测了:-( 在cfs-coffee.c的flags宏定义可得知,M表示文件已被修改,日志存在(Modified file, log exists)。

L(log)

    L(log)标记文件已被修改,与微日志文件存在有关(and that a related log file exists)。不同于M,应该是指微日志的修改标志(待读源码确认)。

I(isolated)

    I标记孤立的页,所有Coffee算法每次都会处理孤立的页面(Isolated pages are processed one at a time by all Coffee algorithms, and are treated the same way as obsolete files)

V(valid)

    V(valid)标记文件头是完整的(helps by marking that the header data is complete),To discover garbled headers-typically caused by a system reboot during a header write operation。

    注:这6个标志是有优先顺序的,依次是the valid flag(V)、the isolated flag(I), the obsolete flag(O),、the log flag(L)、the allocated flag(A)。(不晓得M该处于哪个位置)

为方便操作,Coffee将这些flags单独定义成宏,源代码如下(在cfs-coffee.c文件):

  1. /* File header flags. */ 
  2. #define HDR_FLAG_VALID  0x1 /* Completely written header. */ 
  3. #define HDR_FLAG_ALLOCATED  0x2 /* Allocated file. */ 
  4. #define HDR_FLAG_OBSOLETE  0x4 /* File marked for GC. */ 
  5. #define HDR_FLAG_MODIFIED  0x8 /* Modified file, log exists. */ 
  6. #define HDR_FLAG_LOG  0x10 /* Log file. */ 
  7. #define HDR_FLAG_ISOLATED 0x20 /* Isolated page. */

Coffee定义了若干宏来判断文件的状态(依据file_header中的flags),如下:

  1. /* File header macros. */ 
  2. #define CHECK_FLAG(hdr, flag) ((hdr).flags & (flag))

  3. #define HDR_VALID(hdr) CHECK_FLAG(hdr, HDR_FLAG_VALID)  //若V标志置1,则返回真 
  4. #define HDR_ALLOCATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ALLOCATED) //若A标志置1,则返回真
  5. #define HDR_OBSOLETE(hdr) CHECK_FLAG(hdr, HDR_FLAG_OBSOLETE) //若O标志置1,则返回真
  6. #define HDR_MODIFIED(hdr) CHECK_FLAG(hdr, HDR_FLAG_MODIFIED) //若M标志置1,则返回真
  7. #define HDR_LOG(hdr) CHECK_FLAG(hdr, HDR_FLAG_LOG) //若L标志置1,则返回真 
  8. #define HDR_ISOLATED(hdr) CHECK_FLAG(hdr, HDR_FLAG_ISOLATED) //若I标志置1,则返回真 

  9. #define HDR_FREE(hdr) !HDR_ALLOCATED(hdr) //若A标志置0,则返回真
  10. #define HDR_ACTIVE(hdr) (HDR_ALLOCATED(hdr) && !HDR_OBSOLETE(hdr) && !HDR_ISOLATED(hdr))//若A为1,O为0,I为0,则返回真


    有个疑问,在Coffee格式化cfs_coffee_format中,将所有的逻辑区全部擦除,即file_header各成员变量填充为1,所以file_header的flags各位都是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] Contiki源代码

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