diff -urN 2.4.19pre6/fs/buffer.c prepare-write/fs/buffer.c --- 2.4.19pre6/fs/buffer.c Fri Apr 5 10:11:08 2002 +++ prepare-write/fs/buffer.c Wed Apr 10 04:42:02 2002 @@ -1689,8 +1689,21 @@ * Zero out any newly allocated blocks to avoid exposing stale * data. If BH_New is set, we know that the block was newly * allocated in the above loop. + * + * Details the buffer can be new and uptodate because: + * 1) hole in uptodate page, get_block(create) allocate the block, so the buffer is + * new and additionally we also mark it uptodate + * 2) The buffer is not mapped and uptodate due a previous partial read. + * + * We can always ignore uptodate buffers here, if you mark a buffer uptodate + * you must make sure it contains the right data first. */ bh = head; + /* + * We must stop the "undo/clear" fixup pass not at the caller "to" but at the last + * block that we successfully arrived in the main loop. + */ + to = block_start; /* stop at the last successfully handled block */ block_start = 0; do { block_end = block_start+blocksize; @@ -1698,10 +1711,9 @@ goto next_bh; if (block_start >= to) break; - if (buffer_new(bh)) { - if (buffer_uptodate(bh)) - printk(KERN_ERR "%s: zeroing uptodate buffer!\n", __FUNCTION__); + if (buffer_new(bh) && !buffer_uptodate(bh)) { memset(kaddr+block_start, 0, bh->b_size); + flush_dcache_page(page); set_bit(BH_Uptodate, &bh->b_state); mark_buffer_dirty(bh); }