aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-08-09 01:46:15 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-08-09 02:25:24 -0400
commite518ff81c337e39b9b63d92ba41e4512521d7c9c (patch)
tree9e576b0984e21e4ab3a4515bab29864d63fbcf01 /fs
parentdbe6a5ff4fa78bdfa983458c338831d91b35f315 (diff)
f2fs: fix inconsistency between xattr node blocks and its inode
Previously xattr node blocks are stored to the COLD_NODE log, which means that our roll-forward mechanism doesn't recover the xattr node blocks at all. Only the direct node blocks in the WARM_NODE log can be recovered. So, let's resolve the issue simply by conducting checkpoint during fsync when a file has a modified xattr node block. This approach is able to degrade the performance, but normally the checkpoint overhead is shown at the initial fsync call after the xattr entry changes. Once the checkpoint is done, no additional overhead would be occurred. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/f2fs/f2fs.h1
-rw-r--r--fs/f2fs/file.c5
-rw-r--r--fs/f2fs/xattr.c4
3 files changed, 10 insertions, 0 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index eb8c45b65fe5..c1c9670e642f 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -181,6 +181,7 @@ struct f2fs_inode_info {
181 f2fs_hash_t chash; /* hash value of given file name */ 181 f2fs_hash_t chash; /* hash value of given file name */
182 unsigned int clevel; /* maximum level of given file name */ 182 unsigned int clevel; /* maximum level of given file name */
183 nid_t i_xattr_nid; /* node id that contains xattrs */ 183 nid_t i_xattr_nid; /* node id that contains xattrs */
184 unsigned long long xattr_ver; /* cp version of xattr modification */
184 struct extent_info ext; /* in-memory extent cache entry */ 185 struct extent_info ext; /* in-memory extent cache entry */
185}; 186};
186 187
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index c2deb27ffb72..8ef3184b0037 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -161,10 +161,15 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
161 need_cp = true; 161 need_cp = true;
162 else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino)) 162 else if (!is_checkpointed_node(sbi, F2FS_I(inode)->i_pino))
163 need_cp = true; 163 need_cp = true;
164 else if (F2FS_I(inode)->xattr_ver ==
165 le64_to_cpu(F2FS_CKPT(sbi)->checkpoint_ver))
166 need_cp = true;
164 167
165 if (need_cp) { 168 if (need_cp) {
166 nid_t pino; 169 nid_t pino;
167 170
171 F2FS_I(inode)->xattr_ver = 0;
172
168 /* all the dirty node pages should be flushed for POR */ 173 /* all the dirty node pages should be flushed for POR */
169 ret = f2fs_sync_fs(inode->i_sb, 1); 174 ret = f2fs_sync_fs(inode->i_sb, 1);
170 if (file_wrong_pino(inode) && inode->i_nlink == 1 && 175 if (file_wrong_pino(inode) && inode->i_nlink == 1 &&
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 3ab07ecd86ca..0f6d2a1b9a7a 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -486,6 +486,10 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
486 inode->i_ctime = CURRENT_TIME; 486 inode->i_ctime = CURRENT_TIME;
487 clear_inode_flag(fi, FI_ACL_MODE); 487 clear_inode_flag(fi, FI_ACL_MODE);
488 } 488 }
489
490 /* store checkpoint version for conducting checkpoint during fsync */
491 fi->xattr_ver = le64_to_cpu(F2FS_CKPT(sbi)->checkpoint_ver);
492
489 if (ipage) 493 if (ipage)
490 update_inode(inode, ipage); 494 update_inode(inode, ipage);
491 else 495 else