diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 5dfc093ceb3d..5631d6b2a62d 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -868,6 +868,7 @@ void do_generic_mapping_read(struct address_space *mapping, | |||
868 | unsigned long last_index; | 868 | unsigned long last_index; |
869 | unsigned long next_index; | 869 | unsigned long next_index; |
870 | unsigned long prev_index; | 870 | unsigned long prev_index; |
871 | unsigned int prev_offset; | ||
871 | loff_t isize; | 872 | loff_t isize; |
872 | struct page *cached_page; | 873 | struct page *cached_page; |
873 | int error; | 874 | int error; |
@@ -876,7 +877,8 @@ void do_generic_mapping_read(struct address_space *mapping, | |||
876 | cached_page = NULL; | 877 | cached_page = NULL; |
877 | index = *ppos >> PAGE_CACHE_SHIFT; | 878 | index = *ppos >> PAGE_CACHE_SHIFT; |
878 | next_index = index; | 879 | next_index = index; |
879 | prev_index = ra.prev_page; | 880 | prev_index = ra.prev_index; |
881 | prev_offset = ra.prev_offset; | ||
880 | last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; | 882 | last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; |
881 | offset = *ppos & ~PAGE_CACHE_MASK; | 883 | offset = *ppos & ~PAGE_CACHE_MASK; |
882 | 884 | ||
@@ -924,10 +926,10 @@ page_ok: | |||
924 | flush_dcache_page(page); | 926 | flush_dcache_page(page); |
925 | 927 | ||
926 | /* | 928 | /* |
927 | * When (part of) the same page is read multiple times | 929 | * When a sequential read accesses a page several times, |
928 | * in succession, only mark it as accessed the first time. | 930 | * only mark it as accessed the first time. |
929 | */ | 931 | */ |
930 | if (prev_index != index) | 932 | if (prev_index != index || offset != prev_offset) |
931 | mark_page_accessed(page); | 933 | mark_page_accessed(page); |
932 | prev_index = index; | 934 | prev_index = index; |
933 | 935 | ||
@@ -945,6 +947,8 @@ page_ok: | |||
945 | offset += ret; | 947 | offset += ret; |
946 | index += offset >> PAGE_CACHE_SHIFT; | 948 | index += offset >> PAGE_CACHE_SHIFT; |
947 | offset &= ~PAGE_CACHE_MASK; | 949 | offset &= ~PAGE_CACHE_MASK; |
950 | prev_offset = offset; | ||
951 | ra.prev_offset = offset; | ||
948 | 952 | ||
949 | page_cache_release(page); | 953 | page_cache_release(page); |
950 | if (ret == nr && desc->count) | 954 | if (ret == nr && desc->count) |
@@ -1446,30 +1450,6 @@ page_not_uptodate: | |||
1446 | majmin = VM_FAULT_MAJOR; | 1450 | majmin = VM_FAULT_MAJOR; |
1447 | count_vm_event(PGMAJFAULT); | 1451 | count_vm_event(PGMAJFAULT); |
1448 | } | 1452 | } |
1449 | lock_page(page); | ||
1450 | |||
1451 | /* Did it get unhashed while we waited for it? */ | ||
1452 | if (!page->mapping) { | ||
1453 | unlock_page(page); | ||
1454 | page_cache_release(page); | ||
1455 | goto retry_all; | ||
1456 | } | ||
1457 | |||
1458 | /* Did somebody else get it up-to-date? */ | ||
1459 | if (PageUptodate(page)) { | ||
1460 | unlock_page(page); | ||
1461 | goto success; | ||
1462 | } | ||
1463 | |||
1464 | error = mapping->a_ops->readpage(file, page); | ||
1465 | if (!error) { | ||
1466 | wait_on_page_locked(page); | ||
1467 | if (PageUptodate(page)) | ||
1468 | goto success; | ||
1469 | } else if (error == AOP_TRUNCATED_PAGE) { | ||
1470 | page_cache_release(page); | ||
1471 | goto retry_find; | ||
1472 | } | ||
1473 | 1453 | ||
1474 | /* | 1454 | /* |
1475 | * Umm, take care of errors if the page isn't up-to-date. | 1455 | * Umm, take care of errors if the page isn't up-to-date. |
@@ -1726,7 +1706,7 @@ int generic_file_readonly_mmap(struct file * file, struct vm_area_struct * vma) | |||
1726 | EXPORT_SYMBOL(generic_file_mmap); | 1706 | EXPORT_SYMBOL(generic_file_mmap); |
1727 | EXPORT_SYMBOL(generic_file_readonly_mmap); | 1707 | EXPORT_SYMBOL(generic_file_readonly_mmap); |
1728 | 1708 | ||
1729 | static inline struct page *__read_cache_page(struct address_space *mapping, | 1709 | static struct page *__read_cache_page(struct address_space *mapping, |
1730 | unsigned long index, | 1710 | unsigned long index, |
1731 | int (*filler)(void *,struct page*), | 1711 | int (*filler)(void *,struct page*), |
1732 | void *data) | 1712 | void *data) |
@@ -1763,17 +1743,11 @@ repeat: | |||
1763 | return page; | 1743 | return page; |
1764 | } | 1744 | } |
1765 | 1745 | ||
1766 | /** | 1746 | /* |
1767 | * read_cache_page - read into page cache, fill it if needed | 1747 | * Same as read_cache_page, but don't wait for page to become unlocked |
1768 | * @mapping: the page's address_space | 1748 | * after submitting it to the filler. |
1769 | * @index: the page index | ||
1770 | * @filler: function to perform the read | ||
1771 | * @data: destination for read data | ||
1772 | * | ||
1773 | * Read into the page cache. If a page already exists, | ||
1774 | * and PageUptodate() is not set, try to fill the page. | ||
1775 | */ | 1749 | */ |
1776 | struct page *read_cache_page(struct address_space *mapping, | 1750 | struct page *read_cache_page_async(struct address_space *mapping, |
1777 | unsigned long index, | 1751 | unsigned long index, |
1778 | int (*filler)(void *,struct page*), | 1752 | int (*filler)(void *,struct page*), |
1779 | void *data) | 1753 | void *data) |
@@ -1805,6 +1779,39 @@ retry: | |||
1805 | page = ERR_PTR(err); | 1779 | page = ERR_PTR(err); |
1806 | } | 1780 | } |
1807 | out: | 1781 | out: |
1782 | mark_page_accessed(page); | ||
1783 | return page; | ||
1784 | } | ||
1785 | EXPORT_SYMBOL(read_cache_page_async); | ||
1786 | |||
1787 | /** | ||
1788 | * read_cache_page - read into page cache, fill it if needed | ||
1789 | * @mapping: the page's address_space | ||
1790 | * @index: the page index | ||
1791 | * @filler: function to perform the read | ||
1792 | * @data: destination for read data | ||
1793 | * | ||
1794 | * Read into the page cache. If a page already exists, and PageUptodate() is | ||
1795 | * not set, try to fill the page then wait for it to become unlocked. | ||
1796 | * | ||
1797 | * If the page does not get brought uptodate, return -EIO. | ||
1798 | */ | ||
1799 | struct page *read_cache_page(struct address_space *mapping, | ||
1800 | unsigned long index, | ||
1801 | int (*filler)(void *,struct page*), | ||
1802 | void *data) | ||
1803 | { | ||
1804 | struct page *page; | ||
1805 | |||
1806 | page = read_cache_page_async(mapping, index, filler, data); | ||
1807 | if (IS_ERR(page)) | ||
1808 | goto out; | ||
1809 | wait_on_page_locked(page); | ||
1810 | if (!PageUptodate(page)) { | ||
1811 | page_cache_release(page); | ||
1812 | page = ERR_PTR(-EIO); | ||
1813 | } | ||
1814 | out: | ||
1808 | return page; | 1815 | return page; |
1809 | } | 1816 | } |
1810 | EXPORT_SYMBOL(read_cache_page); | 1817 | EXPORT_SYMBOL(read_cache_page); |