diff options
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r-- | fs/f2fs/node.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 97bd9d3db882..8ab0cf1930bd 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
@@ -41,7 +41,9 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) | |||
41 | /* only uses low memory */ | 41 | /* only uses low memory */ |
42 | avail_ram = val.totalram - val.totalhigh; | 42 | avail_ram = val.totalram - val.totalhigh; |
43 | 43 | ||
44 | /* give 25%, 25%, 50%, 50% memory for each components respectively */ | 44 | /* |
45 | * give 25%, 25%, 50%, 50%, 50% memory for each components respectively | ||
46 | */ | ||
45 | if (type == FREE_NIDS) { | 47 | if (type == FREE_NIDS) { |
46 | mem_size = (nm_i->fcnt * sizeof(struct free_nid)) >> | 48 | mem_size = (nm_i->fcnt * sizeof(struct free_nid)) >> |
47 | PAGE_CACHE_SHIFT; | 49 | PAGE_CACHE_SHIFT; |
@@ -62,6 +64,11 @@ bool available_free_memory(struct f2fs_sb_info *sbi, int type) | |||
62 | mem_size += (sbi->im[i].ino_num * | 64 | mem_size += (sbi->im[i].ino_num * |
63 | sizeof(struct ino_entry)) >> PAGE_CACHE_SHIFT; | 65 | sizeof(struct ino_entry)) >> PAGE_CACHE_SHIFT; |
64 | res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); | 66 | res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); |
67 | } else if (type == EXTENT_CACHE) { | ||
68 | mem_size = (sbi->total_ext_tree * sizeof(struct extent_tree) + | ||
69 | atomic_read(&sbi->total_ext_node) * | ||
70 | sizeof(struct extent_node)) >> PAGE_CACHE_SHIFT; | ||
71 | res = mem_size < ((avail_ram * nm_i->ram_thresh / 100) >> 1); | ||
65 | } else { | 72 | } else { |
66 | if (sbi->sb->s_bdi->dirty_exceeded) | 73 | if (sbi->sb->s_bdi->dirty_exceeded) |
67 | return false; | 74 | return false; |
@@ -494,7 +501,7 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode) | |||
494 | 501 | ||
495 | /* if inline_data is set, should not report any block indices */ | 502 | /* if inline_data is set, should not report any block indices */ |
496 | if (f2fs_has_inline_data(dn->inode) && index) { | 503 | if (f2fs_has_inline_data(dn->inode) && index) { |
497 | err = -EINVAL; | 504 | err = -ENOENT; |
498 | f2fs_put_page(npage[0], 1); | 505 | f2fs_put_page(npage[0], 1); |
499 | goto release_out; | 506 | goto release_out; |
500 | } | 507 | } |
@@ -995,6 +1002,7 @@ static int read_node_page(struct page *page, int rw) | |||
995 | get_node_info(sbi, page->index, &ni); | 1002 | get_node_info(sbi, page->index, &ni); |
996 | 1003 | ||
997 | if (unlikely(ni.blk_addr == NULL_ADDR)) { | 1004 | if (unlikely(ni.blk_addr == NULL_ADDR)) { |
1005 | ClearPageUptodate(page); | ||
998 | f2fs_put_page(page, 1); | 1006 | f2fs_put_page(page, 1); |
999 | return -ENOENT; | 1007 | return -ENOENT; |
1000 | } | 1008 | } |
@@ -1306,6 +1314,7 @@ static int f2fs_write_node_page(struct page *page, | |||
1306 | 1314 | ||
1307 | /* This page is already truncated */ | 1315 | /* This page is already truncated */ |
1308 | if (unlikely(ni.blk_addr == NULL_ADDR)) { | 1316 | if (unlikely(ni.blk_addr == NULL_ADDR)) { |
1317 | ClearPageUptodate(page); | ||
1309 | dec_page_count(sbi, F2FS_DIRTY_NODES); | 1318 | dec_page_count(sbi, F2FS_DIRTY_NODES); |
1310 | unlock_page(page); | 1319 | unlock_page(page); |
1311 | return 0; | 1320 | return 0; |
@@ -1821,6 +1830,7 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1821 | struct f2fs_nat_block *nat_blk; | 1830 | struct f2fs_nat_block *nat_blk; |
1822 | struct nat_entry *ne, *cur; | 1831 | struct nat_entry *ne, *cur; |
1823 | struct page *page = NULL; | 1832 | struct page *page = NULL; |
1833 | struct f2fs_nm_info *nm_i = NM_I(sbi); | ||
1824 | 1834 | ||
1825 | /* | 1835 | /* |
1826 | * there are two steps to flush nat entries: | 1836 | * there are two steps to flush nat entries: |
@@ -1874,7 +1884,9 @@ static void __flush_nat_entry_set(struct f2fs_sb_info *sbi, | |||
1874 | 1884 | ||
1875 | f2fs_bug_on(sbi, set->entry_cnt); | 1885 | f2fs_bug_on(sbi, set->entry_cnt); |
1876 | 1886 | ||
1887 | down_write(&nm_i->nat_tree_lock); | ||
1877 | radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); | 1888 | radix_tree_delete(&NM_I(sbi)->nat_set_root, set->set); |
1889 | up_write(&nm_i->nat_tree_lock); | ||
1878 | kmem_cache_free(nat_entry_set_slab, set); | 1890 | kmem_cache_free(nat_entry_set_slab, set); |
1879 | } | 1891 | } |
1880 | 1892 | ||
@@ -1902,6 +1914,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1902 | if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) | 1914 | if (!__has_cursum_space(sum, nm_i->dirty_nat_cnt, NAT_JOURNAL)) |
1903 | remove_nats_in_journal(sbi); | 1915 | remove_nats_in_journal(sbi); |
1904 | 1916 | ||
1917 | down_write(&nm_i->nat_tree_lock); | ||
1905 | while ((found = __gang_lookup_nat_set(nm_i, | 1918 | while ((found = __gang_lookup_nat_set(nm_i, |
1906 | set_idx, SETVEC_SIZE, setvec))) { | 1919 | set_idx, SETVEC_SIZE, setvec))) { |
1907 | unsigned idx; | 1920 | unsigned idx; |
@@ -1910,6 +1923,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
1910 | __adjust_nat_entry_set(setvec[idx], &sets, | 1923 | __adjust_nat_entry_set(setvec[idx], &sets, |
1911 | MAX_NAT_JENTRIES(sum)); | 1924 | MAX_NAT_JENTRIES(sum)); |
1912 | } | 1925 | } |
1926 | up_write(&nm_i->nat_tree_lock); | ||
1913 | 1927 | ||
1914 | /* flush dirty nats in nat entry set */ | 1928 | /* flush dirty nats in nat entry set */ |
1915 | list_for_each_entry_safe(set, tmp, &sets, set_list) | 1929 | list_for_each_entry_safe(set, tmp, &sets, set_list) |