diff options
author | Boaz Harrosh <Boaz Harrosh bharrosh@panasas.com> | 2010-10-07 13:37:51 -0400 |
---|---|---|
committer | Boaz Harrosh <Boaz Harrosh bharrosh@panasas.com> | 2010-10-08 11:26:54 -0400 |
commit | f17b1f9f1a5882e486aad469b9ac4cb18581707f (patch) | |
tree | fc8e1025ea9871d7ebe1aad63ce0c5fcb2bdf3ca /fs | |
parent | cb655d0f3d57c23db51b981648e452988c0223f9 (diff) | |
download | linux-rpi-f17b1f9f1a5882e486aad469b9ac4cb18581707f.tar.gz linux-rpi-f17b1f9f1a5882e486aad469b9ac4cb18581707f.tar.bz2 linux-rpi-f17b1f9f1a5882e486aad469b9ac4cb18581707f.zip |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exofs/inode.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index eb7368ebd8cd..3eadd97324b1 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -54,6 +54,9 @@ struct page_collect { unsigned nr_pages; unsigned long length; 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, @@ -71,6 +74,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, pcol->nr_pages = 0; pcol->length = 0; pcol->pg_first = -1; + pcol->read_4_write = false; } static void _pcol_reset(struct page_collect *pcol) @@ -347,7 +351,8 @@ static int readpage_strip(void *data, struct page *page) if (PageError(page)) ClearPageError(page); - unlock_page(page); + if (!pcol->read_4_write) + unlock_page(page); EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," " 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 * places but not if we have a single page. */ + pcol.read_4_write = is_sync; ret = readpage_strip(&pcol, page); if (ret) { EXOFS_ERR("_readpage => %d\n", ret); |