UBIFS文件系统

引言

什么是UBIFS文件系统

UBIFS是UBI file system的简称,用于裸的flash设备,作为jffs2的后继文件系统之一。UBIFS通过UBI子系统处理与MTD设备之间动作。UBIFS文件系统更适合MLCNAND FLASH。需要注意的是UBIFS并不是为SSD,MMC,SD,Compact Flash等之类的基于flash的存储设备,其是针对于裸flash设备。

         裸flash有以下特点:

l  其包含的块被称为可擦除块,而对于SSD这类的设备,并无可擦除块的概念,取而代之的是扇区的概念。

l  包括读、写、擦除可擦除块三种操作。

l  硬件并不管理坏的可擦除块,而SSD之类的设备则具有专门的控制器处理坏块。

l  可擦除块的读写寿命从几千到几十万之间不等。

图0.1中给出的设备是MMC、SD类型的,该设备具有flash转换层的硬件控制器,该硬件控制器的损耗平衡算法属于商业秘密,华为的dorado 系列高端存储器的文档对其损耗平衡(动态和静态)原理讲解的非常透彻,感兴趣的可以自己找找。对于UBIFS使用的场景,通常只有NANDFLASH那一个模块,其和控制器的接口通常是专门的NAND flash接口。由于这类设备的速率比较慢,所以通常用在相对而言比较低端的嵌入式设备,追求加载速度快一点嵌入式设备通常会选择使用emmc存储器,其文件系统通常会选择UFS。

图0.1 具有flash转换层的设备

UBI/UBIFS 协议栈

图0.2 UBIFS实现的协议栈

MTD(Memory Technology Devices)对闪存存储器提供了一个抽象,隐藏了特定flash的独特之处,提供统一的API存取各种类型的flash。

MTD在内核层的API是struct mtd_device而用户空间的API接口是/dev/mtd0,这些接口提供了设备信息,读写可擦除块,擦除一个可擦除块,标记一个可擦除块是坏块,检查可擦除块是否是坏块。MTD的API并不隐藏坏的可擦除块也不做任何损耗平衡。

UBI(Unsorted Block Images)的内核API是include/mtd/ubi-user.h,用户空间的则是/dev/ubi0,提供损耗平衡,隐藏坏块,允许运行时容量创建、删除和修改,有点类似LVM功能。UBI线性扩展,在初始化时会读取所有的可擦除块头,所以当flash容量越大,初始化所花费的时间越多,但是就可扩展性而言比JFFS2要好很多。

LEB(logic eraseblock),PEB(physical erase block);将LEB映射到PEB,任何一个LEB可能映射到任何一个PEB,可擦除块头存储的是映射信息以及擦除计数值。

图0.3 UBI基本思想

UBI坏的可擦除块处理:

l  为坏的可擦除块预留1%的PEB

l  如果一个PEB变成坏块,则相应的LEB会被映射到一个好的PEB中

l  I/O错处处理对上层并未隐藏。

写错误处理

假设用户写数据到LEB0可擦除块,选择一个好的PEB可擦除块(这里假设选择PEB4)来恢复数据,恢复数据实际上就是将数据拷贝到PEB4,然后重新映射LEB0到PEB4,映射完毕后将新数据再次写入PEB4,这是恢复就完成了,将回到UBI层,后台会将PEB1标记为坏块。

图0.4 写错误处理示例

原子改变LEB

这对UBIFS非常重要,假设LEB0需要被原子改变,这一过程是这样的:

         首先选择一个合适的PEB块,加入这里选择了PEB0,然后向这个块写入新数据,写入完成后需要将原始映射PEB4解映射同时将LEB0映射到PEB0,这是就完成了原子更新操作返回UBI层,但是PEB4的数据会被后台擦除。

图0.5 原子改变LEB

对UBI底层的操作有了一些了解后,可以开始UBIFS的介绍了,首先UBIFS并不关系可擦除坏块了,这一信息依赖于UBI层,损耗平衡依赖于UBI层而不是UBIFS,LEB的更改是原子性的。

         UBIFS文件索引

