diff options
author | Thomas Betker <thomas.betker@freenet.de> | 2012-10-17 22:59:30 +0200 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2012-11-09 17:02:50 +0200 |
commit | 5ffd3412ae5536a4c57469cb8ea31887121dcb2e (patch) | |
tree | 33c9d89eabf70c49e683a36be800be3b4582a358 /fs/jffs2/compr.h | |
parent | 0131950ebd146b5e31508233352d6f4625af25b1 (diff) |
jffs2: Fix lock acquisition order bug in jffs2_write_begin
jffs2_write_begin() first acquires the page lock, then f->sem. This
causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first
acquires f->sem, then the page lock:
jffs2_garbage_collect_live
mutex_lock(&f->sem) (A)
jffs2_garbage_collect_dnode
jffs2_gc_fetch_page
read_cache_page_async
do_read_cache_page
lock_page(page) (B)
jffs2_write_begin
grab_cache_page_write_begin
find_lock_page
lock_page(page) (B)
mutex_lock(&f->sem) (A)
We fix this by restructuring jffs2_write_begin() to take f->sem before
the page lock. However, we make sure that f->sem is not held when
calling jffs2_reserve_space(), as this is not permitted by the locking
rules.
The deadlock above was observed multiple times on an SoC with a dual
ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred
when using scp to copy files from a host system to the ARM target
system. The fix was heavily tested on the same target system.
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Betker <thomas.betker@rohde-schwarz.com>
Acked-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'fs/jffs2/compr.h')
0 files changed, 0 insertions, 0 deletions