Anton Altaparmakov 152becd26e [PATCH] Bug in error recovery in fs/buffer.c::__block_prepare_write()
fs/buffer.c::__block_prepare_write() has broken error recovery.  It calls
the get_block() callback with "create = 1" and if that succeeds it
immediately clears buffer_new on the just allocated buffer (which has
buffer_new set).

The bug is that if an error occurs and get_block() returns != 0, we break
from this loop and go into recovery code.  This code has this comment:

/* Error case: */
/*
 * 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.
 */

So the intent is obviously good in that it wants to clear just allocated
and hence not zeroed buffers.  However the code recognises allocated
buffers by checking for buffer_new being set.

Unfortunately __block_prepare_write() as discussed above already cleared
buffer_new on all allocated buffers thus no buffers will be cleared during
error recovery and old data will be leaked.

The simplest way I can see to fix this is to make the current recovery code
work by _not_ clearing buffer_new after calling get_block() in
__block_prepare_write().

We cannot safely allow buffer_new buffers to "leak out" of
__block_prepare_write(), thus we simply do a quick loop over the buffers
clearing buffer_new on each of them if it is set just before returning
"success" from __block_prepare_write().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-23 09:45:34 -07:00
..
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-01 08:59:01 -07:00
2005-04-16 15:20:36 -07:00
2005-06-21 19:07:35 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-06-23 09:45:33 -07:00
2005-06-23 09:45:33 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-28 16:46:11 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-05 16:36:47 -07:00
2005-06-23 09:45:33 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-06-23 09:45:33 -07:00
2005-05-05 16:36:47 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-06-23 09:45:26 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-06-21 19:51:18 -07:00
2005-05-01 08:59:16 -07:00
2005-04-16 15:20:36 -07:00
2005-05-05 16:36:47 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-01 08:59:26 -07:00
2005-04-16 15:20:36 -07:00
2005-05-05 16:36:47 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-06-23 09:45:26 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-05 16:36:47 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-05-05 16:36:47 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00
2005-04-16 15:20:36 -07:00