索引允许查找任何数据片段的物理地址。索引采用B+2的结构,图中右上半部分,只有叶子节点包含数据,数的扇出可配,缺省值是8。UBIFS的索引在flash上存储和维护。


图0.6 UBIFS索引

UBIFS日志

日志比较小,为节省功耗只扫描日志并不扫描flash所有数据,这一结果会让挂载很快完成。文件系统所有更改将被日志记录,索引信息只在内存修改,并不在flash上修改。

         主节点存在于LEB1和LEB2,这两个块存储的是一样的,用于备份恢复之用,主节点指向根索引,主分区在挂载时可以很快被找到。


图0.7 索引和UBIFS的关系

超级块

超级块存储在LEB0位置处,对于UBIFS文件系统只读,但是可以被用户空间工具修改,存储如索引树扇出等一些配置信息,缺省使用zlib或者LZO进行压缩,在挂载该文件系统时,UBIFS的mount方法将被调用读取该超级块。

树节点缓存(TreeNode Cache)

         为了加速文件的操作,每次更新flash上的索引树的速率较慢,所以在内存中建立树节点缓存以加快索引树查找。

垃圾回收

有一个空的LEB专门为垃圾回收保留。垃圾回收的一个例子如下:

首先选择一个脏LEB,比如LEB1被选中,然后将其有效数据拷贝的到LEB5,LEB1这时就可以被擦除了,然后再选择一个脏LEB区,如LEB6,同样将数据拷贝到LEB5,拷贝完成后LEB6上的原有数据可能被擦除掉,LEB1将未垃圾回收预留,LEB6这时处于可用状态。索引处理方法,只是将Tree Node Cache的索引节点标记为脏。这样垃圾回收完成。但是还进行一个确认操作,确认操作肯定是可以完成的,会为索引预留至少3倍的空闲空间。

图0.8 垃圾回收原理

LPT(LEB Properites Tree)

         是一个B+树,但是大小固定,比主索引树小很多,管理方法类似于主索引树。

UBIFS初始化

UBIFS的文件系统需要编译的文件如下fs/ubifs/Makefile ,最后会编译成ubifs.o这个文件,链接时会将该文件链接到镜像文件中去。

Shrinker是动态调整树大小的。Journal是UBIFS的日志功能实现的文件,file、dir、super、sb以及io是文件、目录、超级块以及io操作实现;

Tnc(tree nodecache)模块,commit是在垃圾回收确认会用到的操作。gc是垃圾回收实现源码。


为了知道该模块的注册过程,首先查找相关的init函数。


         透过上面的两个查找可以知道,UBIFS子系统在加载时会首先执行ubifs_init函数,这很late_initcall在《Linux系统启动那些事—基于Linux 3.10内核》一文提到过其调用的时机,在系统启动时会被调用。

[cpp]  view plain  copy
  1. Super.c  
  2.     static int __init ubifs_init(void)  
  3. {  
  4. 首先申请一个slab分配器,关于slab见《内存管理-之内核内存管理-基于linux3.10》  
  5.     ubifs_inode_slab = kmem_cache_create("ubifs_inode_slab",  
  6.                 sizeof(struct ubifs_inode), 0,  
  7.                 SLAB_MEM_SPREAD | SLAB_RECLAIM_ACCOUNT,  
  8.                 &inode_slab_ctor);  
  9. //将ubifs_shrinker(定义于shrinker.c文件)注册到VM子系统,在cache压力较大时,将会缩小TNC(tree node cache)。  
  10. register_shrinker(&ubifs_shrinker_info);  
  11. //UBIFS文件系统支持两种压缩格式lzo和zlib,该函数定义于compress.c文件,两种压缩格式在编译时根据宏选定。  
  12.     err = ubifs_compressors_init();  
  13. //注册该文件系统,这个过程见《虚拟文件系统 (VFS)-基于linux3.10》,这里比较感兴趣的是ubifs_fs_type  
  14.     err = register_filesystem(&ubifs_fs_type);  
  15. }  

