linux/fs/ubifs
Artem Bityutskiy 6ed09c34b7 UBIFS: fix assertion warning and refine comments
This patch fixes the following UBIFS assertion warning:

UBIFS assert failed in do_readpage at 115 (pid 199)
[<b00321b8>] (unwind_backtrace+0x0/0xdc) from [<af025118>]
(do_readpage+0x108/0x594 [ubifs])
[<af025118>] (do_readpage+0x108/0x594 [ubifs]) from [<af025764>]
(ubifs_write_end+0x1c0/0x2e8 [ubifs])
[<af025764>] (ubifs_write_end+0x1c0/0x2e8 [ubifs]) from
[<b00a0164>] (generic_file_buffered_write+0x18c/0x270)
[<b00a0164>] (generic_file_buffered_write+0x18c/0x270) from
[<b00a08d4>] (__generic_file_aio_write+0x478/0x4c0)
[<b00a08d4>] (__generic_file_aio_write+0x478/0x4c0) from
[<b00a0984>] (generic_file_aio_write+0x68/0xc8)
[<b00a0984>] (generic_file_aio_write+0x68/0xc8) from
[<af024a78>] (ubifs_aio_write+0x178/0x1d8 [ubifs])
[<af024a78>] (ubifs_aio_write+0x178/0x1d8 [ubifs]) from
[<b00d104c>] (do_sync_write+0xb0/0x100)
[<b00d104c>] (do_sync_write+0xb0/0x100) from [<b00d1abc>]
(vfs_write+0xac/0x154)
[<b00d1abc>] (vfs_write+0xac/0x154) from [<b00d1c10>]
(sys_write+0x3c/0x68)
[<b00d1c10>] (sys_write+0x3c/0x68) from [<b002d9a0>]
(ret_fast_syscall+0x0/0x2c)

The 'PG_checked' flag is used to indicate that the page does not
supposedly exist on the media (e.g., a hole or a page beyond the
inode size), so it requires slightly bigger budget, because we have
to account the indexing size increase. And this flag basically
tells that the budget for this page has to be "new page budget".
The "new page budget" is slightly bigger than the "existing page
budget".

The 'do_readpage()' function has the following assertion which
sometimes is hit: 'ubifs_assert(!PageChecked(page))'. Obviously,
the meaning of this assertion is: "I should not be asked to read
a page which does not exist on the media".

However, in 'ubifs_write_begin()' we have a small "trick". Notice,
that VFS may write pages which were not read yet, so the page data
were not loaded from the media to the page cache yet. If VFS tells
that it is going to change only some part of the page, we obviously
have to load it from the media. However, if VFS tells that it is
going to change whole page, we do not read it from the media for
optimization purposes.

However, since we do not read it, we do not know if it exists on
the media or not (a hole, etc). So we set the 'PG_checked' flag
to this page to force bigger budget, just in case.

So 'ubifs_write_begin()' sets 'PG_checked'. Then we are in
'ubifs_write_end()'. And VFS tells us: "hey, for some reasons I
changed my mind and did not change whole page". Frankly, I do not
know why this happens, but I hit this somehow on an ARM platform.
And this is extremely rare.

So in this case UBIFS does the following:

1. Cancels allocated budget.
2. Loads the page from the media by calling 'do_readpage()'.
3. Asks VFS to repeat the whole write operation from the very
   beginning (call '->write_begin() again, etc).

And the assertion warning is hit at the step 2 - remember we have
the 'PG_checked' set for this page, and 'do_readpage()' does not
like this. So this patch fixes the problem by adding step 1.5 and
cleaning the 'PG_checked' before calling 'do_readpage()'.

All in all, this patch does not fix any functionality issue, but it
silences UBIFS false positive warning which may happen in very very
rare cases.

And while on it, this patch also improves a commentary which explains
the reasons of setting the 'PG_checked' flag for the page. The old
commentary was a bit difficult to understand.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
2011-03-24 16:16:18 +02:00
..
budget.c writeback: enforce s_umount locking in writeback_inodes_sb 2010-06-11 12:58:07 +02:00
commit.c UBIFS: do not start the commit if there is nothing to commit 2011-01-25 10:21:13 +02:00
compress.c UBIFS: fix sparse warnings 2008-12-31 14:13:24 +02:00
debug.c UBIFS: use GFP_NOFS properly 2011-03-24 16:14:26 +02:00
debug.h UBIFS: clean-up commentaries 2011-03-16 14:05:25 +02:00
dir.c fs: Remove i_nlink check from file system link callback 2011-03-15 02:21:44 -04:00
file.c UBIFS: fix assertion warning and refine comments 2011-03-24 16:16:18 +02:00
find.c UBIFS: improve find function interface 2009-03-08 13:29:09 +02:00
gc.c UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
io.c UBIFS: use max_write_size for write-buffers 2011-03-08 10:12:49 +02:00
ioctl.c headers: smp_lock.h redux 2009-07-12 12:22:34 -07:00
journal.c UBIFS: handle allocation failures in UBIFS write path 2011-03-11 10:52:07 +02:00
Kconfig UBIFS: kill CONFIG_UBIFS_FS_DEBUG_CHKS 2011-03-24 16:16:08 +02:00
key.h UBIFS: mark unused key objects as invalid 2010-08-30 10:19:08 +03:00
log.c UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
lprops.c UBIFS: use GFP_NOFS properly 2011-03-24 16:14:26 +02:00
lpt_commit.c UBIFS: use GFP_NOFS properly 2011-03-24 16:14:26 +02:00
lpt.c UBIFS: check return code of ubifs_lpt_lookup 2010-09-07 12:09:41 +03:00
Makefile
master.c UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
misc.h UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
orphan.c UBIFS: use GFP_NOFS properly 2011-03-24 16:14:26 +02:00
recovery.c UBIFS: use max_write_size during recovery 2011-03-08 10:12:49 +02:00
replay.c UBIFS: do not allocate unneeded scan buffer 2010-10-21 11:15:19 +03:00
sb.c UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
scan.c UBIFS: remove double semicolon 2011-02-06 15:08:02 +02:00
shrinker.c UBIFS: introduce new flags for RO mounts 2010-09-19 21:07:58 +03:00
super.c Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6 2011-03-18 10:50:27 -07:00
tnc_commit.c UBIFS: do not print scary error messages needlessly 2009-09-10 12:06:47 +03:00
tnc_misc.c UBIFS: correct key comparison 2008-09-30 11:12:57 +03:00
tnc.c UBIFS: introduce mounting flag 2011-01-17 23:24:30 +02:00
ubifs-media.h UBIFS: define journal head numbers in ubifs-media.h 2009-09-15 14:45:35 +03:00
ubifs.h UBIFS: handle allocation failures in UBIFS write path 2011-03-11 10:52:07 +02:00
xattr.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00