| From 2cbba75a56ea78e6876b4e2547a882f10b3fe72b Mon Sep 17 00:00:00 2001 |
| From: Alexey Khoroshilov <khoroshilov@ispras.ru> |
| Date: Mon, 5 Nov 2012 22:40:14 +0400 |
| Subject: jffs2: hold erase_completion_lock on exit |
| |
| From: Alexey Khoroshilov <khoroshilov@ispras.ru> |
| |
| commit 2cbba75a56ea78e6876b4e2547a882f10b3fe72b upstream. |
| |
| Users of jffs2_do_reserve_space() expect they still held |
| erase_completion_lock after call to it. But there is a path |
| where jffs2_do_reserve_space() leaves erase_completion_lock unlocked. |
| The patch fixes it. |
| |
| Found by Linux Driver Verification project (linuxtesting.org). |
| |
| Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> |
| Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/jffs2/nodemgmt.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/fs/jffs2/nodemgmt.c |
| +++ b/fs/jffs2/nodemgmt.c |
| @@ -355,14 +355,16 @@ static int jffs2_do_reserve_space(struct |
| spin_unlock(&c->erase_completion_lock); |
| |
| ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); |
| - if (ret) |
| - return ret; |
| + |
| /* Just lock it again and continue. Nothing much can change because |
| we hold c->alloc_sem anyway. In fact, it's not entirely clear why |
| we hold c->erase_completion_lock in the majority of this function... |
| but that's a question for another (more caffeine-rich) day. */ |
| spin_lock(&c->erase_completion_lock); |
| |
| + if (ret) |
| + return ret; |
| + |
| waste = jeb->free_size; |
| jffs2_link_node_ref(c, jeb, |
| (jeb->offset + c->sector_size - waste) | REF_OBSOLETE, |