mount方法才是最感兴趣的,在《虚拟文件系统 (VFS)-基于linux3.10》里提到文件系统挂载时会调用具体的文件系统的mount方法,这里就来看看它的mount方法。

[cpp]  view plain  copy
  1. <super.c>  
  2. static struct file_system_type ubifs_fs_type = {  
  3.     .name    = "ubifs",  
  4.     .owner   = THIS_MODULE,  
  5.     .mount   = ubifs_mount,  
  6.     .kill_sb = kill_ubifs_super,  
  7. };  

Mount的函数虽然很重要,但是并没有想象中那么复杂,逻辑结构相对比较明晰。该函数首先调用open_ubi打开一个UBI设备,之所以以只读方式打开是因为这也许是一个新的挂载点,UBI同一时刻只允许有一个读写者。alloc_ubifs_info为描述UBIFS文件系统的结构体struct ubifs_info申请内存,并且初始化自旋锁、互斥锁、链表、树节点等操作。Sget首先在该文件系统中查找超级块,如果没有找到则调用alloc_super创建一个超级块,并初始化超级块的相关成员,该函数并未定义于ubifs文件目录内。然后调用ubifs_fill_super对超级块进行填充,填充的信息源于LEB0,这涉及到UBI和MTD层。由于fill_super()函数在一次打开了UBI,所以这里调用ubi_close_volume将其关闭。最后调用dget返回目录项。

图1.1 UBIFS挂载过程

假设挂载形式如《虚拟文件系统 (VFS)-基于linux3.10》提到的,如:

[cpp]  view plain  copy
  1. mount   –t     ubifs               /dev/ubi4_0                         /config  

则open_ubi调用ubi_open_volume_path(“/dev/ubi4_0”,UBI_READONLY)查找UBI卷描述符。

[cpp]  view plain  copy
  1. struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)  
  2. {  
  3. //该函数分析见《虚拟文件系统 (VFS)-基于linux3.10》  
  4.     error = kern_path(pathname, LOOKUP_FOLLOW, &path);  
  5.   
  6.     inode = path.dentry->d_inode;  
  7.     mod = inode->i_mode;  
  8. //获得主次设备号  
  9.     ubi_num = ubi_major2num(imajor(inode));  
  10.     vol_id = iminor(inode) - 1;  
  11.     path_put(&path);  
  12.   
  13. UBI卷描述符的获取  
  14.     if (vol_id >= 0 && ubi_num >= 0)  
  15.         return ubi_open_volume(ubi_num, vol_id, mode);  
  16. }  

ubi_open_volume获取UBI卷描述符,主要依赖前两个参数,第一个参数是UBI主设备号对应的数字,而第二个参数是UBI次设备号对应的数字。由主设备号索引到ubi设备,ubi_devices是一个局部全局的描述ubi设备的数组。

[cpp]  view plain  copy
  1. struct ubi_device *ubi;  
  2. ubi = ubi_devices[ubi_num];  

根据ubi设备信息找到UBI卷:

[cpp]  view plain  copy
  1. vol = ubi->volumes[vol_id];  

alloc_ubifs_info主要功能就是slab分配内存,不多解释,有兴趣见《内存管理-之内核内存管理-基于linux3.10》。

sget用于查找并创建超级块

