Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 205b9822 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: call mark_inode_dirty_sync for i_field changes



This patch calls mark_inode_dirty_sync() for the following on-disk inode
changes.

 -> largest
 -> ctime/mtime/atime
 -> i_current_depth
 -> i_xattr_nid
 -> i_pino
 -> i_advise
 -> i_flags
 -> i_mode

Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent a1961246
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -384,6 +384,8 @@ int f2fs_init_acl(struct inode *inode, struct inode *dir, struct page *ipage,
	if (error)
		return error;

	mark_inode_dirty_sync(inode);

	if (default_acl) {
		error = __f2fs_set_acl(inode, ACL_TYPE_DEFAULT, default_acl,
				       ipage);
+7 −7
Original line number Diff line number Diff line
@@ -243,8 +243,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
				"Corrupted max_depth of %lu: %u",
				dir->i_ino, max_depth);
		max_depth = MAX_DIR_HASH_DEPTH;
		F2FS_I(dir)->i_current_depth = max_depth;
		mark_inode_dirty(dir);
		f2fs_i_depth_write(dir, max_depth);
	}

	for (level = 0; level < max_depth; level++) {
@@ -303,9 +302,9 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
	set_de_type(de, inode->i_mode);
	f2fs_dentry_kunmap(dir, page);
	set_page_dirty(page);
	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
	mark_inode_dirty(dir);

	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
	mark_inode_dirty_sync(dir);
	f2fs_put_page(page, 1);
}

@@ -462,10 +461,10 @@ void update_parent_metadata(struct inode *dir, struct inode *inode,
		clear_inode_flag(inode, FI_NEW_INODE);
	}
	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
	mark_inode_dirty(dir);
	mark_inode_dirty_sync(dir);

	if (F2FS_I(dir)->i_current_depth != current_depth) {
		F2FS_I(dir)->i_current_depth = current_depth;
		f2fs_i_depth_write(dir, current_depth);
		set_inode_flag(dir, FI_UPDATE_DIR);
	}

@@ -597,7 +596,7 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name,

	if (inode) {
		/* we don't need to mark_inode_dirty now */
		F2FS_I(inode)->i_pino = dir->i_ino;
		f2fs_i_pino_write(inode, dir->i_ino);
		update_inode(inode, page);
		f2fs_put_page(page, 1);
	}
@@ -730,6 +729,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
	set_page_dirty(page);

	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
	mark_inode_dirty_sync(dir);

	if (inode)
		f2fs_drop_nlink(dir, inode, NULL);
+14 −10
Original line number Diff line number Diff line
@@ -170,8 +170,10 @@ static void __drop_largest_extent(struct inode *inode,
{
	struct extent_info *largest = &F2FS_I(inode)->extent_tree->largest;

	if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs)
	if (fofs < largest->fofs + largest->len && fofs + len > largest->fofs) {
		largest->len = 0;
		mark_inode_dirty_sync(inode);
	}
}

/* return true, if inode page is changed */
@@ -335,11 +337,12 @@ static struct extent_node *__lookup_extent_tree_ret(struct extent_tree *et,
	return en;
}

