aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/node.c
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk.kim@samsung.com>2013-03-08 07:29:23 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2013-03-20 05:30:06 -0400
commit393ff91f57c87d48ffed30878be6e3e486d3a00a (patch)
treec80fe33bcf8546ebce9ab6fc043b99889e67536f /fs/f2fs/node.c
parent25c0a6e529b56ca010e1f46239edd07c1b484b63 (diff)
f2fs: reduce unncessary locking pages during read
This patch reduces redundant locking and unlocking pages during read operations. In f2fs_readpage, let's use wait_on_page_locked() instead of lock_page. And then, when we need to modify any data finally, let's lock the page so that we can avoid lock contention. [readpage rule] - The f2fs_readpage returns unlocked page, or released page too in error cases. - Its caller should handle read error, -EIO, after locking the page, which indicates read completion. - Its caller should check PageUptodate after grab_cache_page. Signed-off-by: Changman Lee <cm224.lee@samsung.com> Reviewed-by: Namjae Jeon <namjae.jeon@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r--fs/f2fs/node.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index a3cb1ff34f8e..9e6ed6708fa8 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -100,10 +100,13 @@ static void ra_nat_pages(struct f2fs_sb_info *sbi, int nid)
100 page = grab_cache_page(mapping, index); 100 page = grab_cache_page(mapping, index);
101 if (!page) 101 if (!page)
102 continue; 102 continue;
103 if (f2fs_readpage(sbi, page, index, READ)) { 103 if (PageUptodate(page)) {
104 f2fs_put_page(page, 1); 104 f2fs_put_page(page, 1);
105 continue; 105 continue;
106 } 106 }
107 if (f2fs_readpage(sbi, page, index, READ))
108 continue;
109
107 f2fs_put_page(page, 0); 110 f2fs_put_page(page, 0);
108 } 111 }
109} 112}
@@ -851,8 +854,16 @@ static int read_node_page(struct page *page, int type)
851 854
852 get_node_info(sbi, page->index, &ni); 855 get_node_info(sbi, page->index, &ni);
853 856
854 if (ni.blk_addr == NULL_ADDR) 857 if (ni.blk_addr == NULL_ADDR) {
858 f2fs_put_page(page, 1);
855 return -ENOENT; 859 return -ENOENT;
860 }
861
862 if (PageUptodate(page)) {
863 unlock_page(page);
864 return 0;
865 }
866
856 return f2fs_readpage(sbi, page, ni.blk_addr, type); 867 return f2fs_readpage(sbi, page, ni.blk_addr, type);
857} 868}
858 869
@@ -865,19 +876,18 @@ void ra_node_page(struct f2fs_sb_info *sbi, nid_t nid)
865 struct page *apage; 876 struct page *apage;
866 877
867 apage = find_get_page(mapping, nid); 878 apage = find_get_page(mapping, nid);
868 if (apage && PageUptodate(apage)) 879 if (apage && PageUptodate(apage)) {
869 goto release_out; 880 f2fs_put_page(apage, 0);
881 return;
882 }
870 f2fs_put_page(apage, 0); 883 f2fs_put_page(apage, 0);
871 884
872 apage = grab_cache_page(mapping, nid); 885 apage = grab_cache_page(mapping, nid);
873 if (!apage) 886 if (!apage)
874 return; 887 return;
875 888
876 if (read_node_page(apage, READA)) 889 if (read_node_page(apage, READA) == 0)
877 unlock_page(apage); 890 f2fs_put_page(apage, 0);
878
879release_out:
880 f2fs_put_page(apage, 0);
881 return; 891 return;
882} 892}
883 893
@@ -892,11 +902,14 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
892 return ERR_PTR(-ENOMEM); 902 return ERR_PTR(-ENOMEM);
893 903
894 err = read_node_page(page, READ_SYNC); 904 err = read_node_page(page, READ_SYNC);
895 if (err) { 905 if (err)
896 f2fs_put_page(page, 1);
897 return ERR_PTR(err); 906 return ERR_PTR(err);
898 }
899 907
908 lock_page(page);
909 if (!PageUptodate(page)) {
910 f2fs_put_page(page, 1);
911 return ERR_PTR(-EIO);
912 }
900 BUG_ON(nid != nid_of_node(page)); 913 BUG_ON(nid != nid_of_node(page));
901 mark_page_accessed(page); 914 mark_page_accessed(page);
902 return page; 915 return page;
@@ -928,11 +941,8 @@ repeat:
928 goto page_hit; 941 goto page_hit;
929 942
930 err = read_node_page(page, READ_SYNC); 943 err = read_node_page(page, READ_SYNC);
931 unlock_page(page); 944 if (err)
932 if (err) {
933 f2fs_put_page(page, 0);
934 return ERR_PTR(err); 945 return ERR_PTR(err);
935 }
936 946
937 /* Then, try readahead for siblings of the desired node */ 947 /* Then, try readahead for siblings of the desired node */
938 end = start + MAX_RA_NODE; 948 end = start + MAX_RA_NODE;
@@ -957,6 +967,7 @@ page_hit:
957 f2fs_put_page(page, 1); 967 f2fs_put_page(page, 1);
958 goto repeat; 968 goto repeat;
959 } 969 }
970 mark_page_accessed(page);
960 return page; 971 return page;
961} 972}
962 973
@@ -1473,23 +1484,24 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
1473 sum_entry = &sum->entries[0]; 1484 sum_entry = &sum->entries[0];
1474 1485
1475 for (i = 0; i < last_offset; i++, sum_entry++) { 1486 for (i = 0; i < last_offset; i++, sum_entry++) {
1487 /*
1488 * In order to read next node page,
1489 * we must clear PageUptodate flag.
1490 */
1491 ClearPageUptodate(page);
1492
1476 if (f2fs_readpage(sbi, page, addr, READ_SYNC)) 1493 if (f2fs_readpage(sbi, page, addr, READ_SYNC))
1477 goto out; 1494 goto out;
1478 1495
1496 lock_page(page);
1479 rn = (struct f2fs_node *)page_address(page); 1497 rn = (struct f2fs_node *)page_address(page);
1480 sum_entry->nid = rn->footer.nid; 1498 sum_entry->nid = rn->footer.nid;
1481 sum_entry->version = 0; 1499 sum_entry->version = 0;
1482 sum_entry->ofs_in_node = 0; 1500 sum_entry->ofs_in_node = 0;
1483 addr++; 1501 addr++;
1484
1485 /*
1486 * In order to read next node page,
1487 * we must clear PageUptodate flag.
1488 */
1489 ClearPageUptodate(page);
1490 } 1502 }
1491out:
1492 unlock_page(page); 1503 unlock_page(page);
1504out:
1493 __free_pages(page, 0); 1505 __free_pages(page, 0);
1494 return 0; 1506 return 0;
1495} 1507}