[cpp]  view plain  copy
  1. struct super_block *sget(struct file_system_type *type,  
  2.             int (*test)(struct super_block *,void *),  
  3.             int (*set)(struct super_block *,void *),  
  4.             int flags,  
  5.             void *data)  
  6. {  
  7.     struct super_block *s = NULL;  
  8.     struct super_block *old;  
  9.     int err;  
  10.   
  11. retry:  
  12.     spin_lock(&sb_lock); //获得超级块锁  
  13. //这个if语句就是在现有的文件系统中查找超级块是否存在  
  14.     if (test) { //这个函数在存在,实际上就是sb_test函数。  
  15.         hlist_for_each_entry(old, &type->fs_supers, s_instances) {  
  16.             if (!test(old, data))  
  17.                 continue;  
  18.             if (!grab_super(old))  
  19.                 goto retry;  
  20.             if (s) {  
  21.                 up_write(&s->s_umount);  
  22.                 destroy_super(s);  
  23.                 s = NULL;  
  24.             }  
  25.             down_write(&old->s_umount);  
  26.             if (unlikely(!(old->s_flags & MS_BORN))) {  
  27.                 deactivate_locked_super(old);  
  28.                 goto retry;  
  29.             }  
  30.             return old;  
  31.         }  
  32.     }  
  33. //如果s == null,则说明上面在ubifs文件系统中没有找到,则需要创建超级块,这里申请内存。  
  34.     if (!s) {  
  35.         spin_unlock(&sb_lock);  
  36.         s = alloc_super(type, flags);  
  37.         if (!s)  
  38.             return ERR_PTR(-ENOMEM);  
  39.         goto retry;  
  40.     }  
  41. //调用set方法,为超级块设置一些内容。  
  42.     err = set(s, data);  
  43.     if (err) {  
  44.         spin_unlock(&sb_lock);  
  45.         up_write(&s->s_umount);  
  46.         destroy_super(s);  
  47.         return ERR_PTR(err);  
  48.     }  
  49. //对超级块的一些其它字段的初始化。  
  50.     s->s_type = type;  
  51.     strlcpy(s->s_id, type->name, sizeof(s->s_id));  
  52.     list_add_tail(&s->s_list, &super_blocks);  
  53.     hlist_add_head(&s->s_instances, &type->fs_supers);  
  54.     spin_unlock(&sb_lock);  
  55.     get_filesystem(type);  
  56.     register_shrinker(&s->s_shrink);  
  57.     return s;  
  58. }  

如果sb->s_root为null,则说明还没挂载,该超级块的内容需要从flash上读取。这个任务有ubifs_fill_super实现。

该函数的原型如下:

[cpp]  view plain  copy
  1. static int ubifs_fill_super(struct super_block *sb, void *data, int silent)  
  2. sb参数是先前创建的超级块,首先将超级块描述ubifs信息的字段单独取出来  
  3.     struct ubifs_info *c = sb->s_fs_info;  
  4.   
  5.     c->vfs_sb = sb;  
  6.     这里重新打开改UBI设备,注意权限编程的读写,这意味着需要从该设备读写数据了。  
  7.     c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READWRITE);  
  8.   
  9. 初始化相关字段,bdi是backing_dev_info简写,其功能是禁止预读,不需要改功能。  
  10.     c->bdi.name = "ubifs",  
  11.     c->bdi.capabilities = BDI_CAP_MAP_COPY;  
  12.     err  = bdi_init(&c->bdi);  
  13.     err = bdi_register(&c->bdi, NULL, "ubifs_%d_%d",  
  14.                c->vi.ubi_num, c->vi.vol_id);  
  15.   
  16.     err = ubifs_parse_options(c, data, 0);  
  17.     if (err)  
  18.         goto out_bdi;  
  19. //超级块信息初始化  
  20.     sb->s_bdi = &c->bdi;  
  21.     sb->s_fs_info = c;  
  22.     sb->s_magic = UBIFS_SUPER_MAGIC;  
  23.     sb->s_blocksize = UBIFS_BLOCK_SIZE;  
  24.     sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT;  
  25.     sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c);  
  26.     if (c->max_inode_sz > MAX_LFS_FILESIZE)  
  27.         sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;  
  28.     sb->s_op = &ubifs_super_operations;  
  29.   
  30.     mutex_lock(&c->umount_mutex);  
  31. //挂载ubifs文件系统。并调用ubifs_read_superblock读取超级块,使能日志功能等  
  32.     err = mount_ubifs(c);  
  33.       
  34.     /*读取根索引节点*/  
  35.     root = ubifs_iget(sb, UBIFS_ROOT_INO);  
  36. 将超级块和根索引节点关联  
  37.     sb->s_root = d_make_root(root);  


UBIFS文件系统的读写实际上就是UBI层到MTD层的一个过程,其读代码的执行流程如下,

