Commit e1df8b0a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'writeback-plugging'

Fix up the writeback plugging introduced in commit d353d758
("writeback: plug writeback at a high level") that then caused problems
due to the unplug happening with a spinlock held.

* writeback-plugging:
  writeback: plug writeback in wb_writeback() and writeback_inodes_wb()
  Revert "writeback: plug writeback at a high level"
parents dfb22fc5 505a666e
...@@ -1380,6 +1380,10 @@ static long writeback_chunk_size(struct bdi_writeback *wb, ...@@ -1380,6 +1380,10 @@ static long writeback_chunk_size(struct bdi_writeback *wb,
* Write a portion of b_io inodes which belong to @sb. * Write a portion of b_io inodes which belong to @sb.
* *
* Return the number of pages and/or inodes written. * Return the number of pages and/or inodes written.
*
* NOTE! This is called with wb->list_lock held, and will
* unlock and relock that for each inode it ends up doing
* IO for.
*/ */
static long writeback_sb_inodes(struct super_block *sb, static long writeback_sb_inodes(struct super_block *sb,
struct bdi_writeback *wb, struct bdi_writeback *wb,
...@@ -1398,9 +1402,7 @@ static long writeback_sb_inodes(struct super_block *sb, ...@@ -1398,9 +1402,7 @@ static long writeback_sb_inodes(struct super_block *sb,
unsigned long start_time = jiffies; unsigned long start_time = jiffies;
long write_chunk; long write_chunk;
long wrote = 0; /* count both pages and inodes */ long wrote = 0; /* count both pages and inodes */
struct blk_plug plug;
blk_start_plug(&plug);
while (!list_empty(&wb->b_io)) { while (!list_empty(&wb->b_io)) {
struct inode *inode = wb_inode(wb->b_io.prev); struct inode *inode = wb_inode(wb->b_io.prev);
...@@ -1498,7 +1500,6 @@ static long writeback_sb_inodes(struct super_block *sb, ...@@ -1498,7 +1500,6 @@ static long writeback_sb_inodes(struct super_block *sb,
break; break;
} }
} }
blk_finish_plug(&plug);
return wrote; return wrote;
} }
...@@ -1545,12 +1546,15 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, ...@@ -1545,12 +1546,15 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
.range_cyclic = 1, .range_cyclic = 1,
.reason = reason, .reason = reason,
}; };
struct blk_plug plug;
blk_start_plug(&plug);
spin_lock(&wb->list_lock); spin_lock(&wb->list_lock);
if (list_empty(&wb->b_io)) if (list_empty(&wb->b_io))
queue_io(wb, &work); queue_io(wb, &work);
__writeback_inodes_wb(wb, &work); __writeback_inodes_wb(wb, &work);
spin_unlock(&wb->list_lock); spin_unlock(&wb->list_lock);
blk_finish_plug(&plug);
return nr_pages - work.nr_pages; return nr_pages - work.nr_pages;
} }
...@@ -1578,10 +1582,12 @@ static long wb_writeback(struct bdi_writeback *wb, ...@@ -1578,10 +1582,12 @@ static long wb_writeback(struct bdi_writeback *wb,
unsigned long oldest_jif; unsigned long oldest_jif;
struct inode *inode; struct inode *inode;
long progress; long progress;
struct blk_plug plug;
oldest_jif = jiffies; oldest_jif = jiffies;
work->older_than_this = &oldest_jif; work->older_than_this = &oldest_jif;
blk_start_plug(&plug);
spin_lock(&wb->list_lock); spin_lock(&wb->list_lock);
for (;;) { for (;;) {
/* /*
...@@ -1661,6 +1667,7 @@ static long wb_writeback(struct bdi_writeback *wb, ...@@ -1661,6 +1667,7 @@ static long wb_writeback(struct bdi_writeback *wb,
} }
} }
spin_unlock(&wb->list_lock); spin_unlock(&wb->list_lock);
blk_finish_plug(&plug);
return nr_pages - work->nr_pages; return nr_pages - work->nr_pages;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment