lkml.org 
[lkml]   [2001]   [Dec]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: ramdisk corruption problems - was: RE: pivot_root and initrd kern el panic woes
    In article <D52B19A7284D32459CF20D579C4B0C0211CB0F@mail0.myrio.com> you write:
    >Yes, this does fix the problem. Thank you very much!
    >
    >Hopefully something like this will make it into 2.4.18?

    This does not seem quite right.

    >Tachino Nobuhiro (tachino@open.nm.fujitsu.co.jp) wrote:
    >> Hello,
    >>
    >> Following patch may fix your problem.
    >>
    >> diff -r -u linux-2.4.17-rc2.org/drivers/block/rd.c
    >> linux-2.4.17-rc2/drivers/block/rd.c
    >> --- linux-2.4.17-rc2.org/drivers/block/rd.c Thu Dec 20 20:30:57 2001
    >> +++ linux-2.4.17-rc2/drivers/block/rd.c Thu Dec 20 20:46:53 2001
    >> @@ -194,9 +194,11 @@
    >> static int ramdisk_readpage(struct file *file, struct page * page)
    >> {
    >> if (!Page_Uptodate(page)) {
    >> - memset(kmap(page), 0, PAGE_CACHE_SIZE);
    >> - kunmap(page);
    >> - flush_dcache_page(page);
    >> + if (!page->buffers) {
    >> + memset(kmap(page), 0, PAGE_CACHE_SIZE);
    >> + kunmap(page);
    >> + flush_dcache_page(page);
    >> + }
    >> SetPageUptodate(page);
    >> }
    >> UnlockPage(page);
    >>
    >>
    >> grow_dev_page() creates not Uptodate page which has valid
    >> buffers, so
    >> it is wrong that ramdisk_readpage() clears whole page unconditionally.

    The problem is that having buffers doesn't necessarily always mean that
    they are valid, nor that _all_ of them are valid.

    Also, if the ramdisk "readpage" code is wrong, then so is the
    "prepare_write" code. They share the same logic, which basically says
    that "if the page isn't up-to-date, then it is zero". Which is always
    true for normal read/write accesses, but as you found out it's not true
    when parts of the page have been accessed by filesystems through the
    buffers.

    So the code _should_ use a common helper, something like

    static void ramdisk_updatepage(struct page * page)
    {
    if (!Page_Uptodate(page)) {
    struct buffer_head *bh = page->buffers;
    void * address = page_address(page);
    if (bh) {
    struct buffer_head *tmp = bh;
    do {
    if (!buffer_uptodate(tmp)) {
    memset(address, 0, tmp->b_size);
    set_buffer_uptodate(tmp);
    }
    address += tmp->b_size;
    tmp = tmp->b_this_page;
    } while (tmp != bh);
    } else
    memset(address, 0, PAGE_SIZE);
    flush_dcache_page(page);
    SetPageUptodate(page);
    }
    }

    and then ramdisk_readpage() would just be

    kmap(page);
    ramdisk_updatepage(page);
    UnlockPage(page);
    kunmap(page);
    return 0;

    while ramdisk_prepare_write() would be

    ramdisk_updatepage(page);
    SetPageDirty(page);
    return 0;

    NOTE NOTE NOTE! This is untested. Please somebody test it, and in
    particular verify that there aren't any stupid highmem bugs, and
    resubmit the patch to me and Marcelo, ok?

    Linus
    -
    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:14    [W:2.495 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site