由于在这篇文章里并不分析UBI和MTD层,所以这里只列出散布在UBIFS文件目录里的各个函数接口,其功能和关键实现代码在后续文章中再剖析。

UBIFS接口函数集

Makefile中显示的各个编译后目标的文件提供的函数接口如下:

[cpp]  view plain  copy
  1. /* io.c */  
  2. void ubifs_ro_mode(struct ubifs_info *c, int err);  
  3. int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,  
  4.            int len, int even_ebadmsg);  
  5. int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,  
  6.             int len);  
  7. int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len);  
  8. int ubifs_leb_unmap(struct ubifs_info *c, int lnum);  
  9. int ubifs_leb_map(struct ubifs_info *c, int lnum);  
  10. int ubifs_is_mapped(const struct ubifs_info *c, int lnum);  
  11. int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);  
  12. int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs);  
  13. int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf);  
  14. int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,  
  15.             int lnum, int offs);  
  16. int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,  
  17.              int lnum, int offs);  
  18. int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum,  
  19.              int offs);  
  20. int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,  
  21.              int offs, int quiet, int must_chk_crc);  
  22. void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);  
  23. void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last);  
  24. int ubifs_io_init(struct ubifs_info *c);  
  25. void ubifs_pad(const struct ubifs_info *c, void *buf, int pad);  
  26. int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf);  
  27. int ubifs_bg_wbufs_sync(struct ubifs_info *c);  
  28. void ubifs_wbuf_add_ino_nolock(struct ubifs_wbuf *wbuf, ino_t inum);  
  29. int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode);  


[cpp]  view plain  copy
  1. /* scan.c */  
  2. struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,  
  3.                   int offs, void *sbuf, int quiet);  
  4. void ubifs_scan_destroy(struct ubifs_scan_leb *sleb);  
  5. int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,  
  6.               int offs, int quiet);  
  7. struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,  
  8.                     int offs, void *sbuf);  
  9. void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,  
  10.             int lnum, int offs);  
  11. int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb,  
  12.            void *buf, int offs);  
  13. void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,  
  14.                   void *buf);  

[cpp]  view plain  copy
  1. /* log.c */  
  2. void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud);  
  3. void ubifs_create_buds_lists(struct ubifs_info *c);  
  4. int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs);  
  5. struct ubifs_bud *ubifs_search_bud(struct ubifs_info *c, int lnum);  
  6. struct ubifs_wbuf *ubifs_get_wbuf(struct ubifs_info *c, int lnum);  
  7. int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum);  
  8. int ubifs_log_end_commit(struct ubifs_info *c, int new_ltail_lnum);  
  9. int ubifs_log_post_commit(struct ubifs_info *c, int old_ltail_lnum);  
  10. int ubifs_consolidate_log(struct ubifs_info *c);  

[cpp]  view plain  copy
  1. /* journal.c */  
  2. int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,  
  3.              const struct qstr *nm, const struct inode *inode,  
  4.              int deletion, int xent);  
  5. int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode,  
  6.              const union ubifs_key *key, const void *buf, int len);  
  7. int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode);  
  8. int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode);  
  9. int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir,  
  10.              const struct dentry *old_dentry,  
  11.              const struct inode *new_dir,  
  12.              const struct dentry *new_dentry, int sync);  
  13. int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode,  
  14.                loff_t old_size, loff_t new_size);  
  15. int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host,  
  16.                const struct inode *inode, const struct qstr *nm);  
  17. int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode1,  
  18.                const struct inode *inode2);  



[cpp]  view plain  copy
  1. /* budget.c */  
  2. int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req);  
  3. void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req);  
  4. void ubifs_release_dirty_inode_budget(struct ubifs_info *c,  
  5.                       struct ubifs_inode *ui);  
  6. int ubifs_budget_inode_op(struct ubifs_info *c, struct inode *inode,  
  7.               struct ubifs_budget_req *req);  
  8. void ubifs_release_ino_dirty(struct ubifs_info *c, struct inode *inode,  
  9.                 struct ubifs_budget_req *req);  
  10. void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,  
  11.              struct ubifs_budget_req *req);  
  12. long long ubifs_get_free_space(struct ubifs_info *c);  
  13. long long ubifs_get_free_space_nolock(struct ubifs_info *c);  
  14. int ubifs_calc_min_idx_lebs(struct ubifs_info *c);  
  15. void ubifs_convert_page_budget(struct ubifs_info *c);  
  16. long long ubifs_reported_space(const struct ubifs_info *c, long long free);  
  17. long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);  



