Commit de93653f authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: reserve the xattr space dynamically



This patch enables the number of direct pointers inside on-disk inode block to
be changed dynamically according to the size of inline xattr space.

The number of direct pointers, ADDRS_PER_INODE, can be changed only if the file
has inline xattr flag.

The number of direct pointers that will be used by inline xattrs is defined as
F2FS_INLINE_XATTR_ADDRS.
Current patch assigns F2FS_INLINE_XATTR_ADDRS to 0 temporarily.

Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
parent 444c580f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ void update_extent_cache(block_t blk_addr, struct dnode_of_data *dn)
	block_t start_blkaddr, end_blkaddr;

	BUG_ON(blk_addr == NEW_ADDR);
	fofs = start_bidx_of_node(ofs_of_node(dn->node_page)) + dn->ofs_in_node;
	fofs = start_bidx_of_node(ofs_of_node(dn->node_page), fi) +
							dn->ofs_in_node;

	/* Update the page address in the parent node */
	__set_data_blkaddr(dn, blk_addr);
@@ -448,7 +449,7 @@ static int get_data_block_ro(struct inode *inode, sector_t iblock,
		unsigned int end_offset;

		end_offset = IS_INODE(dn.node_page) ?
				ADDRS_PER_INODE :
				ADDRS_PER_INODE(F2FS_I(inode)) :
				ADDRS_PER_BLOCK;

		clear_buffer_new(bh_result);
+8 −10
Original line number Diff line number Diff line
@@ -300,15 +300,6 @@ struct f2fs_sm_info {
	unsigned int ovp_segments;	/* # of overprovision segments */
};

/*
 * For directory operation
 */
#define	NODE_DIR1_BLOCK		(ADDRS_PER_INODE + 1)
#define	NODE_DIR2_BLOCK		(ADDRS_PER_INODE + 2)
#define	NODE_IND1_BLOCK		(ADDRS_PER_INODE + 3)
#define	NODE_IND2_BLOCK		(ADDRS_PER_INODE + 4)
#define	NODE_DIND_BLOCK		(ADDRS_PER_INODE + 5)

/*
 * For superblock
 */
@@ -942,6 +933,13 @@ static inline void set_raw_inline(struct f2fs_inode_info *fi,
		ri->i_inline |= F2FS_INLINE_XATTR;
}

static inline unsigned int addrs_per_inode(struct f2fs_inode_info *fi)
{
	if (is_inode_flag_set(fi, FI_INLINE_XATTR))
		return DEF_ADDRS_PER_INODE - F2FS_INLINE_XATTR_ADDRS;
	return DEF_ADDRS_PER_INODE;
}

static inline int f2fs_readonly(struct super_block *sb)
{
	return sb->s_flags & MS_RDONLY;
@@ -1108,7 +1106,7 @@ int do_write_data_page(struct page *);
 */
int start_gc_thread(struct f2fs_sb_info *);
void stop_gc_thread(struct f2fs_sb_info *);
block_t start_bidx_of_node(unsigned int);
block_t start_bidx_of_node(unsigned int, struct f2fs_inode_info *);
int f2fs_gc(struct f2fs_sb_info *);
void build_gc_manager(struct f2fs_sb_info *);
int __init create_gc_caches(void);
+1 −1
Original line number Diff line number Diff line
@@ -290,7 +290,7 @@ static int truncate_blocks(struct inode *inode, u64 from)
	}

	if (IS_INODE(dn.node_page))
		count = ADDRS_PER_INODE;
		count = ADDRS_PER_INODE(F2FS_I(inode));
	else
		count = ADDRS_PER_BLOCK;

+6 −3
Original line number Diff line number Diff line
@@ -461,7 +461,7 @@ next_step:
 * as indirect or double indirect node blocks, are given, it must be a caller's
 * bug.
 */
block_t start_bidx_of_node(unsigned int node_ofs)
block_t start_bidx_of_node(unsigned int node_ofs, struct f2fs_inode_info *fi)
{
	unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4;
	unsigned int bidx;
@@ -478,7 +478,7 @@ block_t start_bidx_of_node(unsigned int node_ofs)
		int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1);
		bidx = node_ofs - 5 - dec;
	}
	return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE;
	return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE(fi);
}

static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
@@ -586,7 +586,6 @@ next_step:
			continue;
		}

		start_bidx = start_bidx_of_node(nofs);
		ofs_in_node = le16_to_cpu(entry->ofs_in_node);

		if (phase == 2) {
@@ -594,6 +593,8 @@ next_step:
			if (IS_ERR(inode))
				continue;

			start_bidx = start_bidx_of_node(nofs, F2FS_I(inode));

			data_page = find_data_page(inode,
					start_bidx + ofs_in_node, false);
			if (IS_ERR(data_page))
@@ -604,6 +605,8 @@ next_step:
		} else {
			inode = find_gc_inode(dni.ino, ilist);
			if (inode) {
				start_bidx = start_bidx_of_node(nofs,
								F2FS_I(inode));
				data_page = get_lock_data_page(inode,
						start_bidx + ofs_in_node);
				if (IS_ERR(data_page))
+5 −4
Original line number Diff line number Diff line
@@ -315,9 +315,10 @@ cache:
 * The maximum depth is four.
 * Offset[0] will have raw inode offset.
 */
static int get_node_path(long block, int offset[4], unsigned int noffset[4])
static int get_node_path(struct f2fs_inode_info *fi, long block,
				int offset[4], unsigned int noffset[4])
{
	const long direct_index = ADDRS_PER_INODE;
	const long direct_index = ADDRS_PER_INODE(fi);
	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;
@@ -405,7 +406,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
	int level, i;
	int err = 0;

	level = get_node_path(index, offset, noffset);
	level = get_node_path(F2FS_I(dn->inode), index, offset, noffset);

	nids[0] = dn->inode->i_ino;
	npage[0] = dn->inode_page;
@@ -687,7 +688,7 @@ int truncate_inode_blocks(struct inode *inode, pgoff_t from)

	trace_f2fs_truncate_inode_blocks_enter(inode, from);

	level = get_node_path(from, offset, noffset);
	level = get_node_path(F2FS_I(inode), from, offset, noffset);
restart:
	page = get_node_page(sbi, inode->i_ino);
	if (IS_ERR(page)) {
Loading