diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-21 15:27:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-03-21 15:27:06 -0400 |
commit | 689b957baf4412f8d737ce67b6d07cab043becd3 (patch) | |
tree | 9b750115eda12c1ea4d59e934d4495fd17221bb7 | |
parent | 97da3854c526d3a6ee05c849c96e48d21527606c (diff) | |
parent | 7041d5d286fb54635f540c1bb3b43980ed65513a (diff) |
Merge tag 'for-f2fs-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs fixes from Jaegeuk Kim:
- fix performance regression reported by lkp-rebot
- fix potential data lost after power-cut due to SSR reallocation
* tag 'for-f2fs-4.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs:
f2fs: combine nat_bits and free_nid_bitmap cache
f2fs: skip scanning free nid bitmap of full NAT blocks
f2fs: use __set{__clear}_bit_le
f2fs: declare static functions
f2fs: don't overwrite node block by SSR
-rw-r--r-- | fs/f2fs/debug.c | 1 | ||||
-rw-r--r-- | fs/f2fs/dir.c | 2 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
-rw-r--r-- | fs/f2fs/node.c | 163 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 6 |
5 files changed, 87 insertions, 87 deletions
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index a77df377e2e8..ee2d0a485fc3 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c | |||
@@ -196,6 +196,7 @@ static void update_mem_info(struct f2fs_sb_info *sbi) | |||
196 | si->base_mem += (NM_I(sbi)->nat_bits_blocks << F2FS_BLKSIZE_BITS); | 196 | si->base_mem += (NM_I(sbi)->nat_bits_blocks << F2FS_BLKSIZE_BITS); |
197 | si->base_mem += NM_I(sbi)->nat_blocks * NAT_ENTRY_BITMAP_SIZE; | 197 | si->base_mem += NM_I(sbi)->nat_blocks * NAT_ENTRY_BITMAP_SIZE; |
198 | si->base_mem += NM_I(sbi)->nat_blocks / 8; | 198 | si->base_mem += NM_I(sbi)->nat_blocks / 8; |
199 | si->base_mem += NM_I(sbi)->nat_blocks * sizeof(unsigned short); | ||
199 | 200 | ||
200 | get_cache: | 201 | get_cache: |
201 | si->cache_mem = 0; | 202 | si->cache_mem = 0; |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4650c9b85de7..8d5c62b07b28 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
@@ -750,7 +750,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page, | |||
750 | dentry_blk = page_address(page); | 750 | dentry_blk = page_address(page); |
751 | bit_pos = dentry - dentry_blk->dentry; | 751 | bit_pos = dentry - dentry_blk->dentry; |
752 | for (i = 0; i < slots; i++) | 752 | for (i = 0; i < slots; i++) |
753 | clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); | 753 | __clear_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap); |
754 | 754 | ||
755 | /* Let's check and deallocate this dentry page */ | 755 | /* Let's check and deallocate this dentry page */ |
756 | bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, | 756 | bit_pos = find_next_bit_le(&dentry_blk->dentry_bitmap, |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e849f83d6114..0a6e115562f6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -561,6 +561,8 @@ struct f2fs_nm_info { | |||
561 | struct mutex build_lock; /* lock for build free nids */ | 561 | struct mutex build_lock; /* lock for build free nids */ |
562 | unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE]; | 562 | unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE]; |
563 | unsigned char *nat_block_bitmap; | 563 | unsigned char *nat_block_bitmap; |
564 | unsigned short *free_nid_count; /* free nid count of NAT block */ | ||
565 | spinlock_t free_nid_lock; /* protect updating of nid count */ | ||
564 | 566 | ||
565 | /* for checkpoint */ | 567 | /* for checkpoint */ |
566 | char *nat_bitmap; /* NAT bitmap pointer */ | 568 | char *nat_bitmap; /* NAT bitmap pointer */ |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 94967171dee8..481aa8dc79f4 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -338,9 +338,6 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, | |||
338 | set_nat_flag(e, IS_CHECKPOINTED, false); | 338 | set_nat_flag(e, IS_CHECKPOINTED, false); |
339 | __set_nat_cache_dirty(nm_i, e); | 339 | __set_nat_cache_dirty(nm_i, e); |
340 | 340 | ||
341 | if (enabled_nat_bits(sbi, NULL) && new_blkaddr == NEW_ADDR) | ||
342 | clear_bit_le(NAT_BLOCK_OFFSET(ni->nid), nm_i->empty_nat_bits); | ||
343 | |||
344 | /* update fsync_mark if its inode nat entry is still alive */ | 341 | /* update fsync_mark if its inode nat entry is still alive */ |
345 | if (ni->nid != ni->ino) | 342 | if (ni->nid != ni->ino) |
346 | e = __lookup_nat_cache(nm_i, ni->ino); | 343 | e = __lookup_nat_cache(nm_i, ni->ino); |
@@ -1823,7 +1820,8 @@ static void remove_free_nid(struct f2fs_sb_info *sbi, nid_t nid) | |||
1823 | kmem_cache_free(free_nid_slab, i); | 1820 | kmem_cache_free(free_nid_slab, i); |
1824 | } | 1821 | } |
1825 | 1822 | ||
1826 | void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid, bool set) | 1823 | static void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid, |
1824 | bool set, bool build, bool locked) | ||
1827 | { | 1825 | { |
1828 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1826 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
1829 | unsigned int nat_ofs = NAT_BLOCK_OFFSET(nid); | 1827 | unsigned int nat_ofs = NAT_BLOCK_OFFSET(nid); |
@@ -1833,9 +1831,18 @@ void update_free_nid_bitmap(struct f2fs_sb_info *sbi, nid_t nid, bool set) | |||
1833 | return; | 1831 | return; |
1834 | 1832 | ||
1835 | if (set) | 1833 | if (set) |
1836 | set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]); | 1834 | __set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]); |
1837 | else | 1835 | else |
1838 | clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]); | 1836 | __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]); |
1837 | |||
1838 | if (!locked) | ||
1839 | spin_lock(&nm_i->free_nid_lock); | ||
1840 | if (set) | ||
1841 | nm_i->free_nid_count[nat_ofs]++; | ||
1842 | else if (!build) | ||
1843 | nm_i->free_nid_count[nat_ofs]--; | ||
1844 | if (!locked) | ||
1845 | spin_unlock(&nm_i->free_nid_lock); | ||
1839 | } | 1846 | } |
1840 | 1847 | ||
1841 | static void scan_nat_page(struct f2fs_sb_info *sbi, | 1848 | static void scan_nat_page(struct f2fs_sb_info *sbi, |
@@ -1847,7 +1854,10 @@ static void scan_nat_page(struct f2fs_sb_info *sbi, | |||
1847 | unsigned int nat_ofs = NAT_BLOCK_OFFSET(start_nid); | 1854 | unsigned int nat_ofs = NAT_BLOCK_OFFSET(start_nid); |
1848 | int i; | 1855 | int i; |
1849 | 1856 | ||
1850 | set_bit_le(nat_ofs, nm_i->nat_block_bitmap); | 1857 | if (test_bit_le(nat_ofs, nm_i->nat_block_bitmap)) |
1858 | return; | ||
1859 | |||
1860 | __set_bit_le(nat_ofs, nm_i->nat_block_bitmap); | ||
1851 | 1861 | ||
1852 | i = start_nid % NAT_ENTRY_PER_BLOCK; | 1862 | i = start_nid % NAT_ENTRY_PER_BLOCK; |
1853 | 1863 | ||
@@ -1861,7 +1871,7 @@ static void scan_nat_page(struct f2fs_sb_info *sbi, | |||
1861 | f2fs_bug_on(sbi, blk_addr == NEW_ADDR); | 1871 | f2fs_bug_on(sbi, blk_addr == NEW_ADDR); |
1862 | if (blk_addr == NULL_ADDR) | 1872 | if (blk_addr == NULL_ADDR) |
1863 | freed = add_free_nid(sbi, start_nid, true); | 1873 | freed = add_free_nid(sbi, start_nid, true); |
1864 | update_free_nid_bitmap(sbi, start_nid, freed); | 1874 | update_free_nid_bitmap(sbi, start_nid, freed, true, false); |
1865 | } | 1875 | } |
1866 | } | 1876 | } |
1867 | 1877 | ||
@@ -1877,6 +1887,8 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) | |||
1877 | for (i = 0; i < nm_i->nat_blocks; i++) { | 1887 | for (i = 0; i < nm_i->nat_blocks; i++) { |
1878 | if (!test_bit_le(i, nm_i->nat_block_bitmap)) | 1888 | if (!test_bit_le(i, nm_i->nat_block_bitmap)) |
1879 | continue; | 1889 | continue; |
1890 | if (!nm_i->free_nid_count[i]) | ||
1891 | continue; | ||
1880 | for (idx = 0; idx < NAT_ENTRY_PER_BLOCK; idx++) { | 1892 | for (idx = 0; idx < NAT_ENTRY_PER_BLOCK; idx++) { |
1881 | nid_t nid; | 1893 | nid_t nid; |
1882 | 1894 | ||
@@ -1907,58 +1919,6 @@ out: | |||
1907 | up_read(&nm_i->nat_tree_lock); | 1919 | up_read(&nm_i->nat_tree_lock); |
1908 | } | 1920 | } |
1909 | 1921 | ||
1910 | static int scan_nat_bits(struct f2fs_sb_info *sbi) | ||
1911 | { | ||
1912 | struct f2fs_nm_info *nm_i = NM_I(sbi); | ||
1913 | struct page *page; | ||
1914 | unsigned int i = 0; | ||
1915 | nid_t nid; | ||
1916 | |||
1917 | if (!enabled_nat_bits(sbi, NULL)) | ||
1918 | return -EAGAIN; | ||
1919 | |||
1920 | down_read(&nm_i->nat_tree_lock); | ||
1921 | check_empty: | ||
1922 | i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i); | ||
1923 | if (i >= nm_i->nat_blocks) { | ||
1924 | i = 0; | ||
1925 | goto check_partial; | ||
1926 | } | ||
1927 | |||
1928 | for (nid = i * NAT_ENTRY_PER_BLOCK; nid < (i + 1) * NAT_ENTRY_PER_BLOCK; | ||
1929 | nid++) { | ||
1930 | if (unlikely(nid >= nm_i->max_nid)) | ||
1931 | break; | ||
1932 | add_free_nid(sbi, nid, true); | ||
1933 | } | ||
1934 | |||
1935 | if (nm_i->nid_cnt[FREE_NID_LIST] >= MAX_FREE_NIDS) | ||
1936 | goto out; | ||
1937 | i++; | ||
1938 | goto check_empty; | ||
1939 | |||
1940 | check_partial: | ||
1941 | i = find_next_zero_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i); | ||
1942 | if (i >= nm_i->nat_blocks) { | ||
1943 | disable_nat_bits(sbi, true); | ||
1944 | up_read(&nm_i->nat_tree_lock); | ||
1945 | return -EINVAL; | ||
1946 | } | ||
1947 | |||
1948 | nid = i * NAT_ENTRY_PER_BLOCK; | ||
1949 | page = get_current_nat_page(sbi, nid); | ||
1950 | scan_nat_page(sbi, page, nid); | ||
1951 | f2fs_put_page(page, 1); | ||
1952 | |||
1953 | if (nm_i->nid_cnt[FREE_NID_LIST] < MAX_FREE_NIDS) { | ||
1954 | i++; | ||
1955 | goto check_partial; | ||
1956 | } | ||
1957 | out: | ||
1958 | up_read(&nm_i->nat_tree_lock); | ||
1959 | return 0; | ||
1960 | } | ||
1961 | |||
1962 | static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) | 1922 | static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) |
1963 | { | 1923 | { |
1964 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 1924 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
@@ -1980,21 +1940,6 @@ static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) | |||
1980 | 1940 | ||
1981 | if (nm_i->nid_cnt[FREE_NID_LIST]) | 1941 | if (nm_i->nid_cnt[FREE_NID_LIST]) |
1982 | return; | 1942 | return; |
1983 | |||
1984 | /* try to find free nids with nat_bits */ | ||
1985 | if (!scan_nat_bits(sbi) && nm_i->nid_cnt[FREE_NID_LIST]) | ||
1986 | return; | ||
1987 | } | ||
1988 | |||
1989 | /* find next valid candidate */ | ||
1990 | if (enabled_nat_bits(sbi, NULL)) { | ||
1991 | int idx = find_next_zero_bit_le(nm_i->full_nat_bits, | ||
1992 | nm_i->nat_blocks, 0); | ||
1993 | |||
1994 | if (idx >= nm_i->nat_blocks) | ||
1995 | set_sbi_flag(sbi, SBI_NEED_FSCK); | ||
1996 | else | ||
1997 | nid = idx * NAT_ENTRY_PER_BLOCK; | ||
1998 | } | 1943 | } |
1999 | 1944 | ||
2000 | /* readahead nat pages to be scanned */ | 1945 | /* readahead nat pages to be scanned */ |
@@ -2081,7 +2026,7 @@ retry: | |||
2081 | __insert_nid_to_list(sbi, i, ALLOC_NID_LIST, false); | 2026 | __insert_nid_to_list(sbi, i, ALLOC_NID_LIST, false); |
2082 | nm_i->available_nids--; | 2027 | nm_i->available_nids--; |
2083 | 2028 | ||
2084 | update_free_nid_bitmap(sbi, *nid, false); | 2029 | update_free_nid_bitmap(sbi, *nid, false, false, false); |
2085 | 2030 | ||
2086 | spin_unlock(&nm_i->nid_list_lock); | 2031 | spin_unlock(&nm_i->nid_list_lock); |
2087 | return true; | 2032 | return true; |
@@ -2137,7 +2082,7 @@ void alloc_nid_failed(struct f2fs_sb_info *sbi, nid_t nid) | |||
2137 | 2082 | ||
2138 | nm_i->available_nids++; | 2083 | nm_i->available_nids++; |
2139 | 2084 | ||
2140 | update_free_nid_bitmap(sbi, nid, true); | 2085 | update_free_nid_bitmap(sbi, nid, true, false, false); |
2141 | 2086 | ||
2142 | spin_unlock(&nm_i->nid_list_lock); | 2087 | spin_unlock(&nm_i->nid_list_lock); |
2143 | 2088 | ||
@@ -2383,7 +2328,7 @@ add_out: | |||
2383 | list_add_tail(&nes->set_list, head); | 2328 | list_add_tail(&nes->set_list, head); |
2384 | } | 2329 | } |
2385 | 2330 | ||
2386 | void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid, | 2331 | static void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid, |
2387 | struct page *page) | 2332 | struct page *page) |
2388 | { | 2333 | { |
2389 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 2334 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
@@ -2402,16 +2347,16 @@ void __update_nat_bits(struct f2fs_sb_info *sbi, nid_t start_nid, | |||
2402 | valid++; | 2347 | valid++; |
2403 | } | 2348 | } |
2404 | if (valid == 0) { | 2349 | if (valid == 0) { |
2405 | set_bit_le(nat_index, nm_i->empty_nat_bits); | 2350 | __set_bit_le(nat_index, nm_i->empty_nat_bits); |
2406 | clear_bit_le(nat_index, nm_i->full_nat_bits); | 2351 | __clear_bit_le(nat_index, nm_i->full_nat_bits); |
2407 | return; | 2352 | return; |
2408 | } | 2353 | } |
2409 | 2354 | ||
2410 | clear_bit_le(nat_index, nm_i->empty_nat_bits); | 2355 | __clear_bit_le(nat_index, nm_i->empty_nat_bits); |
2411 | if (valid == NAT_ENTRY_PER_BLOCK) | 2356 | if (valid == NAT_ENTRY_PER_BLOCK) |
2412 | set_bit_le(nat_index, nm_i->full_nat_bits); | 2357 | __set_bit_le(nat_index, nm_i->full_nat_bits); |
2413 | else | 2358 | else |
2414 | clear_bit_le(nat_index, nm_i->full_nat_bits); | 2359 | __clear_bit_le(nat_index, nm_i->full_nat_bits); |
2415 | } | 2360 | } |
2416 | 2361 | ||
2417 | static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | 2362 | static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, |
@@ -2467,11 +2412,11 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
2467 | add_free_nid(sbi, nid, false); | 2412 | add_free_nid(sbi, nid, false); |
2468 | spin_lock(&NM_I(sbi)->nid_list_lock); | 2413 | spin_lock(&NM_I(sbi)->nid_list_lock); |
2469 | NM_I(sbi)->available_nids++; | 2414 | NM_I(sbi)->available_nids++; |
2470 | update_free_nid_bitmap(sbi, nid, true); | 2415 | update_free_nid_bitmap(sbi, nid, true, false, false); |
2471 | spin_unlock(&NM_I(sbi)->nid_list_lock); | 2416 | spin_unlock(&NM_I(sbi)->nid_list_lock); |
2472 | } else { | 2417 | } else { |
2473 | spin_lock(&NM_I(sbi)->nid_list_lock); | 2418 | spin_lock(&NM_I(sbi)->nid_list_lock); |
2474 | update_free_nid_bitmap(sbi, nid, false); | 2419 | update_free_nid_bitmap(sbi, nid, false, false, false); |
2475 | spin_unlock(&NM_I(sbi)->nid_list_lock); | 2420 | spin_unlock(&NM_I(sbi)->nid_list_lock); |
2476 | } | 2421 | } |
2477 | } | 2422 | } |
@@ -2577,6 +2522,40 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi) | |||
2577 | return 0; | 2522 | return 0; |
2578 | } | 2523 | } |
2579 | 2524 | ||
2525 | inline void load_free_nid_bitmap(struct f2fs_sb_info *sbi) | ||
2526 | { | ||
2527 | struct f2fs_nm_info *nm_i = NM_I(sbi); | ||
2528 | unsigned int i = 0; | ||
2529 | nid_t nid, last_nid; | ||
2530 | |||
2531 | if (!enabled_nat_bits(sbi, NULL)) | ||
2532 | return; | ||
2533 | |||
2534 | for (i = 0; i < nm_i->nat_blocks; i++) { | ||
2535 | i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i); | ||
2536 | if (i >= nm_i->nat_blocks) | ||
2537 | break; | ||
2538 | |||
2539 | __set_bit_le(i, nm_i->nat_block_bitmap); | ||
2540 | |||
2541 | nid = i * NAT_ENTRY_PER_BLOCK; | ||
2542 | last_nid = (i + 1) * NAT_ENTRY_PER_BLOCK; | ||
2543 | |||
2544 | spin_lock(&nm_i->free_nid_lock); | ||
2545 | for (; nid < last_nid; nid++) | ||
2546 | update_free_nid_bitmap(sbi, nid, true, true, true); | ||
2547 | spin_unlock(&nm_i->free_nid_lock); | ||
2548 | } | ||
2549 | |||
2550 | for (i = 0; i < nm_i->nat_blocks; i++) { | ||
2551 | i = find_next_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i); | ||
2552 | if (i >= nm_i->nat_blocks) | ||
2553 | break; | ||
2554 | |||
2555 | __set_bit_le(i, nm_i->nat_block_bitmap); | ||
2556 | } | ||
2557 | } | ||
2558 | |||
2580 | static int init_node_manager(struct f2fs_sb_info *sbi) | 2559 | static int init_node_manager(struct f2fs_sb_info *sbi) |
2581 | { | 2560 | { |
2582 | struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi); | 2561 | struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi); |
@@ -2638,7 +2617,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) | |||
2638 | return 0; | 2617 | return 0; |
2639 | } | 2618 | } |
2640 | 2619 | ||
2641 | int init_free_nid_cache(struct f2fs_sb_info *sbi) | 2620 | static int init_free_nid_cache(struct f2fs_sb_info *sbi) |
2642 | { | 2621 | { |
2643 | struct f2fs_nm_info *nm_i = NM_I(sbi); | 2622 | struct f2fs_nm_info *nm_i = NM_I(sbi); |
2644 | 2623 | ||
@@ -2651,6 +2630,14 @@ int init_free_nid_cache(struct f2fs_sb_info *sbi) | |||
2651 | GFP_KERNEL); | 2630 | GFP_KERNEL); |
2652 | if (!nm_i->nat_block_bitmap) | 2631 | if (!nm_i->nat_block_bitmap) |
2653 | return -ENOMEM; | 2632 | return -ENOMEM; |
2633 | |||
2634 | nm_i->free_nid_count = f2fs_kvzalloc(nm_i->nat_blocks * | ||
2635 | sizeof(unsigned short), GFP_KERNEL); | ||
2636 | if (!nm_i->free_nid_count) | ||
2637 | return -ENOMEM; | ||
2638 | |||
2639 | spin_lock_init(&nm_i->free_nid_lock); | ||
2640 | |||
2654 | return 0; | 2641 | return 0; |
2655 | } | 2642 | } |
2656 | 2643 | ||
@@ -2670,6 +2657,9 @@ int build_node_manager(struct f2fs_sb_info *sbi) | |||
2670 | if (err) | 2657 | if (err) |
2671 | return err; | 2658 | return err; |
2672 | 2659 | ||
2660 | /* load free nid status from nat_bits table */ | ||
2661 | load_free_nid_bitmap(sbi); | ||
2662 | |||
2673 | build_free_nids(sbi, true, true); | 2663 | build_free_nids(sbi, true, true); |
2674 | return 0; | 2664 | return 0; |
2675 | } | 2665 | } |
@@ -2730,6 +2720,7 @@ void destroy_node_manager(struct f2fs_sb_info *sbi) | |||
2730 | 2720 | ||
2731 | kvfree(nm_i->nat_block_bitmap); | 2721 | kvfree(nm_i->nat_block_bitmap); |
2732 | kvfree(nm_i->free_nid_bitmap); | 2722 | kvfree(nm_i->free_nid_bitmap); |
2723 | kvfree(nm_i->free_nid_count); | ||
2733 | 2724 | ||
2734 | kfree(nm_i->nat_bitmap); | 2725 | kfree(nm_i->nat_bitmap); |
2735 | kfree(nm_i->nat_bits); | 2726 | kfree(nm_i->nat_bits); |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 4bd7a8b19332..29ef7088c558 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -1163,6 +1163,12 @@ static void update_sit_entry(struct f2fs_sb_info *sbi, block_t blkaddr, int del) | |||
1163 | if (f2fs_discard_en(sbi) && | 1163 | if (f2fs_discard_en(sbi) && |
1164 | !f2fs_test_and_set_bit(offset, se->discard_map)) | 1164 | !f2fs_test_and_set_bit(offset, se->discard_map)) |
1165 | sbi->discard_blks--; | 1165 | sbi->discard_blks--; |
1166 | |||
1167 | /* don't overwrite by SSR to keep node chain */ | ||
1168 | if (se->type == CURSEG_WARM_NODE) { | ||
1169 | if (!f2fs_test_and_set_bit(offset, se->ckpt_valid_map)) | ||
1170 | se->ckpt_valid_blocks++; | ||
1171 | } | ||
1166 | } else { | 1172 | } else { |
1167 | if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) { | 1173 | if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) { |
1168 | #ifdef CONFIG_F2FS_CHECK_FS | 1174 | #ifdef CONFIG_F2FS_CHECK_FS |