aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-09-16 13:22:48 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-09-25 12:08:24 -0400
commita5989bdc981ec85e0734ac22519cc0b780813d7b (patch)
tree74cc93bd420b7bd044e3fd5451c652b3742015e6 /fs
parent7fa07729e439a6184bd824746d06a49cca553f15 (diff)
fs: Fix busyloop in wb_writeback()
If all inodes are under writeback (e.g. in case when there's only one inode with dirty pages), wb_writeback() with WB_SYNC_NONE work basically degrades to busylooping until I_SYNC flags of the inode is cleared. Fix the problem by waiting on I_SYNC flags of an inode on b_more_io list in case we failed to write anything. Tested-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/fs-writeback.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 8e1e5e19d21e..c59d6737036c 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -706,6 +706,7 @@ static long wb_writeback(struct bdi_writeback *wb,
706 }; 706 };
707 unsigned long oldest_jif; 707 unsigned long oldest_jif;
708 long wrote = 0; 708 long wrote = 0;
709 struct inode *inode;
709 710
710 if (wbc.for_kupdate) { 711 if (wbc.for_kupdate) {
711 wbc.older_than_this = &oldest_jif; 712 wbc.older_than_this = &oldest_jif;
@@ -747,8 +748,24 @@ static long wb_writeback(struct bdi_writeback *wb,
747 * If we ran out of stuff to write, bail unless more_io got set 748 * If we ran out of stuff to write, bail unless more_io got set
748 */ 749 */
749 if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) { 750 if (wbc.nr_to_write > 0 || wbc.pages_skipped > 0) {
750 if (wbc.more_io && !wbc.for_kupdate) 751 if (wbc.more_io && !wbc.for_kupdate) {
752 if (wbc.nr_to_write < MAX_WRITEBACK_PAGES)
753 continue;
754 /*
755 * Nothing written. Wait for some inode to
756 * become available for writeback. Otherwise
757 * we'll just busyloop.
758 */
759 spin_lock(&inode_lock);
760 if (!list_empty(&wb->b_more_io)) {
761 inode = list_entry(
762 wb->b_more_io.prev,
763 struct inode, i_list);
764 inode_wait_for_writeback(inode);
765 }
766 spin_unlock(&inode_lock);
751 continue; 767 continue;
768 }
752 break; 769 break;
753 } 770 }
754 } 771 }