Poision new and !uptodate buffers. Index: linux-2.6/fs/buffer.c =================================================================== --- linux-2.6.orig/fs/buffer.c +++ linux-2.6/fs/buffer.c @@ -1562,6 +1562,15 @@ void unmap_underlying_metadata(struct bl } EXPORT_SYMBOL(unmap_underlying_metadata); +static void poison_new_buffer(struct page *page, struct buffer_head *bh, int nr, int blocksize) +{ + if (buffer_new(bh) && !buffer_uptodate(bh)) { + void *kaddr = kmap_atomic(page, KM_USER0); + memset(kaddr + nr*blocksize, 0x0f, blocksize); + kunmap_atomic(kaddr, KM_USER0); + } +} + /* * NOTE! All mapped/uptodate combinations are valid: * @@ -1592,6 +1601,7 @@ static int __block_write_full_page(struc { int err; sector_t block; + int i = 0; sector_t last_block; struct buffer_head *bh, *head; const unsigned blocksize = 1 << inode->i_blkbits; @@ -1641,6 +1651,7 @@ static int __block_write_full_page(struc err = get_block(inode, block, bh, 1); if (err) goto recover; + poison_new_buffer(page, bh, i, blocksize); if (buffer_new(bh)) { /* blockdev mappings never come here */ clear_buffer_new(bh); @@ -1650,6 +1661,7 @@ static int __block_write_full_page(struc } bh = bh->b_this_page; block++; + i++; } while (bh != head); do { @@ -1808,6 +1820,7 @@ static int __block_prepare_write(struct unsigned block_start, block_end; sector_t block; int err = 0; + int i = 0; unsigned blocksize, bbits; struct buffer_head *bh, *head, *wait[2], **wait_bh=wait; @@ -1825,7 +1838,7 @@ static int __block_prepare_write(struct block = (sector_t)page->index << (PAGE_CACHE_SHIFT - bbits); for(bh = head, block_start = 0; bh != head || !block_start; - block++, block_start=block_end, bh = bh->b_this_page) { + block++, i++, block_start=block_end, bh = bh->b_this_page) { block_end = block_start + blocksize; if (block_end <= from || block_start >= to) { if (PageUptodate(page)) { @@ -1841,6 +1854,7 @@ static int __block_prepare_write(struct err = get_block(inode, block, bh, 1); if (err) break; + poison_new_buffer(page, bh, i, blocksize); if (buffer_new(bh)) { unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); @@ -2087,6 +2101,7 @@ int block_read_full_page(struct page *pa err = get_block(inode, iblock, bh, 0); if (err) SetPageError(page); + poison_new_buffer(page, bh, i, blocksize); } if (!buffer_mapped(bh)) { void *kaddr = kmap_atomic(page, KM_USER0); @@ -2404,6 +2419,7 @@ int nobh_prepare_write(struct page *page &map_bh, create); if (ret) goto failed; + poison_new_buffer(page, &map_bh, block_in_page, blocksize); if (!buffer_mapped(&map_bh)) is_mapped_to_disk = 0; if (buffer_new(&map_bh)) @@ -2619,7 +2635,7 @@ int block_truncate_page(struct address_s pgoff_t index = from >> PAGE_CACHE_SHIFT; unsigned offset = from & (PAGE_CACHE_SIZE-1); unsigned blocksize; - sector_t iblock; + sector_t iblock, i; unsigned length, pos; struct inode *inode = mapping->host; struct page *page; @@ -2648,8 +2664,10 @@ int block_truncate_page(struct address_s /* Find the buffer that contains "offset" */ bh = page_buffers(page); pos = blocksize; + i = 0; while (offset >= pos) { bh = bh->b_this_page; + i++; iblock++; pos += blocksize; } @@ -2660,6 +2678,7 @@ int block_truncate_page(struct address_s err = get_block(inode, iblock, bh, 0); if (err) goto unlock; + poison_new_buffer(page, bh, i, blocksize); /* unmapped? It's a hole - nothing to do */ if (!buffer_mapped(bh)) goto unlock;