diff options
Diffstat (limited to 'drivers/md/dm-writecache.c')
-rw-r--r-- | drivers/md/dm-writecache.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index 1cb137f0ef9d..d06b8aa41e26 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -190,7 +190,6 @@ struct writeback_struct { struct dm_writecache *wc; struct wc_entry **wc_list; unsigned wc_list_n; - struct page *page; struct wc_entry *wc_list_inline[WB_LIST_INLINE]; struct bio bio; }; @@ -727,7 +726,8 @@ static void writecache_flush(struct dm_writecache *wc) } writecache_commit_flushed(wc); - writecache_wait_for_ios(wc, WRITE); + if (!WC_MODE_PMEM(wc)) + writecache_wait_for_ios(wc, WRITE); wc->seq_count++; pmem_assign(sb(wc)->seq_count, cpu_to_le64(wc->seq_count)); @@ -1561,7 +1561,7 @@ static void writecache_writeback(struct work_struct *work) { struct dm_writecache *wc = container_of(work, struct dm_writecache, writeback_work); struct blk_plug plug; - struct wc_entry *e, *f, *g; + struct wc_entry *f, *g, *e = NULL; struct rb_node *node, *next_node; struct list_head skipped; struct writeback_list wbl; @@ -1598,7 +1598,14 @@ restart: break; } - e = container_of(wc->lru.prev, struct wc_entry, lru); + if (unlikely(wc->writeback_all)) { + if (unlikely(!e)) { + writecache_flush(wc); + e = container_of(rb_first(&wc->tree), struct wc_entry, rb_node); + } else + e = g; + } else + e = container_of(wc->lru.prev, struct wc_entry, lru); BUG_ON(e->write_in_progress); if (unlikely(!writecache_entry_is_committed(wc, e))) { writecache_flush(wc); @@ -1629,8 +1636,8 @@ restart: if (unlikely(!next_node)) break; g = container_of(next_node, struct wc_entry, rb_node); - if (read_original_sector(wc, g) == - read_original_sector(wc, f)) { + if (unlikely(read_original_sector(wc, g) == + read_original_sector(wc, f))) { f = g; continue; } @@ -1659,8 +1666,14 @@ restart: g->wc_list_contiguous = BIO_MAX_PAGES; f = g; e->wc_list_contiguous++; - if (unlikely(e->wc_list_contiguous == BIO_MAX_PAGES)) + if (unlikely(e->wc_list_contiguous == BIO_MAX_PAGES)) { + if (unlikely(wc->writeback_all)) { + next_node = rb_next(&f->rb_node); + if (likely(next_node)) + g = container_of(next_node, struct wc_entry, rb_node); + } break; + } } cond_resched(); } |