All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@zip.com.au>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: lkml <linux-kernel@vger.kernel.org>
Subject: [patch 2/18] block_truncate_page fix
Date: Sun, 26 May 2002 13:38:10 -0700	[thread overview]
Message-ID: <3CF147B2.9D6D7C2F@zip.com.au> (raw)



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;
 	}


-

                 reply	other threads:[~2002-05-26 20:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3CF147B2.9D6D7C2F@zip.com.au \
    --to=akpm@zip.com.au \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.