All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] writeback fixes - slow unmount and others
@ 2010-06-08 16:14 Christoph Hellwig
  2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:14 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

I've started looking into the slow unmount issue again, and digged a
bit deeper into the writeback code to look at the root cause.

All inode writeback is performed by writeback_inodes_wb, which
has the following callgraph (annotated by a few important facts):

writeback_inodes_wb
  <- writeback_inodes_wbc
       <- bdi_flush_io			(WB_SYNC_NONE, no sb)
       <- balance_dirty_pages		(WB_SYNC_NONE, no sb)
  <- wb_writeback
       <- wb_check_old_data_flush	(WB_SYNC_NONE, no sb)
       <- wb_do_writeback
           <- bdi_writeback_task	\
	   <- bdi_start_fn		| take bdi_work item from list
	   <- bdi_forker_task		/

So we either get a bdi_work item submitted by bdi_queue_work, or
we do WB_SYNC_NONE I/O ourselves without specifying a superblock.

For bdi_queue_work the same annotated callchain looks like:

bdi_queue_work
  <- bdi_sync_writeback			(WB_SYNC_ALL, mandatory sb, onstack)
       <- sync_inodes_sb		(..)
  <- bdi_alloc_queue_work
       <- bdi_start_writeback		(WB_SYNC_NONE, optional sb)
            <- balance_dirty_pages	(..          , no sb)
	    <- laptop_mode_timer_fn	(..          , no sb)
	    <- writeback_inodes_sb	(..          , mandatory sb)
       <- bdi_writeback_all		(WB_SYNC_NONE, optional sb)
            <- wakeup_flusher_threads	(..          , no sb)

So in general we can say that the case of WB_SYNC_NONE without a
superblock is the normal case.  And now if we look at the callers of
the functions that take a superblock we see that this is basically
sync_filesystem, which always has s_umount held.  So instead of
trying to add hacks for when it is held, we can assume that we
always have it held if a superblock is specified, and fix up the
two callers inside filesystems that crept in recently to also
hold it.  With that we can replace various ad-hoc checks with
a very clear scheme that only checks the oncase caller, and if
we have a superblock or not after switching all writeback
that has a superblock to submit the I/O on stack.

After my series the annotated callgraph for bdi_queue_work is the
following:


bdi_queue_work
  <- bdi_queue_work_onstack		 (WB_SYNC_ALL/NONE, mandatory sb, onstack)
       <- sync_inodes_sb		 (WB_SYNC_ALL, ..)
       <- writeback_inodes_sb		 (WB_SYNC_NONE, ..)
  <- bdi_alloc_queue_work
       <- bdi_start_writeback		 (WB_SYNC_NONE, no sb)
       <- bdi_start_background_writeback (WB_SYNC_NONE, no sb)
       <- wakeup_flusher_threads	 (WB_SYNC_NONE, no sb)

So it's a lot simpler and just as important flatter.  But when we look
how we use the onstack / sb specified callers I'm not sure this is the
optimal case yet.  We're beeing called from synchronous callers (
we need to wait for completion for the first WB_SYNC_NONE pass later on,
too), so there really is no need to hand this work off to the flusher
threads.  In the end it might be much simpler to just issue this I/O
from the caller context and remove the code for the on-stack
submissions, but that's left for a later patch.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 1/6] writeback: fix writeback completion notifications
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
@ 2010-06-08 16:14 ` Christoph Hellwig
  2010-06-08 19:50   ` Jens Axboe
  2010-06-15 17:25   ` Jan Kara
  2010-06-08 16:14 ` [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb Christoph Hellwig
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:14 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

The code dealing with bdi_work->state and completion of a bdi_work is a
major mess currently.  This patch makes sure we directly use one set of
flags to deal with it, and use it consistently, which means:

 - always notify about completion from the rcu callback.  We only ever
   wait for it from on-stack callers, so this simplification does not
   even cause a theoretical slowdown currently.  It also makes sure we
   don't miss out on the notification if we ever add other callers to
   wait for it.
 - make earlier completion notification depending on the on-stack
   allocation, not the sync mode.  If we introduce new callers that
   want to do WB_SYNC_NONE writeback from on-stack callers this will
   be nessecary.

Also rename bdi_wait_on_work_clear to bdi_wait_on_work_done and inline
a few small functions into their only caller to make the code
understandable.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 16:17:45.781254323 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 16:20:11.916005756 +0200
@@ -63,24 +63,16 @@ struct bdi_work {
 };
 
 enum {
-	WS_USED_B = 0,
-	WS_ONSTACK_B,
+	WS_INPROGRESS = 0,
+	WS_ONSTACK,
 };
 
-#define WS_USED (1 << WS_USED_B)
-#define WS_ONSTACK (1 << WS_ONSTACK_B)
-
-static inline bool bdi_work_on_stack(struct bdi_work *work)
-{
-	return test_bit(WS_ONSTACK_B, &work->state);
-}
-
 static inline void bdi_work_init(struct bdi_work *work,
 				 struct wb_writeback_args *args)
 {
 	INIT_RCU_HEAD(&work->rcu_head);
 	work->args = *args;
-	work->state = WS_USED;
+	__set_bit(WS_INPROGRESS, &work->state);
 }
 
 /**
@@ -95,43 +87,16 @@ int writeback_in_progress(struct backing
 	return !list_empty(&bdi->work_list);
 }
 
-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);
-}
-
 static void bdi_work_free(struct rcu_head *head)
 {
 	struct bdi_work *work = container_of(head, struct bdi_work, rcu_head);
 
-	if (!bdi_work_on_stack(work))
-		kfree(work);
-	else
-		bdi_work_clear(work);
-}
-
-static void wb_work_complete(struct bdi_work *work)
-{
-	const enum writeback_sync_modes sync_mode = work->args.sync_mode;
-	int onstack = bdi_work_on_stack(work);
+	clear_bit(WS_INPROGRESS, &work->state);
+	smp_mb__after_clear_bit();
+	wake_up_bit(&work->state, WS_INPROGRESS);
 
-	/*
-	 * For allocated work, we can clear the done/seen bit right here.
-	 * For on-stack work, we need to postpone both the clear and free
-	 * to after the RCU grace period, since the stack could be invalidated
-	 * as soon as bdi_work_clear() has done the wakeup.
-	 */
-	if (!onstack)
-		bdi_work_clear(work);
-	if (sync_mode == WB_SYNC_NONE || onstack)
-		call_rcu(&work->rcu_head, bdi_work_free);
+	if (!test_bit(WS_ONSTACK, &work->state))
+		kfree(work);
 }
 
 static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work)