[cpp]  view plain  copy
  1. /* find.c */  
  2. int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *offs,  
  3.               int squeeze);  
  4. int ubifs_find_free_leb_for_idx(struct ubifs_info *c);  
  5. int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,  
  6.              int min_space, int pick_free);  
  7. int ubifs_find_dirty_idx_leb(struct ubifs_info *c);  
  8. int ubifs_save_dirty_idx_lnums(struct ubifs_info *c);  



[cpp]  view plain  copy
  1. /* tnc.c */  
  2. int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,  
  3.             struct ubifs_znode **zn, int *n);  
  4. int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,  
  5.             void *node, const struct qstr *nm);  
  6. int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,  
  7.              void *node, int *lnum, int *offs);  
  8. int ubifs_tnc_add(struct ubifs_info *c, const union ubifs_key *key, int lnum,  
  9.           int offs, int len);  
  10. int ubifs_tnc_replace(struct ubifs_info *c, const union ubifs_key *key,  
  11.               int old_lnum, int old_offs, int lnum, int offs, int len);  
  12. int ubifs_tnc_add_nm(struct ubifs_info *c, const union ubifs_key *key,  
  13.              int lnum, int offs, int len, const struct qstr *nm);  
  14. int ubifs_tnc_remove(struct ubifs_info *c, const union ubifs_key *key);  
  15. int ubifs_tnc_remove_nm(struct ubifs_info *c, const union ubifs_key *key,  
  16.             const struct qstr *nm);  
  17. int ubifs_tnc_remove_range(struct ubifs_info *c, union ubifs_key *from_key,  
  18.                union ubifs_key *to_key);  
  19. int ubifs_tnc_remove_ino(struct ubifs_info *c, ino_t inum);  
  20. struct ubifs_dent_node *ubifs_tnc_next_ent(struct ubifs_info *c,  
  21.                        union ubifs_key *key,  
  22.                        const struct qstr *nm);  
  23. void ubifs_tnc_close(struct ubifs_info *c);  
  24. int ubifs_tnc_has_node(struct ubifs_info *c, union ubifs_key *key, int level,  
  25.                int lnum, int offs, int is_idx);  
  26. int ubifs_dirty_idx_node(struct ubifs_info *c, union ubifs_key *key, int level,  
  27.              int lnum, int offs);  
  28. /* Shared by tnc.c for tnc_commit.c */  
  29. void destroy_old_idx(struct ubifs_info *c);  
  30. int is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level,  
  31.                int lnum, int offs);  
  32. int insert_old_idx_znode(struct ubifs_info *c, struct ubifs_znode *znode);  
  33. int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu);  
  34. int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu);  


[cpp]  view plain  copy
  1. /* tnc_misc.c */  
  2. struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,  
  3.                           struct ubifs_znode *znode);  
  4. int ubifs_search_zbranch(const struct ubifs_info *c,  
  5.              const struct ubifs_znode *znode,  
  6.              const union ubifs_key *key, int *n);  
  7. struct ubifs_znode *ubifs_tnc_postorder_first(struct ubifs_znode *znode);  
  8. struct ubifs_znode *ubifs_tnc_postorder_next(struct ubifs_znode *znode);  
  9. long ubifs_destroy_tnc_subtree(struct ubifs_znode *zr);  
  10. struct ubifs_znode *ubifs_load_znode(struct ubifs_info *c,  
  11.                      struct ubifs_zbranch *zbr,  
  12.                      struct ubifs_znode *parent, int iip);  
  13. int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,  
  14.             void *node);  

