aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-07-25 10:40:59 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2014-07-29 10:46:11 -0400
commitfff04f90c1b9f91b9c513a89702a4b9ffe5dc1c5 (patch)
tree93d2a63cedd9e181849cf75feda52eb5f1f2032f
parent39efac41fbe44343cac29472320a1d502fcff66b (diff)
f2fs: add info of appended or updated data writes
This patch introduces a inode number list in which represents inodes having appended data writes or updated data writes after last checkpoint. This will be used at fsync to determine whether the recovery information should be written or not. Reviewed-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/checkpoint.c39
-rw-r--r--fs/f2fs/data.c2
-rw-r--r--fs/f2fs/f2fs.h7
-rw-r--r--fs/f2fs/inline.c1
-rw-r--r--fs/f2fs/inode.c4
5 files changed, 53 insertions, 0 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 4bf203756cf8..430163d8c806 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -326,6 +326,44 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
326 spin_unlock(&sbi->ino_lock[type]); 326 spin_unlock(&sbi->ino_lock[type]);
327} 327}
328 328
329void add_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type)
330{
331 /* add new dirty ino entry into list */
332 __add_ino_entry(sbi, ino, type);
333}
334
335void remove_dirty_inode(struct f2fs_sb_info *sbi, nid_t ino, int type)
336{
337 /* remove dirty ino entry from list */
338 __remove_ino_entry(sbi, ino, type);
339}
340
341/* mode should be APPEND_INO or UPDATE_INO */
342bool exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
343{
344 struct ino_entry *e;
345 spin_lock(&sbi->ino_lock[mode]);
346 e = radix_tree_lookup(&sbi->ino_root[mode], ino);
347 spin_unlock(&sbi->ino_lock[mode]);
348 return e ? true : false;
349}
350
351static void release_dirty_inode(struct f2fs_sb_info *sbi)
352{
353 struct ino_entry *e, *tmp;
354 int i;
355
356 for (i = APPEND_INO; i <= UPDATE_INO; i++) {
357 spin_lock(&sbi->ino_lock[i]);
358 list_for_each_entry_safe(e, tmp, &sbi->ino_list[i], list) {
359 list_del(&e->list);
360 radix_tree_delete(&sbi->ino_root[i], e->ino);
361 kmem_cache_free(ino_entry_slab, e);
362 }
363 spin_unlock(&sbi->ino_lock[i]);
364 }
365}
366
329int acquire_orphan_inode(struct f2fs_sb_info *sbi) 367int acquire_orphan_inode(struct f2fs_sb_info *sbi)
330{ 368{
331 int err = 0; 369 int err = 0;
@@ -897,6 +935,7 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
897 935
898 if (unlikely(!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG))) { 936 if (unlikely(!is_set_ckpt_flags(ckpt, CP_ERROR_FLAG))) {
899 clear_prefree_segments(sbi); 937 clear_prefree_segments(sbi);
938 release_dirty_inode(sbi);
900 F2FS_RESET_SB_DIRT(sbi); 939 F2FS_RESET_SB_DIRT(sbi);
901 } 940 }
902} 941}
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 482313dd9e24..ec3c8860539e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -789,9 +789,11 @@ int do_write_data_page(struct page *page, struct f2fs_io_info *fio)
789 !is_cold_data(page) && 789 !is_cold_data(page) &&
790 need_inplace_update(inode))) { 790 need_inplace_update(inode))) {
791 rewrite_data_page(page, old_blkaddr, fio); 791 rewrite_data_page(page, old_blkaddr, fio);
792 set_inode_flag(F2FS_I(inode), FI_UPDATE_WRITE);
792 } else { 793 } else {
793 write_data_page(page, &dn, &new_blkaddr, fio); 794 write_data_page(page, &dn, &new_blkaddr, fio);
794 update_extent_cache(new_blkaddr, &dn); 795 update_extent_cache(new_blkaddr, &dn);
796 set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE);
795 } 797 }
796out_writepage: 798out_writepage:
797 f2fs_put_dnode(&dn); 799 f2fs_put_dnode(&dn);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4454caa8a253..ab3602576fb2 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -103,6 +103,8 @@ enum {
103/* for the list of ino */ 103/* for the list of ino */
104enum { 104enum {
105 ORPHAN_INO, /* for orphan ino list */ 105 ORPHAN_INO, /* for orphan ino list */
106 APPEND_INO, /* for append ino list */
107 UPDATE_INO, /* for update ino list */
106 MAX_INO_ENTRY, /* max. list */ 108 MAX_INO_ENTRY, /* max. list */
107}; 109};
108 110
@@ -994,6 +996,8 @@ enum {
994 FI_NO_EXTENT, /* not to use the extent cache */ 996 FI_NO_EXTENT, /* not to use the extent cache */
995 FI_INLINE_XATTR, /* used for inline xattr */ 997 FI_INLINE_XATTR, /* used for inline xattr */
996 FI_INLINE_DATA, /* used for inline data*/ 998 FI_INLINE_DATA, /* used for inline data*/
999 FI_APPEND_WRITE, /* inode has appended data */
1000 FI_UPDATE_WRITE, /* inode has in-place-update data */
997}; 1001};
998 1002
999static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag) 1003static inline void set_inode_flag(struct f2fs_inode_info *fi, int flag)
@@ -1252,6 +1256,9 @@ struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
1252struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t); 1256struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
1253int ra_meta_pages(struct f2fs_sb_info *, int, int, int); 1257int ra_meta_pages(struct f2fs_sb_info *, int, int, int);
1254long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long); 1258long sync_meta_pages(struct f2fs_sb_info *, enum page_type, long);
1259void add_dirty_inode(struct f2fs_sb_info *, nid_t, int type);
1260void remove_dirty_inode(struct f2fs_sb_info *, nid_t, int type);
1261bool exist_written_data(struct f2fs_sb_info *, nid_t, int);
1255int acquire_orphan_inode(struct f2fs_sb_info *); 1262int acquire_orphan_inode(struct f2fs_sb_info *);
1256void release_orphan_inode(struct f2fs_sb_info *); 1263void release_orphan_inode(struct f2fs_sb_info *);
1257void add_orphan_inode(struct f2fs_sb_info *, nid_t); 1264void add_orphan_inode(struct f2fs_sb_info *, nid_t);
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 1bba5228c197..5beeccef9ae1 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -172,6 +172,7 @@ int f2fs_write_inline_data(struct inode *inode,
172 stat_inc_inline_inode(inode); 172 stat_inc_inline_inode(inode);
173 } 173 }
174 174
175 set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE);
175 sync_inode_page(&dn); 176 sync_inode_page(&dn);
176 f2fs_put_dnode(&dn); 177 f2fs_put_dnode(&dn);
177 178
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index cafba3c9f8d8..0e69aa90238d 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -296,6 +296,10 @@ void f2fs_evict_inode(struct inode *inode)
296 sb_end_intwrite(inode->i_sb); 296 sb_end_intwrite(inode->i_sb);
297no_delete: 297no_delete:
298 invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino); 298 invalidate_mapping_pages(NODE_MAPPING(sbi), inode->i_ino, inode->i_ino);
299 if (is_inode_flag_set(F2FS_I(inode), FI_APPEND_WRITE))
300 add_dirty_inode(sbi, inode->i_ino, APPEND_INO);
301 if (is_inode_flag_set(F2FS_I(inode), FI_UPDATE_WRITE))
302 add_dirty_inode(sbi, inode->i_ino, UPDATE_INO);
299out_clear: 303out_clear:
300 clear_inode(inode); 304 clear_inode(inode);
301} 305}