Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1352271
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 3.10 09/24] Revert "jffs2: Fix lock acquisition order bug in jffs2_write_begin" |
| Date | 2016-03-08 00:50 +0100 |
| Message-ID | <rad4x-1cJ-85@gated-at.bofh.it> (permalink) |
| References | <rad4t-1cJ-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
3.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Betker <thomas.betker@rohde-schwarz.com>
commit 157078f64b8a9cd7011b6b900b2f2498df850748 upstream.
This reverts commit 5ffd3412ae55
("jffs2: Fix lock acquisition order bug in jffs2_write_begin").
The commit modified jffs2_write_begin() to remove a deadlock with
jffs2_garbage_collect_live(), but this introduced new deadlocks found
by multiple users. page_lock() actually has to be called before
mutex_lock(&c->alloc_sem) or mutex_lock(&f->sem) because
jffs2_write_end() and jffs2_readpage() are called with the page locked,
and they acquire c->alloc_sem and f->sem, resp.
In other words, the lock order in jffs2_write_begin() was correct, and
it is the jffs2_garbage_collect_live() path that has to be changed.
Revert the commit to get rid of the new deadlocks, and to clear the way
for a better fix of the original deadlock.
Reported-by: Deng Chao <deng.chao1@zte.com.cn>
Reported-by: Ming Liu <liu.ming50@gmail.com>
Reported-by: wangzaiwei <wangzaiwei@top-vision.cn>
Signed-off-by: Thomas Betker <thomas.betker@rohde-schwarz.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/jffs2/file.c | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -138,39 +138,33 @@ static int jffs2_write_begin(struct file
struct page *pg;
struct inode *inode = mapping->host;
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- struct jffs2_raw_inode ri;
- uint32_t alloc_len = 0;
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
uint32_t pageofs = index << PAGE_CACHE_SHIFT;
int ret = 0;
- jffs2_dbg(1, "%s()\n", __func__);
-
- if (pageofs > inode->i_size) {
- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
- if (ret)
- return ret;
- }
-
- mutex_lock(&f->sem);
pg = grab_cache_page_write_begin(mapping, index, flags);
- if (!pg) {
- if (alloc_len)
- jffs2_complete_reservation(c);
- mutex_unlock(&f->sem);
+ if (!pg)
return -ENOMEM;
- }
*pagep = pg;
- if (alloc_len) {
+ jffs2_dbg(1, "%s()\n", __func__);
+
+ if (pageofs > inode->i_size) {
/* Make new hole frag from old EOF to new page */
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+ struct jffs2_raw_inode ri;
struct jffs2_full_dnode *fn;
+ uint32_t alloc_len;
jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
(unsigned int)inode->i_size, pageofs);
+ ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
+ if (ret)
+ goto out_page;
+
+ mutex_lock(&f->sem);
memset(&ri, 0, sizeof(ri));
ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -197,6 +191,7 @@ static int jffs2_write_begin(struct file
if (IS_ERR(fn)) {
ret = PTR_ERR(fn);
jffs2_complete_reservation(c);
+ mutex_unlock(&f->sem);
goto out_page;
}
ret = jffs2_add_full_dnode_to_inode(c, f, fn);
@@ -211,10 +206,12 @@ static int jffs2_write_begin(struct file
jffs2_mark_node_obsolete(c, fn->raw);
jffs2_free_full_dnode(fn);
jffs2_complete_reservation(c);
+ mutex_unlock(&f->sem);
goto out_page;
}
jffs2_complete_reservation(c);
inode->i_size = pageofs;
+ mutex_unlock(&f->sem);
}
/*
@@ -223,18 +220,18 @@ static int jffs2_write_begin(struct file
* case of a short-copy.
*/
if (!PageUptodate(pg)) {
+ mutex_lock(&f->sem);
ret = jffs2_do_readpage_nolock(inode, pg);
+ mutex_unlock(&f->sem);
if (ret)
goto out_page;
}
- mutex_unlock(&f->sem);
jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
return ret;
out_page:
unlock_page(pg);
page_cache_release(pg);
- mutex_unlock(&f->sem);
return ret;
}
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 3.10 00/24] 3.10.100-stable review Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 12/24] ALSA: ctl: Fix ioctls for X32 ABI Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 09/24] Revert "jffs2: Fix lock acquisition order bug in jffs2_write_begin" Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 22/24] USB: serial: option: add support for Quectel UC20 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 21/24] USB: serial: option: add support for Telit LE922 PID 0x1045 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 15/24] ALSA: seq: oss: Dont drain at closing a client Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 00:50 +0100 [PATCH 3.10 23/24] ubi: Fix out of bounds write in volume update code Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:00 +0100 [PATCH 3.10 07/24] libata: Align ata_devices id on a cacheline Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 04/24] x86/entry/compat: Add missing CLAC to entry_INT80_32 Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 08/24] PM / sleep / x86: Fix crash on graph trace through x86 suspend Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 03/24] CIFS: Fix SMB2+ interim response processing for read requests Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 02/24] EDAC, mc_sysfs: Fix freeing bus name Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 13/24] ALSA: rawmidi: Fix ioctls X32 ABI Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 [PATCH 3.10 06/24] libata: fix HDIO_GET_32BIT ioctl Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2016-03-08 01:10 +0100 Re: [PATCH 3.10 00/24] 3.10.100-stable review Guenter Roeck <linux@roeck-us.net> - 2016-03-08 12:50 +0100 Re: [PATCH 3.10 00/24] 3.10.100-stable review Shuah Khan <shuahkh@osg.samsung.com> - 2016-03-08 17:30 +0100
csiph-web