@@ -2213,6 +2213,24 @@ static void __move_free_nid(struct f2fs_sb_info *sbi, struct free_nid *i,
2213
2213
}
2214
2214
}
2215
2215
2216
+ bool f2fs_nat_bitmap_enabled (struct f2fs_sb_info * sbi )
2217
+ {
2218
+ struct f2fs_nm_info * nm_i = NM_I (sbi );
2219
+ unsigned int i ;
2220
+ bool ret = true;
2221
+
2222
+ down_read (& nm_i -> nat_tree_lock );
2223
+ for (i = 0 ; i < nm_i -> nat_blocks ; i ++ ) {
2224
+ if (!test_bit_le (i , nm_i -> nat_block_bitmap )) {
2225
+ ret = false;
2226
+ break ;
2227
+ }
2228
+ }
2229
+ up_read (& nm_i -> nat_tree_lock );
2230
+
2231
+ return ret ;
2232
+ }
2233
+
2216
2234
static void update_free_nid_bitmap (struct f2fs_sb_info * sbi , nid_t nid ,
2217
2235
bool set , bool build )
2218
2236
{
@@ -2884,7 +2902,23 @@ static void __adjust_nat_entry_set(struct nat_entry_set *nes,
2884
2902
list_add_tail (& nes -> set_list , head );
2885
2903
}
2886
2904
2887
- static void __update_nat_bits (struct f2fs_sb_info * sbi , nid_t start_nid ,
2905
+ static void __update_nat_bits (struct f2fs_nm_info * nm_i , unsigned int nat_ofs ,
2906
+ unsigned int valid )
2907
+ {
2908
+ if (valid == 0 ) {
2909
+ __set_bit_le (nat_ofs , nm_i -> empty_nat_bits );
2910
+ __clear_bit_le (nat_ofs , nm_i -> full_nat_bits );
2911
+ return ;
2912
+ }
2913
+
2914
+ __clear_bit_le (nat_ofs , nm_i -> empty_nat_bits );
2915
+ if (valid == NAT_ENTRY_PER_BLOCK )
2916
+ __set_bit_le (nat_ofs , nm_i -> full_nat_bits );
2917
+ else
2918
+ __clear_bit_le (nat_ofs , nm_i -> full_nat_bits );
2919
+ }
2920
+
2921
+ static void update_nat_bits (struct f2fs_sb_info * sbi , nid_t start_nid ,
2888
2922
struct page * page )
2889
2923
{
2890
2924
struct f2fs_nm_info * nm_i = NM_I (sbi );
@@ -2893,7 +2927,7 @@ static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
2893
2927
int valid = 0 ;
2894
2928
int i = 0 ;
2895
2929
2896
- if (!enabled_nat_bits (sbi , NULL ))
2930
+ if (!is_set_ckpt_flags (sbi , CP_NAT_BITS_FLAG ))
2897
2931
return ;
2898
2932
2899
2933
if (nat_index == 0 ) {
@@ -2904,17 +2938,36 @@ static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid,
2904
2938
if (le32_to_cpu (nat_blk -> entries [i ].block_addr ) != NULL_ADDR )
2905
2939
valid ++ ;
2906
2940
}
2907
- if (valid == 0 ) {
2908
- __set_bit_le (nat_index , nm_i -> empty_nat_bits );
2909
- __clear_bit_le (nat_index , nm_i -> full_nat_bits );
2910
- return ;
2941
+
2942
+ __update_nat_bits (nm_i , nat_index , valid );
2943
+ }
2944
+
2945
+ void f2fs_enable_nat_bits (struct f2fs_sb_info * sbi )
2946
+ {
2947
+ struct f2fs_nm_info * nm_i = NM_I (sbi );
2948
+ unsigned int nat_ofs ;
2949
+
2950
+ down_read (& nm_i -> nat_tree_lock );
2951
+
2952
+ for (nat_ofs = 0 ; nat_ofs < nm_i -> nat_blocks ; nat_ofs ++ ) {
2953
+ unsigned int valid = 0 , nid_ofs = 0 ;
2954
+
2955
+ /* handle nid zero due to it should never be used */
2956
+ if (unlikely (nat_ofs == 0 )) {
2957
+ valid = 1 ;
2958
+ nid_ofs = 1 ;
2959
+ }
2960
+
2961
+ for (; nid_ofs < NAT_ENTRY_PER_BLOCK ; nid_ofs ++ ) {
2962
+ if (!test_bit_le (nid_ofs ,
2963
+ nm_i -> free_nid_bitmap [nat_ofs ]))
2964
+ valid ++ ;
2965
+ }
2966
+
2967
+ __update_nat_bits (nm_i , nat_ofs , valid );
2911
2968
}
2912
2969
2913
- __clear_bit_le (nat_index , nm_i -> empty_nat_bits );
2914
- if (valid == NAT_ENTRY_PER_BLOCK )
2915
- __set_bit_le (nat_index , nm_i -> full_nat_bits );
2916
- else
2917
- __clear_bit_le (nat_index , nm_i -> full_nat_bits );
2970
+ up_read (& nm_i -> nat_tree_lock );
2918
2971
}
2919
2972
2920
2973
static int __flush_nat_entry_set (struct f2fs_sb_info * sbi ,
@@ -2933,7 +2986,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
2933
2986
* #1, flush nat entries to journal in current hot data summary block.
2934
2987
* #2, flush nat entries to nat page.
2935
2988
*/
2936
- if (enabled_nat_bits ( sbi , cpc ) ||
2989
+ if (( cpc -> reason & CP_UMOUNT ) ||
2937
2990
!__has_cursum_space (journal , set -> entry_cnt , NAT_JOURNAL ))
2938
2991
to_journal = false;
2939
2992
@@ -2980,7 +3033,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi,
2980
3033
if (to_journal ) {
2981
3034
up_write (& curseg -> journal_rwsem );
2982
3035
} else {
2983
- __update_nat_bits (sbi , start_nid , page );
3036
+ update_nat_bits (sbi , start_nid , page );
2984
3037
f2fs_put_page (page , 1 );
2985
3038
}
2986
3039
@@ -3011,7 +3064,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
3011
3064
* during unmount, let's flush nat_bits before checking
3012
3065
* nat_cnt[DIRTY_NAT].
3013
3066
*/
3014
- if (enabled_nat_bits ( sbi , cpc ) ) {
3067
+ if (cpc -> reason & CP_UMOUNT ) {
3015
3068
down_write (& nm_i -> nat_tree_lock );
3016
3069
remove_nats_in_journal (sbi );
3017
3070
up_write (& nm_i -> nat_tree_lock );
@@ -3027,7 +3080,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
3027
3080
* entries, remove all entries from journal and merge them
3028
3081
* into nat entry set.
3029
3082
*/
3030
- if (enabled_nat_bits ( sbi , cpc ) ||
3083
+ if (cpc -> reason & CP_UMOUNT ||
3031
3084
!__has_cursum_space (journal ,
3032
3085
nm_i -> nat_cnt [DIRTY_NAT ], NAT_JOURNAL ))
3033
3086
remove_nats_in_journal (sbi );
@@ -3064,15 +3117,18 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
3064
3117
__u64 cp_ver = cur_cp_version (ckpt );
3065
3118
block_t nat_bits_addr ;
3066
3119
3067
- if (!enabled_nat_bits (sbi , NULL ))
3068
- return 0 ;
3069
-
3070
3120
nm_i -> nat_bits_blocks = F2FS_BLK_ALIGN ((nat_bits_bytes << 1 ) + 8 );
3071
3121
nm_i -> nat_bits = f2fs_kvzalloc (sbi ,
3072
3122
nm_i -> nat_bits_blocks << F2FS_BLKSIZE_BITS , GFP_KERNEL );
3073
3123
if (!nm_i -> nat_bits )
3074
3124
return - ENOMEM ;
3075
3125
3126
+ nm_i -> full_nat_bits = nm_i -> nat_bits + 8 ;
3127
+ nm_i -> empty_nat_bits = nm_i -> full_nat_bits + nat_bits_bytes ;
3128
+
3129
+ if (!is_set_ckpt_flags (sbi , CP_NAT_BITS_FLAG ))
3130
+ return 0 ;
3131
+
3076
3132
nat_bits_addr = __start_cp_addr (sbi ) + sbi -> blocks_per_seg -
3077
3133
nm_i -> nat_bits_blocks ;
3078
3134
for (i = 0 ; i < nm_i -> nat_bits_blocks ; i ++ ) {
@@ -3089,13 +3145,12 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi)
3089
3145
3090
3146
cp_ver |= (cur_cp_crc (ckpt ) << 32 );
3091
3147
if (cpu_to_le64 (cp_ver ) != * (__le64 * )nm_i -> nat_bits ) {
3092
- disable_nat_bits (sbi , true);
3148
+ clear_ckpt_flags (sbi , CP_NAT_BITS_FLAG );
3149
+ f2fs_notice (sbi , "Disable nat_bits due to incorrect cp_ver (%llu, %llu)" ,
3150
+ cp_ver , le64_to_cpu (* (__le64 * )nm_i -> nat_bits ));
3093
3151
return 0 ;
3094
3152
}
3095
3153
3096
- nm_i -> full_nat_bits = nm_i -> nat_bits + 8 ;
3097
- nm_i -> empty_nat_bits = nm_i -> full_nat_bits + nat_bits_bytes ;
3098
-
3099
3154
f2fs_notice (sbi , "Found nat_bits in checkpoint" );
3100
3155
return 0 ;
3101
3156
}
@@ -3106,7 +3161,7 @@ static inline void load_free_nid_bitmap(struct f2fs_sb_info *sbi)
3106
3161
unsigned int i = 0 ;
3107
3162
nid_t nid , last_nid ;
3108
3163
3109
- if (!enabled_nat_bits (sbi , NULL ))
3164
+ if (!is_set_ckpt_flags (sbi , CP_NAT_BITS_FLAG ))
3110
3165
return ;
3111
3166
3112
3167
for (i = 0 ; i < nm_i -> nat_blocks ; i ++ ) {
0 commit comments