aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-06-03 11:39:42 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-06-04 05:41:38 -0400
commitb6fe5873cb422417ae3fc914954bc5a10fd4e003 (patch)
treed9e958f62b4ed402a1b10e2592453320c6ff1447
parent1dbe4152168d44fa164edbdc9f1243de70b98f7a (diff)
f2fs: fix to recover data written by dio
If data are overwritten through dio, previous f2fs doesn't remain the fsync mark due to no additional node writes. Note that this patch should resolve the xfstests:311. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c3
-rw-r--r--fs/f2fs/f2fs.h1
-rw-r--r--fs/f2fs/node.c12
3 files changed, 16 insertions, 0 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8c250a5d6f26..39fe7d70791a 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1041,6 +1041,9 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
1041 if (check_direct_IO(inode, rw, iov, offset, nr_segs)) 1041 if (check_direct_IO(inode, rw, iov, offset, nr_segs))
1042 return 0; 1042 return 0;
1043 1043
1044 /* clear fsync mark to recover these blocks */
1045 fsync_mark_clear(F2FS_SB(inode->i_sb), inode->i_ino);
1046
1044 return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, 1047 return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
1045 get_data_block); 1048 get_data_block);
1046} 1049}
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9684b1f77a7d..f628c3c5e63f 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1168,6 +1168,7 @@ struct node_info;
1168bool available_free_memory(struct f2fs_sb_info *, int); 1168bool available_free_memory(struct f2fs_sb_info *, int);
1169int is_checkpointed_node(struct f2fs_sb_info *, nid_t); 1169int is_checkpointed_node(struct f2fs_sb_info *, nid_t);
1170bool fsync_mark_done(struct f2fs_sb_info *, nid_t); 1170bool fsync_mark_done(struct f2fs_sb_info *, nid_t);
1171void fsync_mark_clear(struct f2fs_sb_info *, nid_t);
1171void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *); 1172void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
1172int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int); 1173int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
1173int truncate_inode_blocks(struct inode *, pgoff_t); 1174int truncate_inode_blocks(struct inode *, pgoff_t);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 02a59e9027b1..a0a1f25ed20f 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -153,6 +153,18 @@ bool fsync_mark_done(struct f2fs_sb_info *sbi, nid_t nid)
153 return fsync_done; 153 return fsync_done;
154} 154}
155 155
156void fsync_mark_clear(struct f2fs_sb_info *sbi, nid_t nid)
157{
158 struct f2fs_nm_info *nm_i = NM_I(sbi);
159 struct nat_entry *e;
160
161 write_lock(&nm_i->nat_tree_lock);
162 e = __lookup_nat_cache(nm_i, nid);
163 if (e)
164 e->fsync_done = false;
165 write_unlock(&nm_i->nat_tree_lock);
166}
167
156static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid) 168static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid)
157{ 169{
158 struct nat_entry *new; 170 struct nat_entry *new;