[cpp]  view plain  copy
  1. /* tnc_commit.c */  
  2. int ubifs_tnc_start_commit(struct ubifs_info *c, struct ubifs_zbranch *zroot);  
  3. int ubifs_tnc_end_commit(struct ubifs_info *c);  
  4.   
  5. /* shrinker.c */  
  6. int ubifs_shrinker(struct shrinker *shrink, struct shrink_control *sc);  
  7.   
  8. /* commit.c */  
  9. int ubifs_bg_thread(void *info);  
  10. void ubifs_commit_required(struct ubifs_info *c);  
  11. void ubifs_request_bg_commit(struct ubifs_info *c);  
  12. int ubifs_run_commit(struct ubifs_info *c);  
  13. void ubifs_recovery_commit(struct ubifs_info *c);  
  14. int ubifs_gc_should_commit(struct ubifs_info *c);  
  15. void ubifs_wait_for_commit(struct ubifs_info *c);  
  16.   
  17. /* master.c */  
  18. int ubifs_read_master(struct ubifs_info *c);  
  19. int ubifs_write_master(struct ubifs_info *c);  
  20.   
  21. /* sb.c */  
  22. int ubifs_read_superblock(struct ubifs_info *c);  
  23. struct ubifs_sb_node *ubifs_read_sb_node(struct ubifs_info *c);  
  24. int ubifs_write_sb_node(struct ubifs_info *c, struct ubifs_sb_node *sup);  
  25. int ubifs_fixup_free_space(struct ubifs_info *c);  
  26.   
  27. /* replay.c */  
  28. int ubifs_validate_entry(struct ubifs_info *c,  
  29.              const struct ubifs_dent_node *dent);  
  30. int ubifs_replay_journal(struct ubifs_info *c);  
  31.   
  32. /* gc.c */  
  33. int ubifs_garbage_collect(struct ubifs_info *c, int anyway);  
  34. int ubifs_gc_start_commit(struct ubifs_info *c);  
  35. int ubifs_gc_end_commit(struct ubifs_info *c);  
  36. void ubifs_destroy_idx_gc(struct ubifs_info *c);  
  37. int ubifs_get_idx_gc_leb(struct ubifs_info *c);  
  38. int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp);  
  39.   
  40. /* orphan.c */  
  41. int ubifs_add_orphan(struct ubifs_info *c, ino_t inum);  
  42. void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum);  
  43. int ubifs_orphan_start_commit(struct ubifs_info *c);  
  44. int ubifs_orphan_end_commit(struct ubifs_info *c);  
  45. int ubifs_mount_orphans(struct ubifs_info *c, int unclean, int read_only);  
  46. int ubifs_clear_orphans(struct ubifs_info *c);  

