aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-04-15 16:37:53 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2015-04-16 12:45:35 -0400
commitd0cae97cb600d84a7e00df6f83ab3b2f60d8d7f7 (patch)
tree5b57f4664b0f18b102cbf92e9ca05b0dc8d5e3e3 /fs/f2fs
parent9df47ba759e40ea2facd0601d4888abb37ed9658 (diff)
f2fs: flush symlink path to avoid broken symlink after POR
This patch tries to avoid broken symlink case after POR in best effort. This results in performance regression. But, if f2fs has inline_data and the target path is under 3KB-sized long, the page would be stored in its inode_block, so that there would be no performance regression. Note that, if user wants to keep this file atomically, it needs to trigger dir->fsync. And, there is still a hole to produce broken symlink. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/namei.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 8055e30eb14d..9f0eec4677fe 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -324,6 +324,17 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
324 d_instantiate(dentry, inode); 324 d_instantiate(dentry, inode);
325 unlock_new_inode(inode); 325 unlock_new_inode(inode);
326 326
327 /*
328 * Let's flush symlink data in order to avoid broken symlink as much as
329 * possible. Nevertheless, fsyncing is the best way, but there is no
330 * way to get a file descriptor in order to flush that.
331 *
332 * Note that, it needs to do dir->fsync to make this recoverable.
333 * If the symlink path is stored into inline_data, there is no
334 * performance regression.
335 */
336 filemap_write_and_wait_range(inode->i_mapping, 0, symlen - 1);
337
327 if (IS_DIRSYNC(dir)) 338 if (IS_DIRSYNC(dir))
328 f2fs_sync_fs(sbi->sb, 1); 339 f2fs_sync_fs(sbi->sb, 1);
329 return err; 340 return err;