]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - mm/filemap.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / mm / filemap.c
index 6b9aee20f2426b88024a25749402fc5ca1ff7a0a..83a45d35468b961340fb19a958eee77d0e2e2297 100644 (file)
  *    ->inode_lock             (zap_pte_range->set_page_dirty)
  *    ->private_lock           (zap_pte_range->__set_page_dirty_buffers)
  *
- *  ->task->proc_lock
- *    ->dcache_lock            (proc_pid_lookup)
- *
  *  (code doesn't rely on that order, so you could switch it around)
  *  ->tasklist_lock             (memory_failure, collect_procs_ao)
  *    ->i_mmap_lock
@@ -301,7 +298,7 @@ int filemap_fdatawait_range(struct address_space *mapping, loff_t start_byte,
                                continue;
 
                        wait_on_page_writeback(page);
-                       if (PageError(page))
+                       if (TestClearPageError(page))
                                ret = -EIO;
                }
                pagevec_release(&pvec);
@@ -840,9 +837,6 @@ repeat:
                if (radix_tree_deref_retry(page))
                        goto restart;
 
-               if (page->mapping == NULL || page->index != index)
-                       break;
-
                if (!page_cache_get_speculative(page))
                        goto repeat;
 
@@ -852,6 +846,16 @@ repeat:
                        goto repeat;
                }
 
+               /*
+                * must check mapping and index after taking the ref.
+                * otherwise we can get both false positives and false
+                * negatives, which is just confusing to the caller.
+                */
+               if (page->mapping == NULL || page->index != index) {
+                       page_cache_release(page);
+                       break;
+               }
+
                pages[ret] = page;
                ret++;
                index++;
@@ -2223,7 +2227,7 @@ struct page *grab_cache_page_write_begin(struct address_space *mapping,
                gfp_notmask = __GFP_FS;
 repeat:
        page = find_lock_page(mapping, index);
-       if (likely(page))
+       if (page)
                return page;
 
        page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask);