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

Commit 6b863986 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: remain written times to update inode during fsync



This fixes xfstests/generic/392.

The failure was caused by different times between 1) one marked in the last
fsync(2) call and 2) the other given by roll-forward recovery after power-cut.
The reason was that we skipped updating inode block at 1), since its i_size
was recoverable along with 4KB-aligned data writes, which was fixed by:
  "f2fs: fix a wrong condition in f2fs_skip_inode_update"

Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 7e1903bc
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -762,6 +762,7 @@ struct f2fs_inode_info {
	kprojid_t i_projid;		/* id for project quota */
	int i_inline_xattr_size;	/* inline xattr size */
	struct timespec i_crtime;	/* inode creation time */
	struct timespec i_disk_time[4];	/* inode disk times */
};

static inline void get_extent_info(struct extent_info *ext,
@@ -2572,6 +2573,16 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
			i_size_read(inode) & ~PAGE_MASK)
		return false;

	if (!timespec_equal(F2FS_I(inode)->i_disk_time, &inode->i_atime))
		return false;
	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 1, &inode->i_ctime))
		return false;
	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 2, &inode->i_mtime))
		return false;
	if (!timespec_equal(F2FS_I(inode)->i_disk_time + 3,
						&F2FS_I(inode)->i_crtime))
		return false;

	down_read(&F2FS_I(inode)->i_sem);
	ret = F2FS_I(inode)->last_disk_size == i_size_read(inode);
	up_read(&F2FS_I(inode)->i_sem);
+8 −0
Original line number Diff line number Diff line
@@ -284,6 +284,10 @@ static int do_read_inode(struct inode *inode)
		fi->i_crtime.tv_nsec = le32_to_cpu(ri->i_crtime_nsec);
	}

	F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
	F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
	F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
	F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
	f2fs_put_page(node_page, 1);

	stat_inc_inline_xattr(inode);
@@ -444,6 +448,10 @@ void update_inode(struct inode *inode, struct page *node_page)
	if (inode->i_nlink == 0)
		clear_inline_node(node_page);

	F2FS_I(inode)->i_disk_time[0] = inode->i_atime;
	F2FS_I(inode)->i_disk_time[1] = inode->i_ctime;
	F2FS_I(inode)->i_disk_time[2] = inode->i_mtime;
	F2FS_I(inode)->i_disk_time[3] = F2FS_I(inode)->i_crtime;
}

void update_inode_page(struct inode *inode)