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();  	}  |