writeback: fix possible bdi writeback refcounting problem

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Wednesday, September 16, 2009 - 7:59 am

Gitweb:     http://git.kernel.org/linus/1ef7d9aa32a8ee054c4d4fdcd2ea537c04d61b2f
Commit:     1ef7d9aa32a8ee054c4d4fdcd2ea537c04d61b2f
Parent:     77b9d059cb3ddb8b1246d5878e81d52926550b23
Author:     Nick Piggin <npiggin@suse.de>
AuthorDate: Tue Sep 15 21:37:55 2009 +0200
Committer:  Jens Axboe <jens.axboe@oracle.com>
CommitDate: Wed Sep 16 15:18:53 2009 +0200

    writeback: fix possible bdi writeback refcounting problem
    
    wb_clear_pending AFAIKS should not be called after the item has been
    put on the list, except by the worker threads. It could lead to the
    situation where the refcount is decremented below 0 and cause lots of
    problems.
    
    Presumably the !wb_has_dirty_io case is not a common one, so it can
    be discovered when the thread wakes up to check?
    
    Also add a comment in bdi_work_clear.
    
    Signed-off-by: Nick Piggin <npiggin@suse.de>
    Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
---
 fs/fs-writeback.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 7eba732..8e1e5e1 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -97,6 +97,11 @@ static void bdi_work_clear(struct bdi_work *work)
 {
 	clear_bit(WS_USED_B, &work->state);
 	smp_mb__after_clear_bit();
+	/*
+	 * work can have disappeared at this point. bit waitq functions
+	 * should be able to tolerate this, provided bdi_sched_wait does
+	 * not dereference it's pointer argument.
+	*/
 	wake_up_bit(&work->state, WS_USED_B);
 }
 
@@ -169,13 +174,7 @@ static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work)
 	else {
 		struct bdi_writeback *wb = &bdi->wb;
 
-		/*
-		 * End work now if this wb has no dirty IO pending. Otherwise
-		 * wakeup the handling thread
-		 */
-		if (!wb_has_dirty_io(wb))
-			wb_clear_pending(wb, work);
-		else if (wb->task)
+		if (wb->task)
 			wake_up_process(wb->task);
 	}
 }
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
writeback: fix possible bdi writeback refcounting problem, Linux Kernel Mailing ..., (Wed Sep 16, 7:59 am)