diff options
Diffstat (limited to 'fs/f2fs/super.c')
-rw-r--r-- | fs/f2fs/super.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 657582fc7601..41bdf511003d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -432,9 +432,15 @@ static void f2fs_put_super(struct super_block *sb) | |||
432 | stop_gc_thread(sbi); | 432 | stop_gc_thread(sbi); |
433 | 433 | ||
434 | /* We don't need to do checkpoint when it's clean */ | 434 | /* We don't need to do checkpoint when it's clean */ |
435 | if (sbi->s_dirty && get_pages(sbi, F2FS_DIRTY_NODES)) | 435 | if (sbi->s_dirty) |
436 | write_checkpoint(sbi, true); | 436 | write_checkpoint(sbi, true); |
437 | 437 | ||
438 | /* | ||
439 | * normally superblock is clean, so we need to release this. | ||
440 | * In addition, EIO will skip do checkpoint, we need this as well. | ||
441 | */ | ||
442 | release_dirty_inode(sbi); | ||
443 | |||
438 | iput(sbi->node_inode); | 444 | iput(sbi->node_inode); |
439 | iput(sbi->meta_inode); | 445 | iput(sbi->meta_inode); |
440 | 446 | ||
@@ -457,9 +463,6 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
457 | 463 | ||
458 | trace_f2fs_sync_fs(sb, sync); | 464 | trace_f2fs_sync_fs(sb, sync); |
459 | 465 | ||
460 | if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) | ||
461 | return 0; | ||
462 | |||
463 | if (sync) { | 466 | if (sync) { |
464 | mutex_lock(&sbi->gc_mutex); | 467 | mutex_lock(&sbi->gc_mutex); |
465 | write_checkpoint(sbi, false); | 468 | write_checkpoint(sbi, false); |
@@ -505,8 +508,8 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
505 | buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; | 508 | buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; |
506 | buf->f_bavail = user_block_count - valid_user_blocks(sbi); | 509 | buf->f_bavail = user_block_count - valid_user_blocks(sbi); |
507 | 510 | ||
508 | buf->f_files = sbi->total_node_count; | 511 | buf->f_files = sbi->total_node_count - F2FS_RESERVED_NODE_NUM; |
509 | buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi); | 512 | buf->f_ffree = buf->f_files - valid_inode_count(sbi); |
510 | 513 | ||
511 | buf->f_namelen = F2FS_NAME_LEN; | 514 | buf->f_namelen = F2FS_NAME_LEN; |
512 | buf->f_fsid.val[0] = (u32)id; | 515 | buf->f_fsid.val[0] = (u32)id; |
@@ -663,7 +666,7 @@ restore_gc: | |||
663 | if (need_restart_gc) { | 666 | if (need_restart_gc) { |
664 | if (start_gc_thread(sbi)) | 667 | if (start_gc_thread(sbi)) |
665 | f2fs_msg(sbi->sb, KERN_WARNING, | 668 | f2fs_msg(sbi->sb, KERN_WARNING, |
666 | "background gc thread is stop"); | 669 | "background gc thread has stopped"); |
667 | } else if (need_stop_gc) { | 670 | } else if (need_stop_gc) { |
668 | stop_gc_thread(sbi); | 671 | stop_gc_thread(sbi); |
669 | } | 672 | } |
@@ -812,7 +815,7 @@ static int sanity_check_ckpt(struct f2fs_sb_info *sbi) | |||
812 | if (unlikely(fsmeta >= total)) | 815 | if (unlikely(fsmeta >= total)) |
813 | return 1; | 816 | return 1; |
814 | 817 | ||
815 | if (unlikely(is_set_ckpt_flags(ckpt, CP_ERROR_FLAG))) { | 818 | if (unlikely(f2fs_cp_error(sbi))) { |
816 | f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); | 819 | f2fs_msg(sbi->sb, KERN_ERR, "A bug case: need to run fsck"); |
817 | return 1; | 820 | return 1; |
818 | } | 821 | } |
@@ -899,8 +902,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
899 | struct buffer_head *raw_super_buf; | 902 | struct buffer_head *raw_super_buf; |
900 | struct inode *root; | 903 | struct inode *root; |
901 | long err = -EINVAL; | 904 | long err = -EINVAL; |
905 | bool retry = true; | ||
902 | int i; | 906 | int i; |
903 | 907 | ||
908 | try_onemore: | ||
904 | /* allocate memory for f2fs-specific super block info */ | 909 | /* allocate memory for f2fs-specific super block info */ |
905 | sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); | 910 | sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); |
906 | if (!sbi) | 911 | if (!sbi) |
@@ -1080,9 +1085,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
1080 | /* recover fsynced data */ | 1085 | /* recover fsynced data */ |
1081 | if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { | 1086 | if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) { |
1082 | err = recover_fsync_data(sbi); | 1087 | err = recover_fsync_data(sbi); |
1083 | if (err) | 1088 | if (err) { |
1084 | f2fs_msg(sb, KERN_ERR, | 1089 | f2fs_msg(sb, KERN_ERR, |
1085 | "Cannot recover all fsync data errno=%ld", err); | 1090 | "Cannot recover all fsync data errno=%ld", err); |
1091 | goto free_kobj; | ||
1092 | } | ||
1086 | } | 1093 | } |
1087 | 1094 | ||
1088 | /* | 1095 | /* |
@@ -1123,6 +1130,13 @@ free_sb_buf: | |||
1123 | brelse(raw_super_buf); | 1130 | brelse(raw_super_buf); |
1124 | free_sbi: | 1131 | free_sbi: |
1125 | kfree(sbi); | 1132 | kfree(sbi); |
1133 | |||
1134 | /* give only one another chance */ | ||
1135 | if (retry) { | ||
1136 | retry = 0; | ||
1137 | shrink_dcache_sb(sb); | ||
1138 | goto try_onemore; | ||
1139 | } | ||
1126 | return err; | 1140 | return err; |
1127 | } | 1141 | } |
1128 | 1142 | ||