f2fs: stop checkpoint only from fault injection
Jaegeuk Kim
maintainerPATCH 1/2 f2fs: stop checkpoint only from fault injection
If we got EIO by block layer, we still can proceed since EIO can be recovered. But, if we injected stop_checkpoint, we must stop everything.
This should fix generic/441 failure in xfstests.
--- fs/f2fs/checkpoint.c | 16 ++++------------ fs/f2fs/data.c | 8 ++------ fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 8 ++++---- fs/f2fs/gc.c | 2 +- fs/f2fs/inode.c | 2 +- fs/f2fs/segment.c | 2 +- 7 files changed, 14 insertions(+), 26 deletions(-)
fs/f2fs/checkpoint.c +4 -12
@@ -26,11 +26,10 @@static struct kmem_cache *ino_entry_slab;struct kmem_cache *inode_entry_slab; -void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi,bool end_io) +void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi) {set_ckpt_flags (sbi,CP_ERROR_FLAG ); -if (!end_io) -f2fs_flush_merged_writes (sbi); +f2fs_flush_merged_writes (sbi); }/*
@@ -89,18 +88,11 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, }lock_page (page); -if (unlikely (page->mapping != mapping)) { +/* If there is any IO error when accessing device, let's try again. */ +if (unlikely (page->mapping != mapping || !PageUptodate (page))) {f2fs_put_page (page,1 ); goto repeat; } - -/* -* if there is any IO error when accessing device, make our filesystem -* readonly and make sure do not write checkpoint with non-uptodate -* meta page. -*/ -if (unlikely (!PageUptodate (page))) -f2fs_stop_checkpoint (sbi, false); out:return page; }
fs/f2fs/data.c +2 -6
@@ -101,18 +101,14 @@ static void f2fs_write_end_io(struct bio *bio)ClearPagePrivate (page);unlock_page (page);mempool_free (page, sbi->write_io_dummy); - -if (unlikely (bio->bi_status)) -f2fs_stop_checkpoint (sbi, true);continue ; }fscrypt_pullback_bio_page (&page, true); -if (unlikely (bio->bi_status)) { +if (unlikely (bio->bi_status))mapping_set_error (page->mapping, -EIO ); -f2fs_stop_checkpoint (sbi, true); - } +dec_page_count (sbi, type);clear_cold_data (page);end_page_writeback (page);
fs/f2fs/f2fs.h +1 -1
@@ -2741,7 +2741,7 @@ int rw_hint_to_seg_type(enum rw_hint hint);/* * checkpoint.c */ -void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi,bool end_io); +void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi);struct page *grab_meta_page (struct f2fs_sb_info *sbi,pgoff_t index);struct page *get_meta_page (struct f2fs_sb_info *sbi,pgoff_t index);struct page *get_tmp_page (struct f2fs_sb_info *sbi,pgoff_t index);
fs/f2fs/file.c +4 -4
@@ -1840,21 +1840,21 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)case F2FS_GOING_DOWN_FULLSYNC : sb =freeze_bdev (sb->s_bdev);if (sb && !IS_ERR (sb)) { -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);thaw_bdev (sb->s_bdev, sb); }break ;case F2FS_GOING_DOWN_METASYNC :/* do checkpoint only */ f2fs_sync_fs (sb,1 ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;case F2FS_GOING_DOWN_NOSYNC : -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;case F2FS_GOING_DOWN_METAFLUSH :sync_meta_pages (sbi,META ,LONG_MAX ,FS_META_IO ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;default : ret = -EINVAL ;
fs/f2fs/gc.c +1 -1
@@ -56,7 +56,7 @@ static int gc_thread_func(void *data)#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject (sbi,FAULT_CHECKPOINT )) {f2fs_show_injection_info (FAULT_CHECKPOINT ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }#endif
fs/f2fs/inode.c +1 -1
@@ -441,7 +441,7 @@ void update_inode_page(struct inode *inode)cond_resched (); goto retry; }else if (err != -ENOENT ) { -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }return ; }
fs/f2fs/segment.c +1 -1
@@ -454,7 +454,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject (sbi,FAULT_CHECKPOINT )) {f2fs_show_injection_info (FAULT_CHECKPOINT ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }#endif
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Jaegeuk Kim
maintainerPATCH 2/2 f2fs: fix missing error number for xattr operation
This fixes generic/449 hang problem caused by no ENOSPC forever which should be returned by setxattr under disk full scenario.
--- fs/f2fs/xattr.c | 2 ++ 1 file changed, 2 insertions(+)
fs/f2fs/xattr.c +2 -0
@@ -433,6 +433,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,if (F2FS_I (inode)->i_xattr_nid) { xpage =get_node_page (sbi,F2FS_I (inode)->i_xattr_nid);if (IS_ERR (xpage)) { + err =PTR_ERR (xpage);alloc_nid_failed (sbi, new_nid); goto in_page_out; }
@@ -443,6 +444,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,set_new_dnode (&dn, inode,NULL ,NULL , new_nid); xpage =new_node_page (&dn,XATTR_NODE_OFFSET );if (IS_ERR (xpage)) { + err =PTR_ERR (xpage);alloc_nid_failed (sbi, new_nid); goto in_page_out; }
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Re: [f2fs-dev] [PATCH 2/2] f2fs: fix missing error number for xattr operation
Quoted 4 lines · Jaegeuk Kim
This fixes generic/449 hang problem caused by no ENOSPC forever which should be returned by setxattr under disk full scenario.
Signed-off-by Jaegeuk Kim <[email protected]>
Thanks,
Quoted 35 lines · Jaegeuk Kim
If we got EIO by block layer, we still can proceed since EIO can be recovered. But, if we injected
stop_checkpoint, we must stop everything.This should fix generic/441 failure in xfstests.
Signed-off-by Jaegeuk Kim <[email protected]>--- fs/f2fs/checkpoint.c | 16 ++++------------ fs/f2fs/data.c | 8 ++------ fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 8 ++++---- fs/f2fs/gc.c | 2 +- fs/f2fs/inode.c | 2 +- fs/f2fs/segment.c | 2 +- 7 files changed, 14 insertions(+), 26 deletions(-)fs/f2fs/checkpoint.c +2
-3@@ -26,11 +26,10 @@static struct kmem_cache *ino_entry_slab;struct kmem_cache *inode_entry_slab; -void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi,bool end_io) +void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi) {set_ckpt_flags (sbi,CP_ERROR_FLAG ); -if (!end_io) -f2fs_flush_merged_writes (sbi); +f2fs_flush_merged_writes (sbi); }/*
fs/f2fs/checkpoint.c static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, · line 92
Quoted 6 lines
fs/f2fs/checkpoint.c +2
-1@@ -89,18 +88,11 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index, }lock_page (page); -if (unlikely (page->mapping != mapping)) { +/* If there is any IO error when accessing device, let's try again. */ +if (unlikely (page->mapping != mapping || !PageUptodate (page))) {
If IO error is not recovered, we will run into endless loop?
Quoted 24 lines
fs/f2fs/checkpoint.c +0
-8f2fs_put_page (page,1 ); goto repeat; } - -/* -* if there is any IO error when accessing device, make our filesystem -* readonly and make sure do not write checkpoint with non-uptodate -* meta page. -*/ -if (unlikely (!PageUptodate (page))) -f2fs_stop_checkpoint (sbi, false); out:return page; }fs/f2fs/data.c +0
-2@@ -101,18 +101,14 @@ static void f2fs_write_end_io(struct bio *bio)ClearPagePrivate (page);unlock_page (page);mempool_free (page, sbi->write_io_dummy); - -if (unlikely (bio->bi_status))
fs/f2fs/data.c static void f2fs_write_end_io(struct bio *bio) · line 114
Quoted 10 lines
fs/f2fs/data.c +1
-3-f2fs_stop_checkpoint (sbi, true);continue ; }fscrypt_pullback_bio_page (&page, true); -if (unlikely (bio->bi_status)) { +if (unlikely (bio->bi_status))mapping_set_error (page->mapping, -EIO ); -f2fs_stop_checkpoint (sbi, true);
If we do not stop checkpoint here, fs meta/node data and user data can be more and more corrupted and inconsistent... at least, we should stop checkpoint if there is EIO when we writeback fs meta/node data.
Thanks,
Quoted 88 lines
fs/f2fs/data.c +1
-1- } +dec_page_count (sbi, type);clear_cold_data (page);end_page_writeback (page);fs/f2fs/f2fs.h +1
-1@@ -2741,7 +2741,7 @@ int rw_hint_to_seg_type(enum rw_hint hint);/* * checkpoint.c */ -void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi,bool end_io); +void f2fs_stop_checkpoint (struct f2fs_sb_info *sbi);struct page *grab_meta_page (struct f2fs_sb_info *sbi,pgoff_t index);struct page *get_meta_page (struct f2fs_sb_info *sbi,pgoff_t index);struct page *get_tmp_page (struct f2fs_sb_info *sbi,pgoff_t index);fs/f2fs/file.c +4
-4@@ -1840,21 +1840,21 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)case F2FS_GOING_DOWN_FULLSYNC : sb =freeze_bdev (sb->s_bdev);if (sb && !IS_ERR (sb)) { -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);thaw_bdev (sb->s_bdev, sb); }break ;case F2FS_GOING_DOWN_METASYNC :/* do checkpoint only */ f2fs_sync_fs (sb,1 ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;case F2FS_GOING_DOWN_NOSYNC : -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;case F2FS_GOING_DOWN_METAFLUSH :sync_meta_pages (sbi,META ,LONG_MAX ,FS_META_IO ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi);break ;default : ret = -EINVAL ;fs/f2fs/gc.c +1
-1@@ -56,7 +56,7 @@ static int gc_thread_func(void *data)#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject (sbi,FAULT_CHECKPOINT )) {f2fs_show_injection_info (FAULT_CHECKPOINT ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }#endif fs/f2fs/inode.c +1
-1@@ -441,7 +441,7 @@ void update_inode_page(struct inode *inode)cond_resched (); goto retry; }else if (err != -ENOENT ) { -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }return ; }fs/f2fs/segment.c +1
-1@@ -454,7 +454,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject (sbi,FAULT_CHECKPOINT )) {f2fs_show_injection_info (FAULT_CHECKPOINT ); -f2fs_stop_checkpoint (sbi, false); +f2fs_stop_checkpoint (sbi); }#endif
Jaegeuk Kim
maintainerWe can give another chance to write user data, which can resolve generic/441.
---
Change log from v1:
- skip stop_checkpoint for user data writes
fs/f2fs/data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/f2fs/data.c +2 -1
@@ -111,7 +111,8 @@ static void f2fs_write_end_io(struct bio *bio)if (unlikely (bio->bi_status)) {mapping_set_error (page->mapping, -EIO ); -f2fs_stop_checkpoint (sbi, true); +if (type ==F2FS_WB_CP_DATA ) +f2fs_stop_checkpoint (sbi, true); }dec_page_count (sbi, type);clear_cold_data (page);
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Chao Yu
Reviewed-byQuoted 4 lines · Jaegeuk Kim
We can give another chance to write user data, which can resolve generic/441.
Signed-off-by Jaegeuk Kim <[email protected]>
Thanks,