diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..d38a03cf --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,8 @@ +* +!.gitignore +!dm-writeboost.h +!dm-writeboost-target.[c] +!dm-writeboost-metadata.[ch] +!dm-writeboost-daemon.[ch] +!dkms.conf +!Makefile \ No newline at end of file diff --git a/src/dm-writeboost-target.c b/src/dm-writeboost-target.c index bb6dd3f9..51c9df16 100644 --- a/src/dm-writeboost-target.c +++ b/src/dm-writeboost-target.c @@ -752,7 +752,10 @@ static struct read_cache_cell *lookup_read_cache_cell(struct wb_device *wb, sect return NULL; } -static void read_cache_cancel_cells(struct read_cache_cells *cells, u32 n) +/* + * Cancel all cells in [cursor, cursor + seqcount). + */ +static void read_cache_cancel_seq_cells(struct read_cache_cells *cells) { u32 i; u32 last = cells->cursor + cells->seqcount; @@ -760,7 +763,7 @@ static void read_cache_cancel_cells(struct read_cache_cells *cells, u32 n) last = cells->size; for (i = cells->cursor; i < last; i++) { struct read_cache_cell *cell = cells->array + i; - cell->cancelled = true; + atomic_set(&cell->cancelled, 1); } } @@ -780,10 +783,10 @@ static void read_cache_cancel_foreground(struct read_cache_cells *cells, if (cells->seqcount > cells->threshold) { if (cells->over_threshold) - new_cell->cancelled = true; + atomic_set(&new_cell->cancelled, 1); else { cells->over_threshold = true; - read_cache_cancel_cells(cells, cells->seqcount); + read_cache_cancel_seq_cells(cells); } } cells->last_sector = new_cell->sector; @@ -839,7 +842,7 @@ static void might_cancel_read_cache_cell(struct wb_device *wb, struct bio *bio) struct read_cache_cell *found; found = lookup_read_cache_cell(wb, calc_cache_alignment(bi_sector(bio))); if (found) - found->cancelled = true; + atomic_set(&found->cancelled, 1); } static void read_cache_cell_copy_data(struct wb_device *wb, struct bio *bio, unsigned long error) @@ -852,13 +855,13 @@ static void read_cache_cell_copy_data(struct wb_device *wb, struct bio *bio, uns /* Data can be broken. So don't stage. */ if (error) - cell->cancelled = true; + atomic_set(&cell->cancelled, 1); /* * We can omit copying if the cell is cancelled but * copying for a non-cancelled cell isn't problematic. */ - if (!cell->cancelled) + if (!atomic_read(&cell->cancelled)) copy_bio_payload(cell->data, bio); if (atomic_dec_and_test(&cells->ack_count)) @@ -884,7 +887,7 @@ static void inject_read_cache(struct wb_device *wb, struct read_cache_cell *cell * if might_cancel_read_cache_cell() on the foreground * cancelled this cell, the data is now stale. */ - if (cell->cancelled) { + if (atomic_read(&cell->cancelled)) { mutex_unlock(&wb->io_lock); return; } @@ -980,20 +983,18 @@ static void reinit_read_cache_cells(struct wb_device *wb) struct read_cache_cells *cells = wb->read_cache_cells; u32 i, cur_threshold; - mutex_lock(&wb->io_lock); cells->rb_root = RB_ROOT; cells->cursor = cells->size; atomic_set(&cells->ack_count, cells->size); for (i = 0; i < cells->size; i++) { struct read_cache_cell *cell = cells->array + i; - cell->cancelled = false; + atomic_set(&cell->cancelled, 0); } cur_threshold = read_once(wb->read_cache_threshold); if (cur_threshold && (cur_threshold != cells->threshold)) { cells->threshold = cur_threshold; cells->over_threshold = false; } - mutex_unlock(&wb->io_lock); } /* @@ -1004,7 +1005,7 @@ static void visit_and_cancel_cells(struct rb_node *first, struct rb_node *last) struct rb_node *rbp = first; while (rbp != last) { struct read_cache_cell *cell = read_cache_cell_from_node(rbp); - cell->cancelled = true; + atomic_set(&cell->cancelled, 1); rbp = rb_next(rbp); } } @@ -1049,7 +1050,9 @@ static void read_cache_proc(struct work_struct *work) inject_read_cache(wb, cell); } + mutex_lock(&wb->io_lock); reinit_read_cache_cells(wb); + mutex_unlock(&wb->io_lock); } static int init_read_cache_cells(struct wb_device *wb) @@ -1260,9 +1263,8 @@ static int process_write_wa(struct wb_device *wb, struct bio *bio) if (res.found) { dec_inflight_ios(wb, res.found_seg); ht_del(wb, res.found_mb); - } - - might_cancel_read_cache_cell(wb, bio); + } else + might_cancel_read_cache_cell(wb, bio); mutex_unlock(&wb->io_lock); bio_remap(bio, wb->backing_dev, bi_sector(bio)); diff --git a/src/dm-writeboost.h b/src/dm-writeboost.h index 37a3a423..29ccf812 100644 --- a/src/dm-writeboost.h +++ b/src/dm-writeboost.h @@ -207,7 +207,7 @@ struct writeback_segment { struct read_cache_cell { sector_t sector; void *data; /* 4KB data read */ - bool cancelled; /* Don't include this */ + atomic_t cancelled; /* Don't include this */ struct rb_node rb_node; };