@@ -147,7 +112,7 @@ static void wb_clear_pending(struct bdi_
 		list_del_rcu(&work->list);
 		spin_unlock(&bdi->wb_lock);
 
-		wb_work_complete(work);
+		call_rcu(&work->rcu_head, bdi_work_free);
 	}
 }
 
@@ -185,9 +150,9 @@ static void bdi_queue_work(struct backin
  * Used for on-stack allocated work items. The caller needs to wait until
  * the wb threads have acked the work before it's safe to continue.
  */
-static void bdi_wait_on_work_clear(struct bdi_work *work)
+static void bdi_wait_on_work_done(struct bdi_work *work)
 {
-	wait_on_bit(&work->state, WS_USED_B, bdi_sched_wait,
+	wait_on_bit(&work->state, WS_INPROGRESS, bdi_sched_wait,
 		    TASK_UNINTERRUPTIBLE);
 }
 
@@ -234,10 +199,10 @@ static void bdi_sync_writeback(struct ba
 	struct bdi_work work;
 
 	bdi_work_init(&work, &args);
-	work.state |= WS_ONSTACK;
+	__set_bit(WS_ONSTACK, &work.state);
 
 	bdi_queue_work(bdi, &work);
-	bdi_wait_on_work_clear(&work);
+	bdi_wait_on_work_done(&work);
 }
 
 /**
@@ -911,7 +876,7 @@ long wb_do_writeback(struct bdi_writebac
 		 * If this isn't a data integrity operation, just notify
 		 * that we have seen this work and we are now starting it.
 		 */
-		if (args.sync_mode == WB_SYNC_NONE)
+		if (!test_bit(WS_ONSTACK, &work->state))
 			wb_clear_pending(wb, work);
 
 		wrote += wb_writeback(wb, &args);
@@ -920,7 +885,7 @@ long wb_do_writeback(struct bdi_writebac
 		 * This is a data integrity writeback, so only do the
 		 * notification when we have completed the work.
 		 */
-		if (args.sync_mode == WB_SYNC_ALL)
+		if (test_bit(WS_ONSTACK, &work->state))
 			wb_clear_pending(wb, work);
 	}
 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
  2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
@ 2010-06-08 16:14 ` Christoph Hellwig
  2010-06-08 19:51   ` Jens Axboe
  2010-06-08 16:14 ` [PATCH 3/6] writeback: enforce s_umount locking " Christoph Hellwig
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:14 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

If we want to rely on s_umount in the caller we need to wait for completion
of the I/O submission before returning to the caller.  Refactor
bdi_sync_writeback into a bdi_queue_work_onstack helper and use it for this
case.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 16:22:24.293254045 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 16:25:35.794005969 +0200
@@ -178,30 +178,22 @@ static void bdi_alloc_queue_work(struct
 }
 
 /**
- * bdi_sync_writeback - start and wait for writeback
- * @bdi: the backing device to write from
+ * bdi_queue_work_onstack - start and wait for writeback
  * @sb: write inodes from this super_block
  *
  * Description:
- *   This does WB_SYNC_ALL data integrity writeback and waits for the
- *   IO to complete. Callers must hold the sb s_umount semaphore for
+ *   This function initiates writeback and waits for the operation to
+ *   complete. Callers must hold the sb s_umount semaphore for
  *   reading, to avoid having the super disappear before we are done.
  */
-static void bdi_sync_writeback(struct backing_dev_info *bdi,
-			       struct super_block *sb)
+static void bdi_queue_work_onstack(struct wb_writeback_args *args)
 {
-	struct wb_writeback_args args = {
-		.sb		= sb,
-		.sync_mode	= WB_SYNC_ALL,
-		.nr_pages	= LONG_MAX,
-		.range_cyclic	= 0,
-	};
 	struct bdi_work work;
 
-	bdi_work_init(&work, &args);
+	bdi_work_init(&work, args);
 	__set_bit(WS_ONSTACK, &work.state);
 
-	bdi_queue_work(bdi, &work);
+	bdi_queue_work(args->sb->s_bdi, &work);
 	bdi_wait_on_work_done(&work);
 }
 
@@ -944,7 +936,7 @@ int bdi_writeback_task(struct bdi_writeb
 
 /*
  * Schedule writeback for all backing devices. This does WB_SYNC_NONE
- * writeback, for integrity writeback see bdi_sync_writeback().
+ * writeback, for integrity writeback see bdi_queue_work_onstack().
  */
 static void bdi_writeback_all(struct super_block *sb, long nr_pages)
 {
@@ -1183,12 +1175,15 @@ void writeback_inodes_sb(struct super_bl
 {
 	unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
 	unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
-	long nr_to_write;
+	struct wb_writeback_args args = {
+		.sb		= sb,
+		.sync_mode	= WB_SYNC_NONE,
+	};
 
-	nr_to_write = nr_dirty + nr_unstable +
+	args.nr_pages = nr_dirty + nr_unstable +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
 
-	bdi_start_writeback(sb->s_bdi, sb, nr_to_write);
+	bdi_queue_work_onstack(&args);
 }
 EXPORT_SYMBOL(writeback_inodes_sb);
 
@@ -1218,7 +1213,14 @@ EXPORT_SYMBOL(writeback_inodes_sb_if_idl
  */
 void sync_inodes_sb(struct super_block *sb)
 {
-	bdi_sync_writeback(sb->s_bdi, sb);
+	struct wb_writeback_args args = {
+		.sb		= sb,
+		.sync_mode	= WB_SYNC_ALL,
+		.nr_pages	= LONG_MAX,
+		.range_cyclic	= 0,
+	};
+
+	bdi_queue_work_onstack(&args);
 	wait_sb_inodes(sb);
 }
 EXPORT_SYMBOL(sync_inodes_sb);

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 3/6] writeback: enforce s_umount locking in writeback_inodes_sb
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
  2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
  2010-06-08 16:14 ` [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb Christoph Hellwig
@ 2010-06-08 16:14 ` Christoph Hellwig
  2010-06-15 17:54   ` Jan Kara
  2010-06-08 16:14 ` [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb Christoph Hellwig
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:14 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

Make sure that not only sync_filesystem but all callers of writeback_inodes_sb
have the superblock protected against remount.  As-is this disables all
functionality for these callers, but the next patch relies on this locking to
fix writeback_inodes_sb for sync_filesystem.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 16:25:35.000000000 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 16:27:47.846255651 +0200
@@ -1180,6 +1180,8 @@ void writeback_inodes_sb(struct super_bl
 		.sync_mode	= WB_SYNC_NONE,
 	};
 
+	WARN_ON(!rwsem_is_locked(&sb->s_umount));
+
 	args.nr_pages = nr_dirty + nr_unstable +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
 
@@ -1197,7 +1199,9 @@ EXPORT_SYMBOL(writeback_inodes_sb);
 int writeback_inodes_sb_if_idle(struct super_block *sb)
 {
 	if (!writeback_in_progress(sb->s_bdi)) {
+		down_read(&sb->s_umount);
 		writeback_inodes_sb(sb);
+		up_read(&sb->s_umount);
 		return 1;
 	} else
 		return 0;
@@ -1220,6 +1224,8 @@ void sync_inodes_sb(struct super_block *
 		.range_cyclic	= 0,
 	};
 
+	WARN_ON(!rwsem_is_locked(&sb->s_umount));
+
 	bdi_queue_work_onstack(&args);
 	wait_sb_inodes(sb);
 }
Index: linux-2.6/fs/ubifs/budget.c
===================================================================
--- linux-2.6.orig/fs/ubifs/budget.c	2010-06-08 16:22:16.000000000 +0200
+++ linux-2.6/fs/ubifs/budget.c	2010-06-08 16:26:50.464004778 +0200
@@ -62,7 +62,9 @@
  */
 static void shrink_liability(struct ubifs_info *c, int nr_to_write)
 {
+	down_read(&c->vfs_sb->s_umount);
 	writeback_inodes_sb(c->vfs_sb);
+	up_read(&c->vfs_sb->s_umount);
 }
 
 /**

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
                   ` (2 preceding siblings ...)
  2010-06-08 16:14 ` [PATCH 3/6] writeback: enforce s_umount locking " Christoph Hellwig
@ 2010-06-08 16:14 ` Christoph Hellwig
  2010-06-08 19:51   ` Jens Axboe
  2010-06-08 16:15 ` [PATCH 5/6] writeback: simplify wakeup_flusher_threads Christoph Hellwig
  2010-06-08 16:15 ` [PATCH 6/6] writeback: simplify and split bdi_start_writeback Christoph Hellwig
  5 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:14 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

When we call writeback_inodes_wb from writeback_inodes_sb we always have
s_umount held, which currently makes the whole operation a no-op.

But if we are called to write out inodes for a specific superblock we always
have s_umount held, so replace the incorrect logic checking for WB_SYNC_ALL
which only worked by coincidence with the proper check for an explicit
superblock argument.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 16:36:42.665003940 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 17:10:12.958255860 +0200
@@ -518,39 +518,19 @@ select_queue:
 	return ret;
 }
 
-static void unpin_sb_for_writeback(struct super_block *sb)
-{
-	up_read(&sb->s_umount);
-	put_super(sb);
-}
-
-enum sb_pin_state {
-	SB_PINNED,
-	SB_NOT_PINNED,
-	SB_PIN_FAILED
-};
-
 /*
- * For WB_SYNC_NONE writeback, the caller does not have the sb pinned
+ * For background writeback the caller does not have the sb pinned
  * before calling writeback. So make sure that we do pin it, so it doesn't
  * go away while we are writing inodes from it.
  */
-static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
-					      struct super_block *sb)
+static bool pin_sb_for_writeback(struct super_block *sb)
 {
-	/*
-	 * Caller must already hold the ref for this
-	 */
-	if (wbc->sync_mode == WB_SYNC_ALL) {
-		WARN_ON(!rwsem_is_locked(&sb->s_umount));
-		return SB_NOT_PINNED;
-	}
 	spin_lock(&sb_lock);
 	sb->s_count++;
 	if (down_read_trylock(&sb->s_umount)) {
 		if (sb->s_root) {
 			spin_unlock(&sb_lock);
-			return SB_PINNED;
+			return true;
 		}
 		/*
 		 * umounted, drop rwsem again and fall through to failure
@@ -559,7 +539,7 @@ static enum sb_pin_state pin_sb_for_writ
 	}
 	sb->s_count--;
 	spin_unlock(&sb_lock);
-	return SB_PIN_FAILED;
+	return false;
 }
 
 /*
@@ -638,24 +618,29 @@ static void writeback_inodes_wb(struct b
 		struct inode *inode = list_entry(wb->b_io.prev,
 						 struct inode, i_list);
 		struct super_block *sb = inode->i_sb;
-		enum sb_pin_state state;
 
-		if (wbc->sb && sb != wbc->sb) {
-			/* super block given and doesn't
-			   match, skip this inode */
-			redirty_tail(inode);
-			continue;
-		}
-		state = pin_sb_for_writeback(wbc, sb);
-
-		if (state == SB_PIN_FAILED) {
-			requeue_io(inode);
-			continue;
+		if (wbc->sb) {
+			/*
+			 * We are requested to write out inodes for a specific
+			 * superblock.  This means we already have s_umount
+			 * taken by the caller which also waits for us to
+			 * complete the writeout.
+			 */
+			if (sb != wbc->sb) {
+				redirty_tail(inode);
+				continue;
+			}
+
+			WARN_ON(!rwsem_is_locked(&sb->s_umount));
+
+			ret = writeback_sb_inodes(sb, wb, wbc);
+		} else {
+			if (!pin_sb_for_writeback(sb))
+				continue;
+			ret = writeback_sb_inodes(sb, wb, wbc);
+			drop_super(sb);
 		}
-		ret = writeback_sb_inodes(sb, wb, wbc);
 
-		if (state == SB_PINNED)
-			unpin_sb_for_writeback(sb);
 		if (ret)
 			break;
 	}

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 5/6] writeback: simplify wakeup_flusher_threads
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
                   ` (3 preceding siblings ...)
  2010-06-08 16:14 ` [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb Christoph Hellwig
@ 2010-06-08 16:15 ` Christoph Hellwig
  2010-06-08 19:51   ` Jens Axboe
  2010-06-08 16:15 ` [PATCH 6/6] writeback: simplify and split bdi_start_writeback Christoph Hellwig
  5 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:15 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

bdi_writeback_all only has one caller, so fold it to simplify the code and
flatten the call stack.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 17:15:39.612253834 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 17:15:49.849254813 +0200
@@ -920,42 +920,32 @@ int bdi_writeback_task(struct bdi_writeb
 }
 
 /*
- * Schedule writeback for all backing devices. This does WB_SYNC_NONE
- * writeback, for integrity writeback see bdi_queue_work_onstack().
+ * Start writeback of `nr_pages' pages.  If `nr_pages' is zero, write back
+ * the whole world.
  */
-static void bdi_writeback_all(struct super_block *sb, long nr_pages)
+void wakeup_flusher_threads(long nr_pages)
 {
+	struct backing_dev_info *bdi;
 	struct wb_writeback_args args = {
-		.sb		= sb,
-		.nr_pages	= nr_pages,
 		.sync_mode	= WB_SYNC_NONE,
 	};
-	struct backing_dev_info *bdi;
 
-	rcu_read_lock();
+	if (nr_pages) {
+		args.nr_pages = nr_pages;
+	} else {
+		args.nr_pages = global_page_state(NR_FILE_DIRTY) +
+				global_page_state(NR_UNSTABLE_NFS);
+	}
 
+	rcu_read_lock();
 	list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
 		if (!bdi_has_dirty_io(bdi))
 			continue;
-
 		bdi_alloc_queue_work(bdi, &args);
 	}
-
 	rcu_read_unlock();
 }
 
-/*
- * Start writeback of `nr_pages' pages.  If `nr_pages' is zero, write back
- * the whole world.
- */
-void wakeup_flusher_threads(long nr_pages)
-{
-	if (nr_pages == 0)
-		nr_pages = global_page_state(NR_FILE_DIRTY) +
-				global_page_state(NR_UNSTABLE_NFS);
-	bdi_writeback_all(NULL, nr_pages);
-}
-
 static noinline void block_dump___mark_inode_dirty(struct inode *inode)
 {
 	if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH 6/6] writeback: simplify and split bdi_start_writeback
  2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
                   ` (4 preceding siblings ...)
  2010-06-08 16:15 ` [PATCH 5/6] writeback: simplify wakeup_flusher_threads Christoph Hellwig
@ 2010-06-08 16:15 ` Christoph Hellwig
  2010-06-08 19:52   ` Jens Axboe
  5 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-08 16:15 UTC (permalink / raw)
  To: axboe; +Cc: linux-fsdevel

bdi_start_writeback now never gets a superblock passed, so we can just remove
that case.  And to further untangle the code and flatten the call stack
split it into two trivial helpers for it's two callers.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 17:24:33.511003451 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-08 17:24:40.356003590 +0200
@@ -200,7 +200,6 @@ static void bdi_queue_work_onstack(struc
 /**
  * bdi_start_writeback - start writeback
  * @bdi: the backing device to write from
- * @sb: write inodes from this super_block
  * @nr_pages: the number of pages to write
  *
  * Description:
@@ -209,25 +208,34 @@ static void bdi_queue_work_onstack(struc
  *   completion. Caller need not hold sb s_umount semaphore.
  *
  */
-void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
-			 long nr_pages)
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages)
 {
 	struct wb_writeback_args args = {
-		.sb		= sb,
 		.sync_mode	= WB_SYNC_NONE,
 		.nr_pages	= nr_pages,
 		.range_cyclic	= 1,
 	};
 
-	/*
-	 * We treat @nr_pages=0 as the special case to do background writeback,
-	 * ie. to sync pages until the background dirty threshold is reached.
-	 */
-	if (!nr_pages) {
-		args.nr_pages = LONG_MAX;
-		args.for_background = 1;
-	}
+	bdi_alloc_queue_work(bdi, &args);
+}
 
+/**
+ * bdi_start_background_writeback - start background writeback
+ * @bdi: the backing device to write from
+ *
+ * Description:
+ *   This does WB_SYNC_NONE background writeback. The IO is only
+ *   started when this function returns, we make no guarentees on
+ *   completion. Caller need not hold sb s_umount semaphore.
+ */
+void bdi_start_background_writeback(struct backing_dev_info *bdi)
+{
+	struct wb_writeback_args args = {
+		.sync_mode	= WB_SYNC_NONE,
+		.nr_pages	= LONG_MAX,
+		.for_background = 1,
+		.range_cyclic	= 1,
+	};
 	bdi_alloc_queue_work(bdi, &args);
 }
 
Index: linux-2.6/include/linux/backing-dev.h
===================================================================
--- linux-2.6.orig/include/linux/backing-dev.h	2010-06-08 17:24:24.081004289 +0200
+++ linux-2.6/include/linux/backing-dev.h	2010-06-08 17:24:40.357004010 +0200
@@ -105,8 +105,8 @@ int bdi_register(struct backing_dev_info
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
 void bdi_unregister(struct backing_dev_info *bdi);
 int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
-void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
-				long nr_pages);
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages);
+void bdi_start_background_writeback(struct backing_dev_info *bdi);
 int bdi_writeback_task(struct bdi_writeback *wb);
 int bdi_has_dirty_io(struct backing_dev_info *bdi);
 void bdi_arm_supers_timer(void);
