* [patch 2/18] block_truncate_page fix
@ 2002-05-26 20:38 Andrew Morton
0 siblings, 0 replies; only message in thread
From: Andrew Morton @ 2002-05-26 20:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: lkml
Fix bug in block_truncate_page().
When buffers are attached to an uptodate page, they are marked as
being uptodate. To preserve buffer/page state coherency. Dirtiness
is handled in the same way.
But block_truncate_page() assumes that a buffer which is unmapped and
uptodate is over a hole. That's not the case, and the net effect is
that block_truncate_page() is failing to zero the block outside the
truncation point.
This only happens if the page has a disk mapping but has no attached
buffers on entry to block_truncate_page(). That's never the case in
current kernels, so the problem does not exhibit (it _does_ exhibit
with direct-to-BIO bypass-the-buffers I/O).
There are actually three possible states of buffer mappedness:
- Buffer has a disk mapping (buffer_mapped(bh) == true)
- buffer is over a hole (buffer_mapped(bh) == false)
- don't know. Need to run get_block() (buffer_mapped(bh) == false)
This ambiguity could be resolved by added another buffer state bit
(BH_mapping_state_known?) but given that we already elide the get_block
calls for the common case (buffer outside i_size) it is unlikely that
the complexity is worthwhile.
=====================================
--- 2.5.18/fs/buffer.c~block_truncate_page Sun May 26 12:37:39 2002
+++ 2.5.18-akpm/fs/buffer.c Sun May 26 12:37:39 2002
@@ -2079,11 +2079,10 @@ int block_truncate_page(struct address_s
err = 0;
if (!buffer_mapped(bh)) {
- /* Hole? Nothing to do */
- if (buffer_uptodate(bh))
+ err = get_block(inode, iblock, bh, 0);
+ if (err)
goto unlock;
- get_block(inode, iblock, bh, 0);
- /* Still unmapped? Nothing to do */
+ /* unmapped? It's a hole - nothing to do */
if (!buffer_mapped(bh))
goto unlock;
}
--- 2.5.18/fs/ext3/inode.c~block_truncate_page Sun May 26 12:37:39 2002
+++ 2.5.18-akpm/fs/ext3/inode.c Sun May 26 12:37:40 2002
@@ -1408,11 +1408,8 @@ static int ext3_block_truncate_page(hand
err = 0;
if (!buffer_mapped(bh)) {
- /* Hole? Nothing to do */
- if (buffer_uptodate(bh))
- goto unlock;
ext3_get_block(inode, iblock, bh, 0);
- /* Still unmapped? Nothing to do */
+ /* unmapped? It's a hole - nothing to do */
if (!buffer_mapped(bh))
goto unlock;
}
-
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-05-26 20:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-26 20:38 [patch 2/18] block_truncate_page fix Andrew Morton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.