[cpp]  view plain  copy
  1. /* lpt.c */  
  2. int ubifs_calc_lpt_geom(struct ubifs_info *c);  
  3. int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,  
  4.               int *lpt_lebs, int *big_lpt);  
  5. int ubifs_lpt_init(struct ubifs_info *c, int rd, int wr);  
  6. struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum);  
  7. struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum);  
  8. int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum,  
  9.               ubifs_lpt_scan_callback scan_cb, void *data);  
  10.   
  11. /* Shared by lpt.c for lpt_commit.c */  
  12. void ubifs_pack_lsave(struct ubifs_info *c, void *buf, int *lsave);  
  13. void ubifs_pack_ltab(struct ubifs_info *c, void *buf,  
  14.              struct ubifs_lpt_lprops *ltab);  
  15. void ubifs_pack_pnode(struct ubifs_info *c, void *buf,  
  16.               struct ubifs_pnode *pnode);  
  17. void ubifs_pack_nnode(struct ubifs_info *c, void *buf,  
  18.               struct ubifs_nnode *nnode);  
  19. struct ubifs_pnode *ubifs_get_pnode(struct ubifs_info *c,  
  20.                     struct ubifs_nnode *parent, int iip);  
  21. struct ubifs_nnode *ubifs_get_nnode(struct ubifs_info *c,  
  22.                     struct ubifs_nnode *parent, int iip);  
  23. int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip);  
  24. void ubifs_add_lpt_dirt(struct ubifs_info *c, int lnum, int dirty);  
  25. void ubifs_add_nnode_dirt(struct ubifs_info *c, struct ubifs_nnode *nnode);  
  26. uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits);  
  27. struct ubifs_nnode *ubifs_first_nnode(struct ubifs_info *c, int *hght);  
  28. /* Needed only in debugging code in lpt_commit.c */  
  29. int ubifs_unpack_nnode(const struct ubifs_info *c, void *buf,  
  30.                struct ubifs_nnode *nnode);  
  31.   
  32. /* lpt_commit.c */  
  33. int ubifs_lpt_start_commit(struct ubifs_info *c);  
  34. int ubifs_lpt_end_commit(struct ubifs_info *c);  
  35. int ubifs_lpt_post_commit(struct ubifs_info *c);  
  36. void ubifs_lpt_free(struct ubifs_info *c, int wr_only);  
  37.   
  38. /* lprops.c */  
  39. const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,  
  40.                        const struct ubifs_lprops *lp,  
  41.                        int free, int dirty, int flags,  
  42.                        int idx_gc_cnt);  
  43. void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *lst);  
  44. void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,  
  45.               int cat);  
  46. void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops,  
  47.                struct ubifs_lprops *new_lprops);  
  48. void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops);  
  49. int ubifs_categorize_lprops(const struct ubifs_info *c,  
  50.                 const struct ubifs_lprops *lprops);  
  51. int ubifs_change_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,  
  52.             int flags_set, int flags_clean, int idx_gc_cnt);  
  53. int ubifs_update_one_lp(struct ubifs_info *c, int lnum, int free, int dirty,  
  54.             int flags_set, int flags_clean);  
  55. int ubifs_read_one_lp(struct ubifs_info *c, int lnum, struct ubifs_lprops *lp);  
  56. const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c);  
  57. const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c);  
  58. const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c);  
  59. const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);  
  60. int ubifs_calc_dark(const struct ubifs_info *c, int spc);  

[cpp]  view plain  copy
  1. /* file.c */  
  2. int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);  
  3. int ubifs_setattr(struct dentry *dentry, struct iattr *attr);  
  4.   
  5. /* dir.c */  
  6. struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,  
  7.                   umode_t mode);  
  8. int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,  
  9.           struct kstat *stat);  
  10.   
  11. /* xattr.c */  
  12. int ubifs_setxattr(struct dentry *dentry, const char *name,  
  13.            const void *value, size_t size, int flags);  
  14. ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf,  
  15.                size_t size);  
  16. ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size);  
  17. int ubifs_removexattr(struct dentry *dentry, const char *name);  
  18.   
  19. /* super.c */  
  20. struct inode *ubifs_iget(struct super_block *sb, unsigned long inum);  
  21.   
  22. /* recovery.c */  
  23. int ubifs_recover_master_node(struct ubifs_info *c);  
  24. int ubifs_write_rcvrd_mst_node(struct ubifs_info *c);  
  25. struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,  
  26.                      int offs, void *sbuf, int jhead);  
  27. struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,  
  28.                          int offs, void *sbuf);  
  29. int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);  
  30. int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);  
  31. int ubifs_rcvry_gc_commit(struct ubifs_info *c);  
  32. int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,  
  33.                  int deletion, loff_t new_size);  
  34. int ubifs_recover_size(struct ubifs_info *c);  
  35. void ubifs_destroy_size_tree(struct ubifs_info *c);  
  36.   
  37. /* ioctl.c */  
  38. long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);  
  39. void ubifs_set_inode_flags(struct inode *inode);  
  40. #ifdef CONFIG_COMPAT  
  41. long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);  
  42. #endif  
  43.   
  44. /* compressor.c */  
  45. int __init ubifs_compressors_init(void);  
  46. void ubifs_compressors_exit(void);  
  47. void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,  
  48.             int *compr_type);  
  49. int ubifs_decompress(const void *buf, int len, void *out, int *out_len,  
  50.              int compr_type);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值