From mboxrd@z Thu Jan 1 00:00:00 1970 From: Idan Kedar Subject: [PATCH] exofs: clean up the correct page collection on write error Date: Mon, 26 Nov 2012 16:49:06 +0200 Message-ID: <1353941346-20598-1-git-send-email-idank@tonian.com> Cc: idank@tonian.com, linux-fsdevel@vger.kernel.org, osd-dev@open-osd.org, solo@tonian.com, bhalevy@tonian.com, ilya@tonian.com To: bharrosh@panasas.com Return-path: Received: from mail-la0-f46.google.com ([209.85.215.46]:56949 "EHLO mail-la0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754526Ab2KZOtQ (ORCPT ); Mon, 26 Nov 2012 09:49:16 -0500 Received: by mail-la0-f46.google.com with SMTP id p5so5846441lag.19 for ; Mon, 26 Nov 2012 06:49:15 -0800 (PST) Sender: linux-fsdevel-owner@vger.kernel.org List-ID: 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. Signed-off-by: Idan Kedar --- fs/exofs/inode.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index b561810..5106213 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -628,7 +628,7 @@ static int write_exec(struct page_collect *pcol) { struct exofs_i_info *oi = exofs_i(pcol->inode); struct ore_io_state *ios; - struct page_collect *pcol_copy = NULL; + struct page_collect *pcol_copy = NULL, *active_pcol = pcol; int ret; if (!pcol->pages) @@ -658,6 +658,7 @@ static int write_exec(struct page_collect *pcol) /* pages ownership was passed to pcol_copy */ _pcol_reset(pcol); + active_pcol = pcol_copy; ret = _maybe_not_all_in_one_io(ios, pcol_copy, pcol); if (unlikely(ret)) @@ -676,8 +677,8 @@ static int write_exec(struct page_collect *pcol) return 0; err: - _unlock_pcol_pages(pcol, ret, WRITE); - pcol_free(pcol); + _unlock_pcol_pages(active_pcol, ret, WRITE); + pcol_free(active_pcol); kfree(pcol_copy); return ret; -- 1.7.6.5