lkml.org 
[lkml]   [2002]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] swap writepages swizzled
    tmpfs failed fsx+swapout tests after many hours, a page found zeroed.
    Not a truncate problem, but mirror image of earlier truncate problems:
    swap goes through mpage_writepages, which must therefore allow for a
    sudden swizzle back to file identity.

    Second time this caught us, so I've audited the tree for other places
    which might be surprised by such swizzling. The only others I found
    were (perhaps) in the parisc and sparc64 flush_dcache_page called
    from do_generic_mapping_read on a looped tmpfs file which is also
    mmapped; but that's a very marginal case, I wanted to understand it
    better before making any edit, and now realize that hch's sendfile
    in loop eliminates it (now go through do_shmem_file_read instead:
    similar but crucially this locks the page when raising its count,
    which is enough to keep vmscan from interfering).

    Patch applies to 2.5.47, or 2.5.47-mm1 with offsets and fuzz.
    Only the patch to mpage.c is required: I think it's worth adding
    BUG_ON checks in __set_page_dirty_nobuffers and get_swap_bio,
    just leave those out if you disagree; similarly, optional patch
    to try_to_free_buffers, once upon a time swap came that way,
    happily ever after it doesn't, so the test seems misleading.

    Hugh

    --- 2.5.47/fs/mpage.c Mon Nov 11 08:26:55 2002
    +++ linux/fs/mpage.c Mon Nov 11 17:01:27 2002
    @@ -587,12 +587,19 @@
    page_cache_get(page);
    write_unlock(&mapping->page_lock);

    + /*
    + * At this point we hold neither mapping->page_lock nor
    + * lock on the page itself: the page may be truncated or
    + * invalidated (changing page->mapping to NULL), or even
    + * swizzled back from swapper_space to tmpfs file mapping.
    + */
    +
    lock_page(page);

    if (sync)
    wait_on_page_writeback(page);

    - if (page->mapping && !PageWriteback(page) &&
    + if (page->mapping == mapping && !PageWriteback(page) &&
    test_clear_page_dirty(page)) {
    if (writepage) {
    ret = (*writepage)(page);
    --- 2.5.47/mm/page-writeback.c Thu Oct 31 05:40:06 2002
    +++ linux/mm/page-writeback.c Mon Nov 11 17:01:27 2002
    @@ -613,6 +613,7 @@
    if (mapping) {
    write_lock(&mapping->page_lock);
    if (page->mapping) { /* Race with truncate? */
    + BUG_ON(page->mapping != mapping);
    if (!mapping->backing_dev_info->memory_backed)
    inc_page_state(nr_dirty);
    list_del(&page->list);
    --- 2.5.47/mm/page_io.c Mon Oct 7 20:37:50 2002
    +++ linux/mm/page_io.c Mon Nov 11 17:01:27 2002
    @@ -30,6 +30,7 @@
    struct swap_info_struct *sis;
    swp_entry_t entry;

    + BUG_ON(!PageSwapCache(page));
    entry.val = page->index;
    sis = get_swap_info_struct(swp_type(entry));

    --- 2.5.47/fs/buffer.c Mon Nov 11 08:26:55 2002
    +++ linux/fs/buffer.c Mon Nov 11 17:01:27 2002
    @@ -2496,7 +2496,7 @@

    spin_lock(&mapping->private_lock);
    ret = drop_buffers(page, &buffers_to_free);
    - if (ret && !PageSwapCache(page)) {
    + if (ret) {
    /*
    * If the filesystem writes its buffers by hand (eg ext3)
    * then we can have clean buffers against a dirty page. We
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:30    [W:0.022 / U:33.068 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site