]> git.baikalelectronics.ru Git - kernel.git/commitdiff
f2fs: flush pending bios right away when error occurs
authorJaegeuk Kim <jaegeuk@kernel.org>
Wed, 18 May 2016 21:07:56 +0000 (14:07 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 20 May 2016 18:46:15 +0000 (11:46 -0700)
Given errors, this patch flushes pending bios as soon as possible.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/checkpoint.c
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/inode.c

index cf79598aec0ef4f949c5cb1f0ac2e6e710cbfdd7..3891600499939895600bfc9aed37c6f2b5e1d53d 100644 (file)
 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)
+{
+       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
+       sbi->sb->s_flags |= MS_RDONLY;
+       if (!end_io)
+               f2fs_flush_merged_bios(sbi);
+}
+
 /*
  * We guarantee no failure on the returned page.
  */
@@ -91,7 +99,7 @@ repeat:
         * meta page.
         */
        if (unlikely(!PageUptodate(page)))
-               f2fs_stop_checkpoint(sbi);
+               f2fs_stop_checkpoint(sbi, false);
 out:
        return page;
 }
index faef6667ba459e6e6eb54f87ca22bfafd6a27b45..105dd3d5cf5ecb6230e95f05b6e2849ce68b3392 100644 (file)
@@ -68,7 +68,7 @@ static void f2fs_write_end_io(struct bio *bio)
 
                if (unlikely(bio->bi_error)) {
                        set_bit(AS_EIO, &page->mapping->flags);
-                       f2fs_stop_checkpoint(sbi);
+                       f2fs_stop_checkpoint(sbi, true);
                }
                end_page_writeback(page);
        }
index 02f0656cb2ab1fd4668f82dadda1f00b674f1a01..916e7c238e3d14a9da4a91e965ff570d0dc91232 100644 (file)
@@ -1698,12 +1698,6 @@ static inline bool f2fs_cp_error(struct f2fs_sb_info *sbi)
        return is_set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
 }
 
-static inline void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi)
-{
-       set_ckpt_flags(sbi->ckpt, CP_ERROR_FLAG);
-       sbi->sb->s_flags |= MS_RDONLY;
-}
-
 static inline bool is_dot_dotdot(const struct qstr *str)
 {
        if (str->len == 1 && str->name[0] == '.')
@@ -1937,6 +1931,7 @@ void destroy_segment_manager_caches(void);
 /*
  * checkpoint.c
  */
+void f2fs_stop_checkpoint(struct f2fs_sb_info *, bool);
 struct page *grab_meta_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_meta_page(struct f2fs_sb_info *, pgoff_t);
 struct page *get_tmp_page(struct f2fs_sb_info *, pgoff_t);
index 69dd7c9cdd6a6b1c14c4343e8bcc7e71de058ac2..4c2125499da077c0f07d87b68a3852271934d9b3 100644 (file)
@@ -1571,21 +1571,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);
+                       f2fs_stop_checkpoint(sbi, false);
                        thaw_bdev(sb->s_bdev, sb);
                }
                break;
        case F2FS_GOING_DOWN_METASYNC:
                /* do checkpoint only */
                f2fs_sync_fs(sb, 1);
-               f2fs_stop_checkpoint(sbi);
+               f2fs_stop_checkpoint(sbi, false);
                break;
        case F2FS_GOING_DOWN_NOSYNC:
-               f2fs_stop_checkpoint(sbi);
+               f2fs_stop_checkpoint(sbi, false);
                break;
        case F2FS_GOING_DOWN_METAFLUSH:
                sync_meta_pages(sbi, META, LONG_MAX);
-               f2fs_stop_checkpoint(sbi);
+               f2fs_stop_checkpoint(sbi, false);
                break;
        default:
                ret = -EINVAL;
index 689d6914e2e405cd2788ccafb3e6bea5b1fd2dd0..2e68adab0d645b7df68419829d5e8c4809a8c2a9 100644 (file)
@@ -283,7 +283,7 @@ retry:
                        cond_resched();
                        goto retry;
                } else if (err != -ENOENT) {
-                       f2fs_stop_checkpoint(sbi);
+                       f2fs_stop_checkpoint(sbi, false);
                }
                return 0;
        }