exofs: Fix double page_unlock BUG in write_begin/end
This BUG is there since the first submit of the code, but only triggered in last Kernel. It's timing related do to the asynchronous object-creation behaviour of exofs. (Which should be investigated farther) The bug is obvious hence the fixed. Signed-off-by: Boaz Harrosh <Boaz Harrosh bharrosh@panasas.com>
This commit is contained in:
parent
cb655d0f3d
commit
f17b1f9f1a
1 changed files with 7 additions and 1 deletions
|
@ -54,6 +54,9 @@ struct page_collect {
|
||||||
unsigned nr_pages;
|
unsigned nr_pages;
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
loff_t pg_first; /* keep 64bit also in 32-arches */
|
loff_t pg_first; /* keep 64bit also in 32-arches */
|
||||||
|
bool read_4_write; /* This means two things: that the read is sync
|
||||||
|
* And the pages should not be unlocked.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
|
static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
|
||||||
|
@ -71,6 +74,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
|
||||||
pcol->nr_pages = 0;
|
pcol->nr_pages = 0;
|
||||||
pcol->length = 0;
|
pcol->length = 0;
|
||||||
pcol->pg_first = -1;
|
pcol->pg_first = -1;
|
||||||
|
pcol->read_4_write = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _pcol_reset(struct page_collect *pcol)
|
static void _pcol_reset(struct page_collect *pcol)
|
||||||
|
@ -347,7 +351,8 @@ static int readpage_strip(void *data, struct page *page)
|
||||||
if (PageError(page))
|
if (PageError(page))
|
||||||
ClearPageError(page);
|
ClearPageError(page);
|
||||||
|
|
||||||
unlock_page(page);
|
if (!pcol->read_4_write)
|
||||||
|
unlock_page(page);
|
||||||
EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
|
EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
|
||||||
" splitting\n", inode->i_ino, page->index);
|
" splitting\n", inode->i_ino, page->index);
|
||||||
|
|
||||||
|
@ -428,6 +433,7 @@ static int _readpage(struct page *page, bool is_sync)
|
||||||
/* readpage_strip might call read_exec(,is_sync==false) at several
|
/* readpage_strip might call read_exec(,is_sync==false) at several
|
||||||
* places but not if we have a single page.
|
* places but not if we have a single page.
|
||||||
*/
|
*/
|
||||||
|
pcol.read_4_write = is_sync;
|
||||||
ret = readpage_strip(&pcol, page);
|
ret = readpage_strip(&pcol, page);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
EXOFS_ERR("_readpage => %d\n", ret);
|
EXOFS_ERR("_readpage => %d\n", ret);
|
||||||
|
|
Loading…
Add table
Reference in a new issue