f2fs: fix to recover data written by dio
authorJaegeuk Kim <jaegeuk@kernel.org>
Tue, 3 Jun 2014 15:39:42 +0000 (00:39 +0900)
committerJaegeuk Kim <jaegeuk@kernel.org>
Wed, 4 Jun 2014 09:41:38 +0000 (18:41 +0900)
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>
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/node.c

index 8c250a5d6f261aef113b39226beb6e625d6442a2..39fe7d70791a2671b5bf363543b1c33652414027 100644 (file)
@@ -1041,6 +1041,9 @@ static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
        if (check_direct_IO(inode, rw, iov, offset, nr_segs))
                return 0;
 
+       /* clear fsync mark to recover these blocks */
+       fsync_mark_clear(F2FS_SB(inode->i_sb), inode->i_ino);
+
        return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
                                                        get_data_block);
 }
index 9684b1f77a7d7e373c9b22183f3f5c47ed634d9f..f628c3c5e63faf3b7834190705906358a6bd4ed5 100644 (file)
@@ -1168,6 +1168,7 @@ struct node_info;
 bool available_free_memory(struct f2fs_sb_info *, int);
 int is_checkpointed_node(struct f2fs_sb_info *, nid_t);
 bool fsync_mark_done(struct f2fs_sb_info *, nid_t);
+void fsync_mark_clear(struct f2fs_sb_info *, nid_t);
 void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
 int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
 int truncate_inode_blocks(struct inode *, pgoff_t);
index 02a59e9027b193a997e46c3dd279e84456bdf5e5..a0a1f25ed20f99ca378f4653793c07c26334598c 100644 (file)
@@ -153,6 +153,18 @@ bool fsync_mark_done(struct f2fs_sb_info *sbi, nid_t nid)
        return fsync_done;
 }
 
+void fsync_mark_clear(struct f2fs_sb_info *sbi, nid_t nid)
+{
+       struct f2fs_nm_info *nm_i = NM_I(sbi);
+       struct nat_entry *e;
+
+       write_lock(&nm_i->nat_tree_lock);
+       e = __lookup_nat_cache(nm_i, nid);
+       if (e)
+               e->fsync_done = false;
+       write_unlock(&nm_i->nat_tree_lock);
+}
+
 static struct nat_entry *grab_nat_entry(struct f2fs_nm_info *nm_i, nid_t nid)
 {
        struct nat_entry *new;