diff options
author | Idan Kedar <idank@tonian.com> | 2012-11-30 16:03:31 +0200 |
---|---|---|
committer | Boaz Harrosh <bharrosh@panasas.com> | 2012-12-11 18:56:18 +0200 |
commit | af402ab2b0369c2b1acf4cde72c5ed5050c74e5b (patch) | |
tree | 0fbd522fc8f42ff3ac3cc6bdece51129fe871392 /fs | |
parent | b6755ffb0c03c2e763cc56f72cc2ceaba8ea2805 (diff) | |
download | kernel-common-af402ab2b0369c2b1acf4cde72c5ed5050c74e5b.tar.gz kernel-common-af402ab2b0369c2b1acf4cde72c5ed5050c74e5b.tar.bz2 kernel-common-af402ab2b0369c2b1acf4cde72c5ed5050c74e5b.zip |
exofs: clean up the correct page collection on write error
if ore_write() fails, we would unlock the pages of pcol, which is now
empty, rather than pcol_copy which owns the pages when ore_write() is
called. this means that no pages will actually be unlocked
(pcol.nr_pages == 0) and the writing process (more accurately, the
syncing process) will hang waiting for a writeback notification that
never comes.
moreover, if ore_write() fails, pcol_free() is called for pcol, whereas
pcol_copy is the object owning the ore_io_state, thus leaking the
ore_io_state.
[Boaz]
I have simplified Idan's original patch a bit, everything else still
holds
Signed-off-by: Idan Kedar <idank@tonian.com>
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exofs/inode.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index b56181047751..1634b946565f 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -676,8 +676,10 @@ static int write_exec(struct page_collect *pcol) return 0; err: - _unlock_pcol_pages(pcol, ret, WRITE); - pcol_free(pcol); + if (!pcol_copy) /* Failed before ownership transfer */ + pcol_copy = pcol; + _unlock_pcol_pages(pcol_copy, ret, WRITE); + pcol_free(pcol_copy); kfree(pcol_copy); return ret; |