[PATCH] Re: test10-pre7

From: Alexander Viro (viro@math.psu.edu)
Date: Mon Oct 30 2000 - 15:34:44 EST


On Mon, 30 Oct 2000, Linus Torvalds wrote:

>
> Ok, this one contains at least a preliminary fix for the problem with
> truncate together with a concurrent page access - the bug that causes
> oopses in block_read_full_page() and filemap_nopage().
>
> This is a fairly minimal fix, and I'll still have to verify that I caught
> all the relevant places, but I wanted people who have seen this problem to
> please test this out asap - I'll make a real test10 later once I've
> integrated some further patches from Alan and Jeff, but this should fix
> the major show-stopper bug.

Unfortunately, it doesn't fix the thing. ->sync_page() is called when we
do not own the page lock and nfs_sync_page() uses page->mapping. Yes, we
check it before calling the bloody thing, but we don't own the lock.
Problem only for NFS, but I'm not sure what to do about it - the whole
point of ->sync_page() seems to be (if I understood Trond's intentions
right) in forcing the ->readpage() in progress.

Another place you've missed is in read_cache_page(). That one is easy - we've
just locked the page and we should just repeat the whole thing if it's out
of cache.

One more is in filemap_swapout() - dunno, I just shifted the check to
filemap_write_page().

One more: check in do_generic_file_read() for ->mapping->i_shared_mmap.
Fix: trivial.

The last one is in deactivate_page_nolock() - there we check the ->mapping
without pagecache_lock and without page lock. Hell knows whether it's a
bug or not. Rik?

Minimal patch (against -pre7) follows. It still leaves sync_page() problem
open - any suggestions on that one are very welcome. Other than that and
deactivate_page_nolock() we should be safe wrt. ->mapping. Please, apply -
after that we will be in sync. nfs_sync_page() is still a problem and if
somebody (Trond?) might tell WTF it is supposed to be...
                                                        Cheers,
                                                                Al

--- filemap.c Mon Oct 30 18:46:17 2000
+++ filemap.c.new Mon Oct 30 18:54:05 2000
@@ -981,7 +981,7 @@
                  * 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);
 
                 /*
@@ -1473,7 +1473,8 @@
          * vma/file is guaranteed to exist in the unmap/sync cases because
          * mmap_sem is held.
          */
- return page->mapping->a_ops->writepage(file, page);
+ /* Nothing to do if somebody truncated the page from under us.. */
+ return page->mapping?page->mapping->a_ops->writepage(file, page):0;
 }
 
 
@@ -1544,9 +1545,7 @@
         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 +2312,20 @@
                                 int (*filler)(void *,struct page*),
                                 void *data)
 {
- struct page *page = __read_cache_page(mapping, index, filler, data);
+ struct page *page;
+retry:
+ page = __read_cache_page(mapping, index, filler, data);
         int err;
 
         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;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Oct 31 2000 - 21:00:27 EST