lkml.org 
[lkml]   [2000]   [Sep]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Still ext2-corruption in test8-pre5 (incl. OOPS)



    On Tue, 5 Sep 2000, Linus Torvalds wrote:

    >
    >
    > On Tue, 5 Sep 2000, Alexander Viro wrote:
    > >
    > > WTF? <thinks> Erm... Linus, I suspect that we are losing the thing on the
    > > very simple effect: readpage() gets buffer_heads, all right, but then
    > > we lose the lock. That's your window for losing the buffer_head ring of
    > > that page.
    >
    > Note that it's not even a small window: we get an up-to-date page, but
    > readpage() can have happened hours, days, years before. The buffer-head
    > ring _has_ been there at some earlier time, but there's nothing that
    > guarantees that it still is there.
    >
    > Fixing this is not hard, happily. I'll do it. The only issue is whether to
    > just copy one of the existing functions and make changes, or try to share
    > code and have helper functions. The loop over the page doing the
    > get_block() is certainly something that all of the functions for
    > reading/writing need to do, and I suspect that I really should split
    > things up a bit and share more code than we do now.
    >
    > If you WANT to do it, holler. I'm not glutton for punishment, but it
    > doesn't look that bad.

    Me neither, but IMO I have a cop-out:

    --- buffer.c Tue Sep 5 21:23:41 2000
    +++ buffer.c.new Tue Sep 5 21:28:53 2000
    @@ -1724,12 +1724,24 @@
    return 0;
    }

    +/*
    + * If it would be '74 that would go into libc...
    + */
    +int mem_is_zero(char *p, unsigned len)
    +{
    + while (len--)
    + if (*p++)
    + return 0;
    + return 1;
    +}
    +
    int block_zero_page(struct address_space *mapping, loff_t from, unsigned length)
    {
    unsigned long index = from >> PAGE_CACHE_SHIFT;
    unsigned offset = from & (PAGE_CACHE_SIZE-1);
    struct inode *inode = (struct inode *)mapping->host;
    struct page *page;
    + char *kaddr;
    int err;

    if (!length)
    @@ -1745,9 +1757,18 @@
    if (!Page_Uptodate(page))
    goto unlock;

    - memset((char *) kmap(page) + offset, 0, length);
    + kaddr = (char*)kmap(page);
    + err = 0;
    + if (mem_is_zero(kaddr+offset, length))
    + goto unmap;
    + err = mapping->a_ops->prepare_write(NULL, page, offset, offset+length);
    + if (err)
    + goto unmap;
    + memset(kaddr+offset, 0, length);
    flush_dcache_page(page);
    __block_commit_write(inode, page, offset, offset+length);
    + kunmap(page);
    +unmap:
    kunmap(page);
    err = 0;

    -
    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/

    \
     
     \ /
      Last update: 2005-03-22 12:38    [W:0.025 / U:30.516 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site