aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGu Zheng <guz.fnst@cn.fujitsu.com>2014-03-07 05:43:36 -0500
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-03-10 05:45:15 -0400
commitd653788a43475eb3cdfcfaa60fb53451878944cf (patch)
tree0da228bfc15f19a852ef49e7b2519022d8e15a96
parent46c04366bbfd112a74dcfebbe41c9bf3f496ea75 (diff)
f2fs: optimize restore_node_summary slightly
Previously, we ra_sum_pages to pre-read contiguous pages as more as possible, and if we fail to alloc more pages, an ENOMEM error will be reported upstream, even though we have alloced some pages yet. In fact, we can use the available pages to do the job partly, and continue the rest in the following circle. Only reporting ENOMEM upstream if we really can not alloc any available page. And another fix is ignoring dealing with the following pages if an EIO occurs when reading page from page_list. Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com> Reviewed-by: Chao Yu <chao2.yu@samsung.com> [Jaegeuk Kim: modify the flow for better neat code] Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/node.c28
-rw-r--r--fs/f2fs/segment.c7
2 files changed, 17 insertions, 18 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 12c9ded767d9..c415cec041b7 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1588,15 +1588,8 @@ static int ra_sum_pages(struct f2fs_sb_info *sbi, struct list_head *pages,
1588 for (; page_idx < start + nrpages; page_idx++) { 1588 for (; page_idx < start + nrpages; page_idx++) {
1589 /* alloc temporal page for read node summary info*/ 1589 /* alloc temporal page for read node summary info*/
1590 page = alloc_page(GFP_F2FS_ZERO); 1590 page = alloc_page(GFP_F2FS_ZERO);
1591 if (!page) { 1591 if (!page)
1592 struct page *tmp; 1592 break;
1593 list_for_each_entry_safe(page, tmp, pages, lru) {
1594 list_del(&page->lru);
1595 unlock_page(page);
1596 __free_pages(page, 0);
1597 }
1598 return -ENOMEM;
1599 }
1600 1593
1601 lock_page(page); 1594 lock_page(page);
1602 page->index = page_idx; 1595 page->index = page_idx;
@@ -1607,7 +1600,8 @@ static int ra_sum_pages(struct f2fs_sb_info *sbi, struct list_head *pages,
1607 f2fs_submit_page_mbio(sbi, page, page->index, &fio); 1600 f2fs_submit_page_mbio(sbi, page, page->index, &fio);
1608 1601
1609 f2fs_submit_merged_bio(sbi, META, READ); 1602 f2fs_submit_merged_bio(sbi, META, READ);
1610 return 0; 1603
1604 return page_idx - start;
1611} 1605}
1612 1606
1613int restore_node_summary(struct f2fs_sb_info *sbi, 1607int restore_node_summary(struct f2fs_sb_info *sbi,
@@ -1626,15 +1620,17 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
1626 addr = START_BLOCK(sbi, segno); 1620 addr = START_BLOCK(sbi, segno);
1627 sum_entry = &sum->entries[0]; 1621 sum_entry = &sum->entries[0];
1628 1622
1629 for (i = 0; i < last_offset; i += nrpages, addr += nrpages) { 1623 for (i = 0; !err && i < last_offset; i += nrpages, addr += nrpages) {
1630 nrpages = min(last_offset - i, bio_blocks); 1624 nrpages = min(last_offset - i, bio_blocks);
1631 1625
1632 /* read ahead node pages */ 1626 /* read ahead node pages */
1633 err = ra_sum_pages(sbi, &page_list, addr, nrpages); 1627 nrpages = ra_sum_pages(sbi, &page_list, addr, nrpages);
1634 if (err) 1628 if (!nrpages)
1635 return err; 1629 return -ENOMEM;
1636 1630
1637 list_for_each_entry_safe(page, tmp, &page_list, lru) { 1631 list_for_each_entry_safe(page, tmp, &page_list, lru) {
1632 if (err)
1633 goto skip;
1638 1634
1639 lock_page(page); 1635 lock_page(page);
1640 if (unlikely(!PageUptodate(page))) { 1636 if (unlikely(!PageUptodate(page))) {
@@ -1646,9 +1642,9 @@ int restore_node_summary(struct f2fs_sb_info *sbi,
1646 sum_entry->ofs_in_node = 0; 1642 sum_entry->ofs_in_node = 0;
1647 sum_entry++; 1643 sum_entry++;
1648 } 1644 }
1649
1650 list_del(&page->lru);
1651 unlock_page(page); 1645 unlock_page(page);
1646skip:
1647 list_del(&page->lru);
1652 __free_pages(page, 0); 1648 __free_pages(page, 0);
1653 } 1649 }
1654 } 1650 }
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 199c964680c5..b3f84318b7ed 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1160,9 +1160,12 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
1160 ns->ofs_in_node = 0; 1160 ns->ofs_in_node = 0;
1161 } 1161 }
1162 } else { 1162 } else {
1163 if (restore_node_summary(sbi, segno, sum)) { 1163 int err;
1164
1165 err = restore_node_summary(sbi, segno, sum);
1166 if (err) {
1164 f2fs_put_page(new, 1); 1167 f2fs_put_page(new, 1);
1165 return -EINVAL; 1168 return err;
1166 } 1169 }
1167 } 1170 }
1168 } 1171 }