F2FS二三事


/*
 * this structure is used as one of function parameters.
 * all the information are dedicated to a given direct node block determined
 * by the data offset in a file.
 */
struct dnode_of_data {
    struct inode *inode;        /* vfs inode pointer */
    struct page *inode_page;    /* its inode page, NULL is possible */  //相关的inode page
    struct page *node_page;        /* cached direct node page */ //direct node block 的node page
    nid_t nid;            /* node id of the direct node block */  //direct node block的nid
    unsigned int ofs_in_node;    /* data offset in the node page */ //node page 中的data offset
    bool inode_page_locked;        /* inode page is locked or not */
    block_t    data_blkaddr;        /* block address of the node block */ //direct node block 的 block address
};

 

dnode_of_data 这个结构体用来做为函数的参数,结构体里面的所有成员信息,均来自于与其相关的direct node block,

此direct node block由数据所在的file中的位置决定,即:根据数据所在file中的offset, 找到与其相关的direct node block, 

然后填充此direct node block。

 

/*
 * get_node_path - Get the index path of pgoff_t block
 * @offset: offset in the current index node block.
 * @noffset: NO. of the index block within a file.
 * return: depth of the index path.
 *
 * By default, it sets inline_xattr and inline_data
 * 
 * ==================================
 *
 * get_node_path: 得到偏移为pgoff_t block对应的路径
 * offset: 当前node block中的偏移
 * noffset: 一共有多少个索引(index) block(在当前检索到的结点处)
 * level: 得到的index path一共有多少层
 *
 */
static int get_node_path(struct f2fs_node *node, long block,
				int offset[4], unsigned int noffset[4])
{
	const long direct_index = ADDRS_PER_INODE(&node->i);
	const long direct_blks = ADDRS_PER_BLOCK;
	const long dptrs_per_blk = NIDS_PER_BLOCK;
	const long indirect_blks = ADDRS_PER_BLOCK * NIDS_PER_BLOCK;
	const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK;
	int n = 0;
	int level = 0;

    /*
    * 从inode block开始检索, inode 中共有direct_index个地址,
    * 如果block < direct_index,说明此地址存在于inode本身,
    * 这时,设置level = 0, offset[0] = block, noffset[0] = 0,
    * 说明,inode本身包含此地址,则level = 0,
    *       block在inode中的偏移为offset[0] = block,
    *       索引block, 即index block个数为0, noffset[0] = 0
    */
	noffset[0] = 0;
	if (block < direct_index) {
		offset[n] = block;
		goto got;
	}

    /*
    * 如果direct_index < block < direct_blocks, 说明inode 中不包含此地址,
    * 但是因其小于direct_blks,则其存在于第一个direct block中。
    * 此时,level = 1,index path为1层,
    * offset[0] = NODE_DIR1_BLOCKs, 即在inode中的偏移为NODE_DIR1_BLOCKs,
    * 通过NODE_DIR1_BLOCKs找到第一层index block的地址,
    * offset[1] = block, 其实此block已经为原block - direct_index后剩下的值,
    *                    即其在第一层index block中的偏移为block.
    * noffset[0] = 0, noffset[1] = 1, 说明在此时,index path中的index block为1,
    *                    即只有一个inode block为index block
    */
	block -= direct_index;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR1_BLOCK;
		noffset[n]= 1;
		offset[n] = block;
		level = 1;
		goto got;
	}

    /*
    * 如果 block < direct_blks, 说明inode 中不包含此地址,第一个direct block也不包含此
    * 地址,而第二个direct index block中包含此地址。
    * 此时,level = 1,index path为1层,
    * offset[0] = NODE_DIR2_BLOCK, 为第二个direct index block在inode block中的偏移地址,
    * offset[1] = block,为在第二个direct index block中的偏移量,
    * noffset[1] = 2, 说明此时,有两个index block,即inode, 和 第一个direct index block。
    */
	block -= direct_blks;
	if (block < direct_blks) {
		offset[n++] = NODE_DIR2_BLOCK;
		noffset[n] = 2;
		offset[n] = block;
		level = 1;
		goto got;
	}

    /*
    * 如果block < indirect_blks, 说明inode block中不包含,两个direct index block中也不包含,
    * 而是在indirect block中,
    * offset[0] = NODE_IND1_BLOCK, 第一个indirect block在inode中的偏移量,
    * offset[1] = block / direct_blks, 为其在indirect block中的相当于段地址,
    * offset[2] = block % direct_blks, 为其在indirect block中的相当于段内偏移
    * noffset[1] = 3, 包含三个index block, inode, direct index block, direct index block,
    * noffset[2] = 4, 包含四个index block, inode, 2 * direct index block, indirect block.
    * level  = 2
    *  _________________ 
    * |                 |
    * |                 |
    * |_________________|      indirect block
    * |NODE_IND1_BLOCK  |-----> _________
    * |_________________|      | ...     |
    * |_________________|      |_________|
    * |_________________|      |offset[1]|----> _________
    *                          |_________|     |_________|
    *                          |_________|     |offset[2]|---->addr
    *                          |_________|     |_________|
    *                                          |_________|
    */
	block -= direct_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND1_BLOCK;
		noffset[n] = 3;
		offset[n++] = block / direct_blks;
		noffset[n] = 4 + offset[n - 1];
		offset[n] = block % direct_blks;
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < indirect_blks) {
		offset[n++] = NODE_IND2_BLOCK;
		noffset[n] = 4 + dptrs_per_blk;
		offset[n++] = block / direct_blks;
		noffset[n] = 5 + dptrs_per_blk + offset[n - 1];
		offset[n] = block % direct_blks;
		level = 2;
		goto got;
	}
	block -= indirect_blks;
	if (block < dindirect_blks) {
		offset[n++] = NODE_DIND_BLOCK;
		noffset[n] = 5 + (dptrs_per_blk * 2);
		offset[n++] = block / indirect_blks;
		noffset[n] = 6 + (dptrs_per_blk * 2) +
			offset[n - 1] * (dptrs_per_blk + 1);
		offset[n++] = (block / direct_blks) % dptrs_per_blk;
		noffset[n] = 7 + (dptrs_per_blk * 2) +
			offset[n - 2] * (dptrs_per_blk + 1) +
			offset[n - 1];
		offset[n] = block % direct_blks;
		level = 3;
		goto got;
	} else {
		ASSERT(0);
	}
got:
	return level;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值