aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authordavem <davem>2000-10-31 22:30:21 +0000
committerdavem <davem>2000-10-31 22:30:21 +0000
commit3014517da703bd81d82c3683683c5080e76abbb1 (patch)
tree2c5280da67823c2e47c2003ab7bb3bf651058200 /mm
parent268c4b3ec53396a78d0c604d484cede1ae94a923 (diff)
downloadnetdev-vger-cvs-3014517da703bd81d82c3683683c5080e76abbb1.tar.gz
Merge mainline to 2.4.0-test10 final.
Diffstat (limited to 'mm')
-rw-r--r--mm/filemap.c38
-rw-r--r--mm/memory.c2
2 files changed, 26 insertions, 14 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index c5477e6a6..0912e7668 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -981,7 +981,7 @@ page_ok:
* virtual addresses, take care about potential aliasing
* before reading the page on the kernel side.
*/
- if (page->mapping->i_mmap_shared != NULL)
+ if (mapping->i_mmap_shared != NULL)
flush_dcache_page(page);
/*
@@ -1463,17 +1463,25 @@ page_not_uptodate:
return NULL;
}
+/*
+ * If a task terminates while we're swapping the page, the vma and
+ * and file could be released: try_to_swap_out has done a get_file.
+ * vma/file is guaranteed to exist in the unmap/sync cases because
+ * mmap_sem is held.
+ *
+ * The "mapping" test takes care of somebody having truncated the
+ * page and thus made this write-page a no-op..
+ */
static int filemap_write_page(struct file *file,
struct page * page,
int wait)
{
- /*
- * If a task terminates while we're swapping the page, the vma and
- * and file could be released: try_to_swap_out has done a get_file.
- * vma/file is guaranteed to exist in the unmap/sync cases because
- * mmap_sem is held.
- */
- return page->mapping->a_ops->writepage(file, page);
+ struct address_space * mapping = page->mapping;
+ int error = 0;
+
+ if (mapping)
+ error = mapping->a_ops->writepage(file, page);
+ return error;
}
@@ -1543,10 +1551,7 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
spin_unlock(&vma->vm_mm->page_table_lock);
lock_page(page);
- error = 0;
- /* Nothing to do if somebody truncated the page from under us.. */
- if (page->mapping)
- error = filemap_write_page(vma->vm_file, page, 1);
+ error = filemap_write_page(vma->vm_file, page, 1);
UnlockPage(page);
page_cache_free(page);
@@ -2313,13 +2318,20 @@ struct page *read_cache_page(struct address_space *mapping,
int (*filler)(void *,struct page*),
void *data)
{
- struct page *page = __read_cache_page(mapping, index, filler, data);
+ struct page *page;
int err;
+retry:
+ page = __read_cache_page(mapping, index, filler, data);
if (IS_ERR(page) || Page_Uptodate(page))
goto out;
lock_page(page);
+ if (!page->mapping) {
+ UnlockPage(page);
+ page_cache_release(page);
+ goto retry;
+ }
if (Page_Uptodate(page)) {
UnlockPage(page);
goto out;
diff --git a/mm/memory.c b/mm/memory.c
index 4fb133461..4dfd93e69 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -781,8 +781,8 @@ int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long
*/
static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
{
- flush_tlb_page(vma, address);
set_pte(page_table, entry);
+ flush_tlb_page(vma, address);
update_mmu_cache(vma, address, entry);
}