Index: linux-2.6/mm/page-writeback.c
===================================================================
--- linux-2.6.orig/mm/page-writeback.c	2010-06-08 17:24:24.091007362 +0200
+++ linux-2.6/mm/page-writeback.c	2010-06-08 17:24:40.367026988 +0200
@@ -597,7 +597,7 @@ static void balance_dirty_pages(struct a
 	    (!laptop_mode && ((global_page_state(NR_FILE_DIRTY)
 			       + global_page_state(NR_UNSTABLE_NFS))
 					  > background_thresh)))
-		bdi_start_writeback(bdi, NULL, 0);
+		bdi_start_background_writeback(bdi);
 }
 
 void set_page_dirty_balance(struct page *page, int page_mkwrite)
@@ -705,9 +705,8 @@ void laptop_mode_timer_fn(unsigned long
 	 * We want to write everything out, not just down to the dirty
 	 * threshold
 	 */
-
 	if (bdi_has_dirty_io(&q->backing_dev_info))
-		bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages);
+		bdi_start_writeback(&q->backing_dev_info, nr_pages);
 }
 
 /*

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/6] writeback: fix writeback completion notifications
  2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
@ 2010-06-08 19:50   ` Jens Axboe
  2010-06-15 17:25   ` Jan Kara
  1 sibling, 0 replies; 19+ messages in thread
From: Jens Axboe @ 2010-06-08 19:50 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 08/06/10 18.14, Christoph Hellwig wrote:
> The code dealing with bdi_work->state and completion of a bdi_work is a
> major mess currently.  This patch makes sure we directly use one set of
> flags to deal with it, and use it consistently, which means:
> 
>  - always notify about completion from the rcu callback.  We only ever
>    wait for it from on-stack callers, so this simplification does not
>    even cause a theoretical slowdown currently.  It also makes sure we
>    don't miss out on the notification if we ever add other callers to
>    wait for it.

It's still more costly to actually do the rcu callback, but I guess it's
not too big of a deal.

>  - make earlier completion notification depending on the on-stack
>    allocation, not the sync mode.  If we introduce new callers that
>    want to do WB_SYNC_NONE writeback from on-stack callers this will
>    be nessecary.
> 
> Also rename bdi_wait_on_work_clear to bdi_wait_on_work_done and inline
> a few small functions into their only caller to make the code
> understandable.

Looks good to me.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb
  2010-06-08 16:14 ` [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb Christoph Hellwig
@ 2010-06-08 19:51   ` Jens Axboe
  0 siblings, 0 replies; 19+ messages in thread
From: Jens Axboe @ 2010-06-08 19:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 08/06/10 18.14, Christoph Hellwig wrote:
> If we want to rely on s_umount in the caller we need to wait for completion
> of the I/O submission before returning to the caller.  Refactor
> bdi_sync_writeback into a bdi_queue_work_onstack helper and use it for this
> case.

Looks good to me.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb
  2010-06-08 16:14 ` [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb Christoph Hellwig
@ 2010-06-08 19:51   ` Jens Axboe
  2010-06-09 12:25     ` Christoph Hellwig
  0 siblings, 1 reply; 19+ messages in thread
From: Jens Axboe @ 2010-06-08 19:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 08/06/10 18.14, Christoph Hellwig wrote:
> When we call writeback_inodes_wb from writeback_inodes_sb we always have
> s_umount held, which currently makes the whole operation a no-op.
> 
> But if we are called to write out inodes for a specific superblock we always
> have s_umount held, so replace the incorrect logic checking for WB_SYNC_ALL
> which only worked by coincidence with the proper check for an explicit
> superblock argument.

This is tons better than the pinning, I like it a lot.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 5/6] writeback: simplify wakeup_flusher_threads
  2010-06-08 16:15 ` [PATCH 5/6] writeback: simplify wakeup_flusher_threads Christoph Hellwig
@ 2010-06-08 19:51   ` Jens Axboe
  0 siblings, 0 replies; 19+ messages in thread
From: Jens Axboe @ 2010-06-08 19:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 08/06/10 18.15, Christoph Hellwig wrote:
> bdi_writeback_all only has one caller, so fold it to simplify the code and
> flatten the call stack.

Looks good to me.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 6/6] writeback: simplify and split bdi_start_writeback
  2010-06-08 16:15 ` [PATCH 6/6] writeback: simplify and split bdi_start_writeback Christoph Hellwig
@ 2010-06-08 19:52   ` Jens Axboe
  0 siblings, 0 replies; 19+ messages in thread
From: Jens Axboe @ 2010-06-08 19:52 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 08/06/10 18.15, Christoph Hellwig wrote:
> bdi_start_writeback now never gets a superblock passed, so we can just remove
> that case.  And to further untangle the code and flatten the call stack
> split it into two trivial helpers for it's two callers.

This also looks fine.

Overall it's a nice patch series, makes the code a lot more readable as well.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb
  2010-06-08 19:51   ` Jens Axboe
@ 2010-06-09 12:25     ` Christoph Hellwig
  2010-06-09 12:29       ` Jens Axboe
  0 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-09 12:25 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Christoph Hellwig, linux-fsdevel

On Tue, Jun 08, 2010 at 09:51:39PM +0200, Jens Axboe wrote:
> On 08/06/10 18.14, Christoph Hellwig wrote:
> > When we call writeback_inodes_wb from writeback_inodes_sb we always have
> > s_umount held, which currently makes the whole operation a no-op.
> > 
> > But if we are called to write out inodes for a specific superblock we always
> > have s_umount held, so replace the incorrect logic checking for WB_SYNC_ALL
> > which only worked by coincidence with the proper check for an explicit
> > superblock argument.
> 
> This is tons better than the pinning, I like it a lot.

Unfortunately I accidentally removed the requeue_io call when we fail
to pin the inode.  This leads to softlockups after heavy I/O load.

Please fold the patch below into this one, or if not possible add it
to the end of the series.

---
From: Christoph Hellwig <hch@lst.de>
Subject: [PATCH] writeback: add missing requeue_io in writeback_inodes_wb

In "writeback: fix writeback_inodes_wb from writeback_inodes_sb" I
accidentally removed the requeue_io if we need to skip a superblock
because we can't pin it.  Add it back, otherwise we're getting spurious
lockups after multiple xfstests runs.

Signed-off-by: Christoph Hellwig <hch@lst.de>

Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c	2010-06-09 12:09:42.462024800 +0200
+++ linux-2.6/fs/fs-writeback.c	2010-06-09 12:09:47.830005523 +0200
@@ -643,8 +643,10 @@ static void writeback_inodes_wb(struct b
 
 			ret = writeback_sb_inodes(sb, wb, wbc);
 		} else {
-			if (!pin_sb_for_writeback(sb))
+			if (!pin_sb_for_writeback(sb)) {
+				requeue_io(inode);
 				continue;
+			}
 			ret = writeback_sb_inodes(sb, wb, wbc);
 			drop_super(sb);
 		}

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb
  2010-06-09 12:25     ` Christoph Hellwig
@ 2010-06-09 12:29       ` Jens Axboe
  0 siblings, 0 replies; 19+ messages in thread
From: Jens Axboe @ 2010-06-09 12:29 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel

On 2010-06-09 14:25, Christoph Hellwig wrote:
> On Tue, Jun 08, 2010 at 09:51:39PM +0200, Jens Axboe wrote:
>> On 08/06/10 18.14, Christoph Hellwig wrote:
>>> When we call writeback_inodes_wb from writeback_inodes_sb we always have
>>> s_umount held, which currently makes the whole operation a no-op.
>>>
>>> But if we are called to write out inodes for a specific superblock we always
>>> have s_umount held, so replace the incorrect logic checking for WB_SYNC_ALL
>>> which only worked by coincidence with the proper check for an explicit
>>> superblock argument.
>>
>> This is tons better than the pinning, I like it a lot.
> 
> Unfortunately I accidentally removed the requeue_io call when we fail
> to pin the inode.  This leads to softlockups after heavy I/O load.
> 
> Please fold the patch below into this one, or if not possible add it
> to the end of the series.

Oops, not good. I already merged and pushed them out, so I added it to
the end instead.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/6] writeback: fix writeback completion notifications
  2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
  2010-06-08 19:50   ` Jens Axboe
@ 2010-06-15 17:25   ` Jan Kara
  2010-06-15 17:30     ` Christoph Hellwig
  1 sibling, 1 reply; 19+ messages in thread
From: Jan Kara @ 2010-06-15 17:25 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: axboe, linux-fsdevel

On Tue 08-06-10 18:14:34, Christoph Hellwig wrote:
> The code dealing with bdi_work->state and completion of a bdi_work is a
> major mess currently.  This patch makes sure we directly use one set of
> flags to deal with it, and use it consistently, which means:
> 
>  - always notify about completion from the rcu callback.  We only ever
>    wait for it from on-stack callers, so this simplification does not
>    even cause a theoretical slowdown currently.  It also makes sure we
>    don't miss out on the notification if we ever add other callers to
>    wait for it.
>  - make earlier completion notification depending on the on-stack
>    allocation, not the sync mode.  If we introduce new callers that
>    want to do WB_SYNC_NONE writeback from on-stack callers this will
>    be nessecary.
> 
> Also rename bdi_wait_on_work_clear to bdi_wait_on_work_done and inline
  What I find slightly misleading on bdi_wait_on_work_done is that work
isn't always "done" when this returns. For WB_SYNC_NONE writeback this
function returns as soon as writeback thread starts the work... But I don't
have a better name.

								Honza

-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 1/6] writeback: fix writeback completion notifications
  2010-06-15 17:25   ` Jan Kara
@ 2010-06-15 17:30     ` Christoph Hellwig
  0 siblings, 0 replies; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-15 17:30 UTC (permalink / raw)
  To: Jan Kara; +Cc: Christoph Hellwig, axboe, linux-fsdevel

On Tue, Jun 15, 2010 at 07:25:15PM +0200, Jan Kara wrote:
> > Also rename bdi_wait_on_work_clear to bdi_wait_on_work_done and inline
>   What I find slightly misleading on bdi_wait_on_work_done is that work
> isn't always "done" when this returns. For WB_SYNC_NONE writeback this
> function returns as soon as writeback thread starts the work... But I don't
> have a better name.

Well, the "work" actually is done.  For WB_SYNC_NONE that is just
kicking off the writeback, not waiting for it.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] writeback: enforce s_umount locking in writeback_inodes_sb
  2010-06-08 16:14 ` [PATCH 3/6] writeback: enforce s_umount locking " Christoph Hellwig
@ 2010-06-15 17:54   ` Jan Kara
  2010-06-15 17:59     ` Christoph Hellwig
  0 siblings, 1 reply; 19+ messages in thread
From: Jan Kara @ 2010-06-15 17:54 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: axboe, linux-fsdevel

On Tue 08-06-10 18:14:51, Christoph Hellwig wrote:
> Make sure that not only sync_filesystem but all callers of writeback_inodes_sb
> have the superblock protected against remount.  As-is this disables all
> functionality for these callers, but the next patch relies on this locking to
> fix writeback_inodes_sb for sync_filesystem.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> 
> Index: linux-2.6/fs/fs-writeback.c
> ===================================================================
> --- linux-2.6.orig/fs/fs-writeback.c	2010-06-08 16:25:35.000000000 +0200
> +++ linux-2.6/fs/fs-writeback.c	2010-06-08 16:27:47.846255651 +0200
> @@ -1180,6 +1180,8 @@ void writeback_inodes_sb(struct super_bl
>  		.sync_mode	= WB_SYNC_NONE,
>  	};
>  
> +	WARN_ON(!rwsem_is_locked(&sb->s_umount));
> +
>  	args.nr_pages = nr_dirty + nr_unstable +
>  			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
>  
> @@ -1197,7 +1199,9 @@ EXPORT_SYMBOL(writeback_inodes_sb);
>  int writeback_inodes_sb_if_idle(struct super_block *sb)
>  {
>  	if (!writeback_in_progress(sb->s_bdi)) {
> +		down_read(&sb->s_umount);
>  		writeback_inodes_sb(sb);
> +		up_read(&sb->s_umount);
  But this is buggy isn't it? writeback_inodes_sb() returns as soon as
flusher threads start submitting the IO. So we release s_umount too early -
flusher threads can be still writing out inodes for our work. It's exactly
cases like this why I don't like the work to be called "done" when flusher
threads actually still do it...

								Honza
>  		return 1;
>  	} else
>  		return 0;
> @@ -1220,6 +1224,8 @@ void sync_inodes_sb(struct super_block *
>  		.range_cyclic	= 0,
>  	};
>  
> +	WARN_ON(!rwsem_is_locked(&sb->s_umount));
> +
>  	bdi_queue_work_onstack(&args);
>  	wait_sb_inodes(sb);
>  }
> Index: linux-2.6/fs/ubifs/budget.c
> ===================================================================
> --- linux-2.6.orig/fs/ubifs/budget.c	2010-06-08 16:22:16.000000000 +0200
> +++ linux-2.6/fs/ubifs/budget.c	2010-06-08 16:26:50.464004778 +0200
> @@ -62,7 +62,9 @@
>   */
>  static void shrink_liability(struct ubifs_info *c, int nr_to_write)
>  {
> +	down_read(&c->vfs_sb->s_umount);
>  	writeback_inodes_sb(c->vfs_sb);
> +	up_read(&c->vfs_sb->s_umount);
>  }
>  
>  /**
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] writeback: enforce s_umount locking in writeback_inodes_sb
  2010-06-15 17:54   ` Jan Kara
@ 2010-06-15 17:59     ` Christoph Hellwig
  2010-06-15 18:04       ` Jan Kara
  0 siblings, 1 reply; 19+ messages in thread
From: Christoph Hellwig @ 2010-06-15 17:59 UTC (permalink / raw)
  To: Jan Kara; +Cc: Christoph Hellwig, axboe, linux-fsdevel

On Tue, Jun 15, 2010 at 07:54:13PM +0200, Jan Kara wrote:
>   But this is buggy isn't it? writeback_inodes_sb() returns as soon as
> flusher threads start submitting the IO. So we release s_umount too early -
> flusher threads can be still writing out inodes for our work. It's exactly
> cases like this why I don't like the work to be called "done" when flusher
> threads actually still do it...

Now that writeback_inodes_sb uses bdi_queue_work_onstack, wb_do_writeback
doesn't signal completion until I/O is submitted.  So the locking should
be safe.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH 3/6] writeback: enforce s_umount locking in writeback_inodes_sb
  2010-06-15 17:59     ` Christoph Hellwig
@ 2010-06-15 18:04       ` Jan Kara
  0 siblings, 0 replies; 19+ messages in thread
From: Jan Kara @ 2010-06-15 18:04 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Jan Kara, axboe, linux-fsdevel

On Tue 15-06-10 19:59:35, Christoph Hellwig wrote:
> On Tue, Jun 15, 2010 at 07:54:13PM +0200, Jan Kara wrote:
> >   But this is buggy isn't it? writeback_inodes_sb() returns as soon as
> > flusher threads start submitting the IO. So we release s_umount too early -
> > flusher threads can be still writing out inodes for our work. It's exactly
> > cases like this why I don't like the work to be called "done" when flusher
> > threads actually still do it...
> 
> Now that writeback_inodes_sb uses bdi_queue_work_onstack, wb_do_writeback
> doesn't signal completion until I/O is submitted.  So the locking should
> be safe.
  Yay, I see. But it's a bit subtle...

								Honza
-- 
Jan Kara <jack@suse.cz>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2010-06-15 18:05 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-08 16:14 [PATCH 0/6] writeback fixes - slow unmount and others Christoph Hellwig
2010-06-08 16:14 ` [PATCH 1/6] writeback: fix writeback completion notifications Christoph Hellwig
2010-06-08 19:50   ` Jens Axboe
2010-06-15 17:25   ` Jan Kara
2010-06-15 17:30     ` Christoph Hellwig
2010-06-08 16:14 ` [PATCH 2/6] writeback: queue work on stack in writeback_inodes_sb Christoph Hellwig
2010-06-08 19:51   ` Jens Axboe
2010-06-08 16:14 ` [PATCH 3/6] writeback: enforce s_umount locking " Christoph Hellwig
2010-06-15 17:54   ` Jan Kara
2010-06-15 17:59     ` Christoph Hellwig
2010-06-15 18:04       ` Jan Kara
2010-06-08 16:14 ` [PATCH 4/6] writeback: fix writeback_inodes_wb from writeback_inodes_sb Christoph Hellwig
2010-06-08 19:51   ` Jens Axboe
2010-06-09 12:25     ` Christoph Hellwig
2010-06-09 12:29       ` Jens Axboe
2010-06-08 16:15 ` [PATCH 5/6] writeback: simplify wakeup_flusher_threads Christoph Hellwig
2010-06-08 19:51   ` Jens Axboe
2010-06-08 16:15 ` [PATCH 6/6] writeback: simplify and split bdi_start_writeback Christoph Hellwig
2010-06-08 19:52   ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.