xfs bmap实现简析
来源:互联网 发布:网络流行文化有哪些 编辑:程序博客网 时间:2024/05/23 01:04
1.xfs_bmap用于对用户数据进行存储管理,其中的重点有延时分配和预分配
设计源码文件xfs_bmap.h xfs_bmap.c xfs_bmap_tree.h xfs_bmap_tree.c
2.依赖:
xfs bmap和xfs bmap tree的实现依赖于xfs_btree的实现,独立分析。
3.头文件设计的核心数据结构及宏分析
xfs_bmap.h
typedef struct xfs_bmap_free_item
{
xfs_fsblock_t xbfi_startblock;/* starting fs block number */
xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */
struct xfs_bmap_free_item *xbfi_next; /* link to next entry */
typedef struct xfs_bmap_free_item
{
xfs_fsblock_t xbfi_startblock;/* starting fs block number */
xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */
struct xfs_bmap_free_item *xbfi_next; /* link to next entry */
} xfs_bmap_free_item_t;
该结构用于稍后将释放的extent的map信息,根据xbfi_startblock排序
typedef struct xfs_bmap_free
{
xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */
int xbf_count; /* count of items on list */
int xbf_low; /* alloc in low mode */
typedef struct xfs_bmap_free
{
xfs_bmap_free_item_t *xbf_first; /* list of to-be-free extents */
int xbf_count; /* count of items on list */
int xbf_low; /* alloc in low mode */
} xfs_bmap_free_t;
即将释放的extent的链表头
xbf_low:表示分配器启用低空间分配算法,what is lowspace algorithm?
#define XFS_BMAP_MAX_NMAP 4
#define XFS_BMAPI_ENTIRE 0x001 /* return entire extent, not trimmed */
#define XFS_BMAPI_METADATA 0x002 /* mapping metadata not user data */
#define XFS_BMAPI_ATTRFORK 0x004 /* use attribute fork not data */
#define XFS_BMAPI_PREALLOC 0x008 /* preallocation op: unwritten space */
#define XFS_BMAPI_IGSTATE 0x010 /* Ignore state - */
/* combine contig. space */
#define XFS_BMAPI_CONTIG 0x020 /* must allocate only one extent */
typedef struct xfs_bmbt_rec_host {
__uint64_t l0, l1;
} xfs_bmbt_rec_host_t;
/*
* Incore version of above.
*/
typedef struct xfs_bmbt_irec
{
xfs_fileoff_t br_startoff; /* starting file offset */
xfs_fsblock_t br_startblock; /* starting block number */
xfs_filblks_t br_blockcount; /* number of blocks */
xfs_exntst_t br_state; /* extent state */
} xfs_bmbt_irec_t;
/*
* Key structure for non-leaf levels of the tree.
*/
typedef struct xfs_bmbt_key {
__be64 br_startoff; /* starting file offset */
} xfs_bmbt_key_t, xfs_bmdr_key_t;
/* btree pointer type */
typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
#define XFS_BMAPI_METADATA 0x002 /* mapping metadata not user data */
#define XFS_BMAPI_ATTRFORK 0x004 /* use attribute fork not data */
#define XFS_BMAPI_PREALLOC 0x008 /* preallocation op: unwritten space */
#define XFS_BMAPI_IGSTATE 0x010 /* Ignore state - */
/* combine contig. space */
#define XFS_BMAPI_CONTIG 0x020 /* must allocate only one extent */
/*
* unwritten extent conversion - this needs write cache flushing and no additional
* allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts
* from written to unwritten, otherwise convert from unwritten to written.
*/
#define XFS_BMAPI_CONVERT 0x040
* Bmap root header, on-disk form only.
*/
typedef struct xfs_bmdr_block {
__be16 bb_level; /* 0 is a leaf */
__be16 bb_numrecs; /* current # of data records */
} xfs_bmdr_block_t;
/*
* Bmap btree record and extent descriptor.
* l0:63 is an extent flag (value 1 indicates non-normal).
* l0:9-62 are startoff.
* l0:0-8 and l1:21-63 are startblock.
* l1:0-20 are blockcount.
*/
#define BMBT_EXNTFLAG_BITLEN 1
#define BMBT_STARTOFF_BITLEN 54
#define BMBT_STARTBLOCK_BITLEN 52
#define BMBT_BLOCKCOUNT_BITLEN 21
typedef struct xfs_bmbt_rec {
__be64 l0, l1;
* unwritten extent conversion - this needs write cache flushing and no additional
* allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts
* from written to unwritten, otherwise convert from unwritten to written.
*/
#define XFS_BMAPI_CONVERT 0x040
#define XFS_BMAPI_STACK_SWITCH 0x080 /* 用于分配存储空间时调用__xfs_bmapi_allocate是直接调用
/* * 还是用分配工作队列,默认使用分配工作队列; 仅函数
* xfs_iomap_write_allocate使用该方法,用于延时分配
* 延时分配直接调用分配函数,已提高延时分配的效率 */
#define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL)
#define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL)
/*
* Flags for xfs_bmap_add_extent*.
*/
#define BMAP_LEFT_CONTIG (1 << 0)
#define BMAP_RIGHT_CONTIG (1 << 1)
#define BMAP_LEFT_FILLING (1 << 2)
#define BMAP_RIGHT_FILLING (1 << 3)
#define BMAP_LEFT_DELAY (1 << 4)
#define BMAP_RIGHT_DELAY (1 << 5)
#define BMAP_LEFT_VALID (1 << 6)
#define BMAP_RIGHT_VALID (1 << 7)
#define BMAP_ATTRFORK (1 << 8)
typedef struct xfs_bmalloca {
xfs_fsblock_t *firstblock; /* i/o first block allocated */
struct xfs_bmap_free *flist; /* bmap freelist */
struct xfs_trans *tp; /* transaction pointer */
struct xfs_inode *ip; /* incore inode pointer */
struct xfs_bmbt_irec prev; /* extent before the new one */
struct xfs_bmbt_irec got; /* extent after, or delayed */
xfs_fileoff_t offset; /* offset in file filling in */
xfs_extlen_t length; /* i/o length asked/allocated */
xfs_fsblock_t blkno; /* starting block of new extent */
struct xfs_btree_cur *cur; /* btree cursor */
xfs_extnum_t idx; /* current extent index */
int nallocs;/* number of extents alloc'd */
int logflags;/* flags for transaction logging */
xfs_extlen_t total; /* total blocks needed for xaction */
xfs_extlen_t minlen; /* minimum allocation size (blocks) */
xfs_extlen_t minleft; /* amount must be left after alloc */
char eof; /* set if allocating past last extent */
char wasdel; /* replacing a delayed allocation */
char userdata;/* set if is user data */
char aeof; /* allocated space at eof */
char conv; /* overwriting unwritten extents */
struct completion *done;
struct work_struct work;
int result;
} xfs_bmalloca_t;
xfs_bmap_tree.h
#define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL)
/*
* Flags for xfs_bmap_add_extent*.
*/
#define BMAP_LEFT_CONTIG (1 << 0)
#define BMAP_RIGHT_CONTIG (1 << 1)
#define BMAP_LEFT_FILLING (1 << 2)
#define BMAP_RIGHT_FILLING (1 << 3)
#define BMAP_LEFT_DELAY (1 << 4)
#define BMAP_RIGHT_DELAY (1 << 5)
#define BMAP_LEFT_VALID (1 << 6)
#define BMAP_RIGHT_VALID (1 << 7)
#define BMAP_ATTRFORK (1 << 8)
typedef struct xfs_bmalloca {
xfs_fsblock_t *firstblock; /* i/o first block allocated */
struct xfs_bmap_free *flist; /* bmap freelist */
struct xfs_trans *tp; /* transaction pointer */
struct xfs_inode *ip; /* incore inode pointer */
struct xfs_bmbt_irec prev; /* extent before the new one */
struct xfs_bmbt_irec got; /* extent after, or delayed */
xfs_fileoff_t offset; /* offset in file filling in */
xfs_extlen_t length; /* i/o length asked/allocated */
xfs_fsblock_t blkno; /* starting block of new extent */
struct xfs_btree_cur *cur; /* btree cursor */
xfs_extnum_t idx; /* current extent index */
int nallocs;/* number of extents alloc'd */
int logflags;/* flags for transaction logging */
xfs_extlen_t total; /* total blocks needed for xaction */
xfs_extlen_t minlen; /* minimum allocation size (blocks) */
xfs_extlen_t minleft; /* amount must be left after alloc */
char eof; /* set if allocating past last extent */
char wasdel; /* replacing a delayed allocation */
char userdata;/* set if is user data */
char aeof; /* allocated space at eof */
char conv; /* overwriting unwritten extents */
char stack_switch; /* for delayed allocation, call directly function:__xfs_bmapi_allocate,
int flags; don't use allocate workqueue. Because of delayed allocation need to
response as fast as quickly */
struct completion *done;
struct work_struct work;
int result;
} xfs_bmalloca_t;
xfs_bmap_tree.h
* Bmap root header, on-disk form only.
*/
typedef struct xfs_bmdr_block {
__be16 bb_level; /* 0 is a leaf */
__be16 bb_numrecs; /* current # of data records */
} xfs_bmdr_block_t;
/*
* Bmap btree record and extent descriptor.
* l0:63 is an extent flag (value 1 indicates non-normal).
* l0:9-62 are startoff.
* l0:0-8 and l1:21-63 are startblock.
* l1:0-20 are blockcount.
*/
#define BMBT_EXNTFLAG_BITLEN 1
#define BMBT_STARTOFF_BITLEN 54
#define BMBT_STARTBLOCK_BITLEN 52
#define BMBT_BLOCKCOUNT_BITLEN 21
记录在设备上的格式
__be64 l0, l1;
} xfs_bmbt_rec_t;
typedef xfs_bmbt_rec_t xfs_bmdr_rec_t;
记录在内存中的格式
__uint64_t l0, l1;
} xfs_bmbt_rec_host_t;
/*
* Incore version of above.
*/
typedef struct xfs_bmbt_irec
{
xfs_fileoff_t br_startoff; /* starting file offset */
xfs_fsblock_t br_startblock; /* starting block number */
xfs_filblks_t br_blockcount; /* number of blocks */
xfs_exntst_t br_state; /* extent state */
} xfs_bmbt_irec_t;
/*
* Possible extent formats.
*/
typedef enum {
XFS_EXTFMT_NOSTATE = 0,
XFS_EXTFMT_HASSTATE
} xfs_exntfmt_t;
/*
* Possible extent states.
*/
typedef enum {
XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
} xfs_exntst_t;
*/
typedef enum {
XFS_EXTFMT_NOSTATE = 0,
XFS_EXTFMT_HASSTATE
} xfs_exntfmt_t;
/*
* Possible extent states.
*/
typedef enum {
XFS_EXT_NORM, XFS_EXT_UNWRITTEN,
XFS_EXT_DMAPI_OFFLINE, XFS_EXT_INVALID
} xfs_exntst_t;
* Key structure for non-leaf levels of the tree.
*/
typedef struct xfs_bmbt_key {
__be64 br_startoff; /* starting file offset */
} xfs_bmbt_key_t, xfs_bmdr_key_t;
/* btree pointer type */
typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
4.xfs_bmap实现概要分析
xfs_bmap实现文件系统地址到设备块地址的映射管理,包括设备空间的分配和释放;XFS设备空间分配包括延时分配和预分配。
分配信息由struct xfs_bmalloca统一管理,传递给xfs_alloc.c中的函数,实现实际的空间分配操作。
xfs_bmap信息由xfs_bmap_tree管理,struct xfs_bmdr_block表示设备上的映射信息;struct xfs_bmbt_irec表示内存中的映射 信息;
bmap_tree的根节点由struct xfs_btree_block表示即struct xfs_inode->struct xfs_ifork->struct xfs_btree_block[Generic btree header]。
每个xfs的inode有两个分支,分别是数据分支和属性分支,inodep->i_dp和inodep->i_afp。通过下面的操作获取到头节点的设备地址编号:
block = ifp->if_broot;
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, block, 1, ifp->if_broot_bytes);
bno = be64_to_cpu(*pp);
通过根节点,遍历整个inode的数据。
xfs_bmap实现如下分析:
xfs_bmbt_disk_set_allf :将数据(文件偏移、起始地址、块个数和状态)以设备格式保存
xfs_bmap_worst_indlen:对于延时分配计算指定len需要的文件块个数
xfs_default_attroffset:计算新创建的inode的默认属性的偏移位置,主要根据inode size为256或者更大的空间
xfs_bmap_forkoff_reset:当inode的数据格式由LOCAL转换为EXTENT时,重新计算ATTR的数据偏移
xfs_bmap_count_leaves:统计一定范围的数据使用的设备块个数,通过xfs_iext_get_ext获取xfs_bmbt_rec_host_t信息,并调用xfs_bmbt_get_blockcount解析数据
xfs_bmap_disk_count_leaves:同xfs_bmap_count_leaves,但数据格式为disk格式
xfs_bmap_count_tree:递归函数,获取一个文件所占用的所有设备空间
xfs_bmap_count_blocks:统计一个xfs_inode的特定fork的空间
DEBUG部分miss
/* xfs bmap free list管理*/
xfs_bmap_add_free:通过文件系统起始bno和len,增加一个extent信息到bmap_free链表,等在结束一个transactions时完成实际的释放操作
xfs_bmap_del_free:从bmap_free链表中删除一个extent信息
xfs_bmap_finish:对于xfs_bmapi, xfs_bunmapi,在事务结束时释放所有的extents[[续详细分析]]
xfs_bmap_cancel:取消释放映射的操作
/* xfs inode fork format manipulation(local extent btree之间的切换) */
xfs_bmap_btree_to_extents:将xfs的inode数据格式由btree转换为extent
xfs_bmap_extents_to_btree:将xfs的inode数据格式由extents转化为btree
xfs_bmap_local_to_extents_empty:将xfs的inode数据格式由local转化为extents
xfs_bmap_local_to_extents:
/* 为xfs_inode增加属性分支,根据inode的数据分支格式 */
xfs_bmap_add_attrfork_btree:为inode增加属性存储空间,btree格式, call from xfs_bmap_add_attrfork
xfs_bmap_add_attrfork_extents:为inode增加属性存储空间,extents格式
xfs_bmap_add_attrfork_local:为inode增加属性存储空间,locals格式
xfs_bmap_add_attrfork:为inode增加属性存储空间,xfs的事务、日志的整个流程都包含
/* extents和btree的相关操作 */
xfs_bmap_read_extents:读取xfs的extents或btree信息到内存
xfs_bmap_search_multi_extents:搜索特定块号的extents信息,并extents前后extents和是否达到文件尾的标志
xfs_bmap_search_extents:搜索特定分支的特定块号的extents信息
xfs_bmap_first_unused:返回相对与inode地址块号最近的未被使用的地址
xfs_bmap_last_before:返回inode现有地址最后block的下一个地址
xfs_bmap_last_extent:返回inode的最后一个extents
xfs_bmap_isaeof:判断释放到达文件尾
xfs_bmap_eof:判断指定的文件位置到达了现有的extents的最后一个extent
xfs_bmap_last_offset:返回文件最后位置的偏移号
xfs_bmap_one_block:判断文件某分支数据是否在一个block中
/* extent tree manipulation during allocation */
xfs_bmap_add_extent_delay_real:转化一个延时分配到实地址分配即为延时分配分配实际的地址空间,须仔细分析
xfs_bmap_add_extent_unwritten_real:为預分配分配空间,须仔细分析
xfs_bmap_add_extent_hole_delay:为文件洞或延时分配分配空间,须仔细分析
xfs_bmap_add_extent_hole_real:为文件洞分配空间,须仔细分析
xfs_bmap_extsize_align:判断新分配的extent是否满足基于底层设备对齐要求
xfs_bmap_adjacent:分配相邻的块
xfs_bmap_rtalloc:在实时设备上分配extent
xfs_bmap_btalloc_nullfb:
xfs_bmap_btalloc:在数据设备上分配extent
xfs_bmap_alloc:有xfs_bmapi,为inode分配一个extent
xfs_bmapi_trim_map:将地址映射区间压缩到最小请求区间
xfs_bmapi_update_map:?
xfs_bmapi_read:读取inode的空间映射信息
xfs_bmapi_reserve_delalloc:为延时分配的预留空间分配实际的空间(?)
xfs_bmapi_delay:延时的分配空间
__xfs_bmapi_allocate:执行实际的分配工作,将调用xfs_alloc.c中的函数
xfs_bmapi_allocate_worker:bmap分配工作者线程执行函数
xfs_bmapi_allocate:bmap分配的外部可调用函数
xfs_bmapi_convert_unwritten:将为预分配信息分配实际的空间
xfs_bmapi_write:映射文件块到文件系统块,分配extents或转换extents状态
xfs_bmap_del_extent:移除或取消延时分配
xfs_bunmapi:移除文件blocks
xfs_getbmapx_fix_eof_hole:
xfs_getbmap:
xfs_bmap_punch_delalloc_range:
xfs_bmap_btree实现概要分析
xfs_bmap_btree作为设备地址空间管理接口,由xfs_btree.c调用,导出API:struct xfs_btree_ops xfs_bmbt_ops
static const struct xfs_btree_ops xfs_bmbt_ops = {
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
.dup_cursor = xfs_bmbt_dup_cursor,
.update_cursor = xfs_bmbt_update_cursor,
.alloc_block = xfs_bmbt_alloc_block,
.free_block = xfs_bmbt_free_block,
.get_maxrecs = xfs_bmbt_get_maxrecs,
.get_minrecs = xfs_bmbt_get_minrecs,
.get_dmaxrecs = xfs_bmbt_get_dmaxrecs,
.init_key_from_rec = xfs_bmbt_init_key_from_rec,
.init_rec_from_key = xfs_bmbt_init_rec_from_key,
.init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
.init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
.key_diff = xfs_bmbt_key_diff,
.buf_ops = &xfs_bmbt_buf_ops,
#if defined(DEBUG) || defined(XFS_WARN)
.keys_inorder = xfs_bmbt_keys_inorder,
.recs_inorder = xfs_bmbt_recs_inorder,
#endif
.rec_len = sizeof(xfs_bmbt_rec_t),
.key_len = sizeof(xfs_bmbt_key_t),
.dup_cursor = xfs_bmbt_dup_cursor,
.update_cursor = xfs_bmbt_update_cursor,
.alloc_block = xfs_bmbt_alloc_block,
.free_block = xfs_bmbt_free_block,
.get_maxrecs = xfs_bmbt_get_maxrecs,
.get_minrecs = xfs_bmbt_get_minrecs,
.get_dmaxrecs = xfs_bmbt_get_dmaxrecs,
.init_key_from_rec = xfs_bmbt_init_key_from_rec,
.init_rec_from_key = xfs_bmbt_init_rec_from_key,
.init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
.init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
.key_diff = xfs_bmbt_key_diff,
.buf_ops = &xfs_bmbt_buf_ops,
#if defined(DEBUG) || defined(XFS_WARN)
.keys_inorder = xfs_bmbt_keys_inorder,
.recs_inorder = xfs_bmbt_recs_inorder,
#endif
};
xfs_btree处理的外部接口:struct xfs_btree_cur
当xfs_bmap需要分配空间时,调用xfs_bmbt_init_cursor初始化xfs_btree_cur并设置bc_ops。
然后调用xfs_btree.c导出的接口如xfs_btree_new_iroot,在xfs_btree中将调用指定模块的API。
然后调用xfs_btree.c导出的接口如xfs_btree_new_iroot,在xfs_btree中将调用指定模块的API。
xfs_extent_state:返回extent的状态,正常的extent状态:NORM和UNWRITTEN
xfs_bmdr_to_bmbt:转换磁盘格式的btree root为主机格式,磁盘格式为小端字节序,主机格式为大端字节序(?)
__xfs_bmbt_get_all:转换压缩的bmap extent为非压缩的bmap extent(how to compressed?)
xfs_bmbt_get_all:call __xfs_bmbt_get_all
xfs_bmbt_get_blockcount:获取extent的所包含的block count
xfs_bmbt_get_startblock:获取extent的起始block number
xfs_bmbt_get_startoff:获取extent所属文件的offset
xfs_bmbt_get_state:获取extent的状态
xfs_bmbt_disk_get_blockcount:从磁盘格式的extent中获取block count
xfs_bmbt_disk_get_startoff:
xfs_bmbt_set_allf:从参数中设置xfs_bmbt_rec_host_t
xfs_bmbt_set_all:call xfs_bmbt_set_allf
xfs_bmbt_disk_set_allf:设置磁盘格式的extent
xfs_bmbt_disk_set_all:
xfs_bmbt_to_bmdr:将btree root从主机格式转换设备格式
xfs_check_nostate_extents:检测extent信息
xfs_bmbt_dup_cursor:btree的核心数据结构之一,见btree节分析。
xfs_bmbt_update_cursor:
xfs_bmbt_alloc_block:
5.XFS延时分配实现
传统的设备地址分配是在
xfs_vm_write_begin
status = __block_write_begin(page, pos, len, xfs_get_blocks);
# if (!buffer_mapped(bh)) {
# WARN_ON(bh->b_size != blocksize);
# if (!buffer_mapped(bh)) {
# WARN_ON(bh->b_size != blocksize);
# err = get_block(inode, block, bh, 1);
# ......
# }
__xfs_get_blocks
xfs_iomap_write_delay
xfs_iomap_eof_want_preallocate
xfs_bmapi_delay
xfs_bmapi_reserve_delalloc # 为延时分配预留空间
大致流程:
xfs_get_extsz_hint:
获取底层设备块大小对齐,对于realtime设备,需要按照realtime设备的chunk大小分配空间;当底层设备是raid时,需要案子条带大小分配
xfs_trans_reserve_quota_nblks:
如果配置了quota,为ionde的使用qutoa值设置预留值
xfs_mod_incore_sb/xfs_icsb_modify_counters:
修改超级块可使用空间的可使用值
xfs_bmap_add_extent_hole_delay:
完成实际的inode的延时分配,大致流程:
如果新的延时分配请求可以和与左边或右边的延时分配记录合并,则更新xfs_bmbt_irec_t记录;否则则调用函数xfs_iext_insert,在inode的extents记录中新增加一个xfs_bmbt_irec_t记录
xfs_bmbt_get_all:
更新延时分配的extent信息,如果在xfs_bmap_add_extent_hole_delay检测可合并,则更新extents信息为合并后的信息
何时为延时分配分配实际的存储空间:
在刷新脏数据时调用xfs_vm_writepage
大致流程:
xfs_map_blocks
if (type == XFS_IO_DELALLOC &&
(!nimaps || isnullstartblock(imap->br_startblock))) {
error = xfs_iomap_write_allocate(ip, offset, count, imap);
(!nimaps || isnullstartblock(imap->br_startblock))) {
error = xfs_iomap_write_allocate(ip, offset, count, imap);
......
}
结论:根据设备空间分配的时机可有效的提高数据存储地址的连续性,通过預读可有效的提高读的性能。
6.XFS預分配实现
文件系统的預分配是在创建文件后,在写数据之前,调用fallocate或posix_fallocate实现设备空间的分配;可有效保证数据的连续性,ftp服务、smb服务在传输文件时都使用了預分配接口;
預分配与fseek有这本质的区别
xfs的预分配内核函数xfs_file_fallocate
大致流程:
调用 xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);cmd为XFS_IOC_RESVSP
xfs_alloc_file_space # flags == XFS_BMAPI_PREALLOC
xfs_bmapi_allocate
何时转化預分配的extents元数据信息:
xfs_bmap_add_extent_unwritten_real
该函数主要是修改的extents的btree或extents元数据信息
0 0
- xfs bmap实现简析
- XFS实现原理详解
- XFS实现原理详解
- WOSA/XFS架构分析和实现
- XFS文件系统
- XFS 简介
- XFS设计
- 百度BMap覆盖物
- 百度地图BMap
- BMap清空
- APICloud bMap api
- linux下获取所有文件夹和文件,支持nfs和xfs(C++实现)
- BMap添加海量点数据,BMap.Point携带数据
- 百度BMap开发(基础知识)
- iget iput bmap 函数介绍
- 循环输出BMap.Marker标记
- bmap地图api删除路线
- 解决BMap is not defined?
- 【训练计划】北大ACM试题分类
- 1D 2D 混合
- 双击以管理员权限运行批处理文件
- 密码类库Crypto++™ Library 5.1的研究与应用
- Criteria的完整用法
- xfs bmap实现简析
- 【概念解析一】两种比较方法的区别:== 和 equals
- Valid Palindrome - LeetCode
- CCheckListBox的BUG
- [集合]浅谈 properties 和hashMap的区别以及用法
- hihoCoder 1107 Shortest Proper Prefix 微软苏州校招笔试 1月17日
- SQL——处理页面多条件查询
- JDBC: 批量处理提高SQL处理速度
- UVa Q10137: The Trip (旅行)