Commit f17b1f9f authored by Boaz Harrosh's avatar Boaz Harrosh

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>
parent cb655d0f
...@@ -54,6 +54,9 @@ struct page_collect { ...@@ -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, ...@@ -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,6 +351,7 @@ static int readpage_strip(void *data, struct page *page) ...@@ -347,6 +351,7 @@ static int readpage_strip(void *data, struct page *page)
if (PageError(page)) if (PageError(page))
ClearPageError(page); ClearPageError(page);
if (!pcol->read_4_write)
unlock_page(page); 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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment