lkml.org 
[lkml]   [2007]   [Oct]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] rd: Preserve the dirty bit in init_page_buffers()
    Date

    The problem: When we are trying to free buffers try_to_free_buffers()
    will look at ramdisk pages with clean buffer heads and remove the
    dirty bit from the page. Resulting in ramdisk pages with data that get
    removed from the page cache. Ouch!

    Buffer heads appear on ramdisk pages when a filesystem calls
    __getblk() which through a series of function calls eventually calls
    init_page_buffers().

    So to fix the mismatch between buffer head and page state this patch
    modifies init_page_buffers() to transfer the dirty bit from the page to
    the buffer heads like we currently do for the uptodate bit.

    This patch is safe as only __getblk calls init_page_buffers, and
    there are only two implementations of block devices cached in the
    page cache. The generic implementation in block_dev.c and the
    implementation in rd.c.

    The generic implementation of block devices always does everything
    in terms of buffer heads so it always has buffer heads allocated
    before a page is marked dirty so this change does not affect it.

    Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
    ---
    fs/buffer.c | 3 +++
    1 files changed, 3 insertions(+), 0 deletions(-)

    diff --git a/fs/buffer.c b/fs/buffer.c
    index 75b51df..8b87beb 100644
    --- a/fs/buffer.c
    +++ b/fs/buffer.c
    @@ -972,6 +972,7 @@ init_page_buffers(struct page *page, struct block_device *bdev,
    struct buffer_head *head = page_buffers(page);
    struct buffer_head *bh = head;
    int uptodate = PageUptodate(page);
    + int dirty = PageDirty(page);

    do {
    if (!buffer_mapped(bh)) {
    @@ -980,6 +981,8 @@ init_page_buffers(struct page *page, struct block_device *bdev,
    bh->b_blocknr = block;
    if (uptodate)
    set_buffer_uptodate(bh);
    + if (dirty)
    + set_buffer_dirty(bh);
    set_buffer_mapped(bh);
    }
    block++;
    --
    1.5.3.rc6.17.g1911
    -
    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: 2007-10-16 00:43    [W:0.029 / U:0.972 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site