static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
static struct extent_node *__try_merge_extent_node(struct inode *inode,
				struct extent_tree *et, struct extent_info *ei,
				struct extent_node *prev_ex,
				struct extent_node *next_ex)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct extent_node *en = NULL;

	if (prev_ex && __is_back_mergeable(ei, &prev_ex->ei)) {
@@ -360,7 +363,7 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
	if (!en)
		return NULL;

	__try_update_largest_extent(et, en);
	__try_update_largest_extent(inode, et, en);

	spin_lock(&sbi->extent_lock);
	if (!list_empty(&en->list)) {
@@ -371,11 +374,12 @@ static struct extent_node *__try_merge_extent_node(struct f2fs_sb_info *sbi,
	return en;
}

static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
static struct extent_node *__insert_extent_tree(struct inode *inode,
				struct extent_tree *et, struct extent_info *ei,
				struct rb_node **insert_p,
				struct rb_node *insert_parent)
{
	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
	struct rb_node **p = &et->root.rb_node;
	struct rb_node *parent = NULL;
	struct extent_node *en = NULL;
@@ -402,7 +406,7 @@ static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi,
	if (!en)
		return NULL;

	__try_update_largest_extent(et, en);
	__try_update_largest_extent(inode, et, en);

	/* update in global extent list */
	spin_lock(&sbi->extent_lock);
@@ -473,7 +477,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
				set_extent_info(&ei, end,
						end - dei.fofs + dei.blk,
						org_end - end);
				en1 = __insert_extent_tree(sbi, et, &ei,
				en1 = __insert_extent_tree(inode, et, &ei,
							NULL, NULL);
				next_en = en1;
			} else {
@@ -494,7 +498,7 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
		}

		if (parts)
			__try_update_largest_extent(et, en);
			__try_update_largest_extent(inode, et, en);
		else
			__release_extent_node(sbi, et, en);

@@ -514,15 +518,15 @@ static unsigned int f2fs_update_extent_tree_range(struct inode *inode,
	if (blkaddr) {

		set_extent_info(&ei, fofs, blkaddr, len);
		if (!__try_merge_extent_node(sbi, et, &ei, prev_en, next_en))
			__insert_extent_tree(sbi, et, &ei,
		if (!__try_merge_extent_node(inode, et, &ei, prev_en, next_en))
			__insert_extent_tree(inode, et, &ei,
						insert_p, insert_parent);

		/* give up extent_cache, if split and small updates happen */
		if (dei.len >= 1 &&
				prev.len < F2FS_MIN_EXTENT_LEN &&
				et->largest.len < F2FS_MIN_EXTENT_LEN) {
			et->largest.len = 0;
			__drop_largest_extent(inode, 0, UINT_MAX);
			set_inode_flag(inode, FI_NO_EXTENT);
		}
	}
+50 −8
Original line number Diff line number Diff line
@@ -498,11 +498,13 @@ static inline bool __is_front_mergeable(struct extent_info *cur,
	return __is_extent_mergeable(cur, front);
}

static inline void __try_update_largest_extent(struct extent_tree *et,
						struct extent_node *en)
static inline void __try_update_largest_extent(struct inode *inode,
			struct extent_tree *et, struct extent_node *en)
{
	if (en->ei.len > et->largest.len)
	if (en->ei.len > et->largest.len) {
		et->largest = en->ei;
		mark_inode_dirty_sync(inode);
	}
}

struct f2fs_nm_info {
@@ -1534,10 +1536,26 @@ enum {
	FI_DIRTY_FILE,		/* indicate regular/symlink has dirty pages */
};

static inline void __mark_inode_dirty_flag(struct inode *inode,
						int flag, bool set)
{
	switch (flag) {
	case FI_INLINE_XATTR:
	case FI_INLINE_DATA:
	case FI_INLINE_DENTRY:
		if (set)
			return;
	case FI_DATA_EXIST:
	case FI_INLINE_DOTS:
		mark_inode_dirty_sync(inode);
	}
}

static inline void set_inode_flag(struct inode *inode, int flag)
{
	if (!test_bit(flag, &F2FS_I(inode)->flags))
		set_bit(flag, &F2FS_I(inode)->flags);
	__mark_inode_dirty_flag(inode, flag, true);
}

static inline int is_inode_flag_set(struct inode *inode, int flag)
@@ -1549,12 +1567,14 @@ static inline void clear_inode_flag(struct inode *inode, int flag)
{
	if (test_bit(flag, &F2FS_I(inode)->flags))
		clear_bit(flag, &F2FS_I(inode)->flags);
	__mark_inode_dirty_flag(inode, flag, false);
}

static inline void set_acl_inode(struct inode *inode, umode_t mode)
{
	F2FS_I(inode)->i_acl_mode = mode;
	set_inode_flag(inode, FI_ACL_MODE);
	mark_inode_dirty_sync(inode);
}

static inline void f2fs_i_links_write(struct inode *inode, bool inc)
@@ -1583,18 +1603,38 @@ static inline void f2fs_i_size_write(struct inode *inode, loff_t i_size)
	mark_inode_dirty_sync(inode);
}

static inline void f2fs_i_depth_write(struct inode *inode, unsigned int depth)
{
	F2FS_I(inode)->i_current_depth = depth;
	mark_inode_dirty_sync(inode);
}

static inline void f2fs_i_xnid_write(struct inode *inode, nid_t xnid)
{
	F2FS_I(inode)->i_xattr_nid = xnid;
	mark_inode_dirty_sync(inode);
}

static inline void f2fs_i_pino_write(struct inode *inode, nid_t pino)
{
	F2FS_I(inode)->i_pino = pino;
	mark_inode_dirty_sync(inode);
}

static inline void get_inline_info(struct inode *inode, struct f2fs_inode *ri)
{
	struct f2fs_inode_info *fi = F2FS_I(inode);

	if (ri->i_inline & F2FS_INLINE_XATTR)
		set_inode_flag(inode, FI_INLINE_XATTR);
		set_bit(FI_INLINE_XATTR, &fi->flags);
	if (ri->i_inline & F2FS_INLINE_DATA)
		set_inode_flag(inode, FI_INLINE_DATA);
		set_bit(FI_INLINE_DATA, &fi->flags);
	if (ri->i_inline & F2FS_INLINE_DENTRY)
		set_inode_flag(inode, FI_INLINE_DENTRY);
		set_bit(FI_INLINE_DENTRY, &fi->flags);
	if (ri->i_inline & F2FS_DATA_EXIST)
		set_inode_flag(inode, FI_DATA_EXIST);
		set_bit(FI_DATA_EXIST, &fi->flags);
	if (ri->i_inline & F2FS_INLINE_DOTS)
		set_inode_flag(inode, FI_INLINE_DOTS);
		set_bit(FI_INLINE_DOTS, &fi->flags);
}

static inline void set_raw_inline(struct inode *inode, struct f2fs_inode *ri)
@@ -1706,11 +1746,13 @@ static inline int is_file(struct inode *inode, int type)
static inline void set_file(struct inode *inode, int type)
{
	F2FS_I(inode)->i_advise |= type;
	mark_inode_dirty_sync(inode);
}

static inline void clear_file(struct inode *inode, int type)
{
	F2FS_I(inode)->i_advise &= ~type;
	mark_inode_dirty_sync(inode);
}

static inline int f2fs_readonly(struct super_block *sb)
+5 −7
Original line number Diff line number Diff line
@@ -171,11 +171,10 @@ static void try_to_fix_pino(struct inode *inode)
	fi->xattr_ver = 0;
	if (file_wrong_pino(inode) && inode->i_nlink == 1 &&
			get_parent_ino(inode, &pino)) {
		fi->i_pino = pino;
		f2fs_i_pino_write(inode, pino);
		file_got_pino(inode);
		up_write(&fi->i_sem);

		mark_inode_dirty_sync(inode);
		f2fs_write_inode(inode, NULL);
	} else {
		up_write(&fi->i_sem);
@@ -636,7 +635,7 @@ int f2fs_truncate(struct inode *inode, bool lock)
		return err;

	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	mark_inode_dirty(inode);
	mark_inode_dirty_sync(inode);
	return 0;
}

@@ -726,7 +725,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
		}
	}

	mark_inode_dirty(inode);
	mark_inode_dirty_sync(inode);
	return err;
}

@@ -1279,7 +1278,7 @@ static long f2fs_fallocate(struct file *file, int mode,

	if (!ret) {
		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
		mark_inode_dirty(inode);
		mark_inode_dirty_sync(inode);
		f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
	}

@@ -1370,9 +1369,8 @@ static int f2fs_ioc_setflags(struct file *filp, unsigned long arg)
	fi->i_flags = flags;
	inode_unlock(inode);

	f2fs_set_inode_flags(inode);
	inode->i_ctime = CURRENT_TIME;
	mark_inode_dirty(inode);
	f2fs_set_inode_flags(inode);
out:
	mnt_drop_write_file(filp);
	return ret;
Loading