源文件
linux/fs/btrfs/inode-map.h
linux/fs/btrfs/inode-map.c
linux/fs/btrfs/free-space-cache.c
inode map 也是基于 free-space-cache 实现的,使用的时候需要开启选项 inode_cache:
INODE_MAP_CACHE: mount -o inode_cache
inode map 是属于系统范围的:root->free_ino_ctl,其对应的 objectid 为 BTRFS_FREE_INO_OBJECTID:
118 /* 119 * The inode number assigned to the special inode for storing 120 * free ino cache 121 */ 122 #define BTRFS_FREE_INO_OBJECTID -12ULL
file ino 的限制范围为 [BTRFS_FIRST_FREE_OBJECTID, BTRFS_LAST_FREE_OBJECTID]
/* * All files have objectids in this range. */ #define BTRFS_FIRST_FREE_OBJECTID 256ULL #define BTRFS_LAST_FREE_OBJECTID -256ULL
从 btrfs_init_free_ino_ctl 中可以看到对于 inode map ctl 的初始设置:
ctl->unit = 1; 对于 free space,这里是 sectorsize;对于 inode,粒度为 1 ctl->start = 0; ctl->private = NULL; 对于 free space,这里记录所属的 block group;对于 inode map 则是全局的 ctl->op = &free_ino_op; /* * Initially we allow to use 16K of ram to cache chunks of * inode numbers before we resort to bitmaps. This is somewhat * arbitrary, but it will be adjusted in runtime. */ ctl->extents_thresh = INIT_THRESHOLD;
是使用 bitmap 还是 extent 来管理空闲节点空间,也是动态调整的;这个可以参考 free-space-cache 的调整限制。
kthread btrfs-ino-cache
填充 ino map 的操作是一个比较耗时的过程,由内核线程来完成:
kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", root->root_key.objectid)
btrfs_find_free_ino 会激活 btrfs-ino-cache 内核线程的运行。
基本操作
分配 inode number:btrfs_find_free_ino
btrfs_find_free_ino 会调用 btrfs_find_ino_for_alloc 搜索 inode map 来找到一个空闲的 ino:
* Find the left-most item in the cache tree, and then return the * smallest inode number in the item. * * Note: the returned inode number may not be the smallest one in * the tree, if the left-most item is a bitmap.
如果找不到空闲 ino,则激活 btrfs-ino-cache 内核线程来填充 inode map,同时会阻塞当前进程。
从磁盘加载 ino map:load_free_ino_cache
写 ino map 到磁盘:btrfs_write_out_ino_cache
创建 ino map 的 inode:create_free_ino_inode
查找 ino map 的 inode:lookup_free_ino_inode
对于查找操作,会先看 root->cache_inode,这里缓存了 free ino map 的 inode
ino:BTRFS_FREE_INO_OBJECTID
对应的 struct btrfs_free_space_header
key.objectid = BTRFS_FREE_SPACE_OBJECTID;
key.offset = 0;
key.type = 0;
定位 inode map 对应的 inode:
* 尚未弄明白的问题
* inode map 属于哪课 tree?
* free ino map 的 inode 属于哪课 tree?
跟对应的 struct btrfs_free_space_header 属于同一棵树,tree_root
* ->free_ino_pinned 在什么情况下使用?
* btrfs_save_ino_cache 具体会做些什么?
* 如果不激活 inode_cache 选项,那么如何管理 ino?