Fix a bug in the block cache read path.

This commit is contained in:
Joe Thornber 2014-07-29 13:41:45 +01:00
parent f06a2673c5
commit a99d6896a8
2 changed files with 36 additions and 21 deletions

View File

@ -146,7 +146,7 @@ namespace bcache {
* lists. * lists.
*/ */
// FIXME: add batch issue // FIXME: add batch issue
int void
block_cache::issue_low_level(block &b, enum io_iocb_cmd opcode, const char *desc) block_cache::issue_low_level(block &b, enum io_iocb_cmd opcode, const char *desc)
{ {
int r; int r;
@ -168,25 +168,26 @@ namespace bcache {
info("could not submit IOs, with %s op\n", desc); info("could not submit IOs, with %s op\n", desc);
complete_io(b, EIO); complete_io(b, EIO);
return -EIO;
std::ostringstream out;
out << "couldn't issue io (" << desc << ") for block " << b.index_;
throw std::runtime_error(out.str());
}
} }
return 0; void
}
int
block_cache::issue_read(block &b) block_cache::issue_read(block &b)
{ {
assert(!b.test_flags(BF_IO_PENDING)); assert(!b.test_flags(BF_IO_PENDING));
return issue_low_level(b, IO_CMD_PREAD, "read"); issue_low_level(b, IO_CMD_PREAD, "read");
} }
int void
block_cache::issue_write(block &b) block_cache::issue_write(block &b)
{ {
assert(!b.test_flags(BF_IO_PENDING)); assert(!b.test_flags(BF_IO_PENDING));
b.v_->prepare(b.data_, b.index_); b.v_->prepare(b.data_, b.index_);
return issue_low_level(b, IO_CMD_PWRITE, "write"); issue_low_level(b, IO_CMD_PWRITE, "write");
} }
void void
@ -267,7 +268,6 @@ namespace bcache {
unsigned unsigned
block_cache::writeback(unsigned count) block_cache::writeback(unsigned count)
{ {
int r;
block *b, *tmp; block *b, *tmp;
unsigned actual = 0, dirty_length = 0; unsigned actual = 0, dirty_length = 0;
@ -282,8 +282,7 @@ namespace bcache {
if (b->ref_count_) if (b->ref_count_)
continue; continue;
r = issue_write(*b); issue_write(*b);
if (!r)
actual++; actual++;
} }
@ -361,6 +360,23 @@ namespace bcache {
cb->u.c.nbytes = block_size_bytes; cb->u.c.nbytes = block_size_bytes;
} }
block_cache::block *
block_cache::find_unused_clean_block()
{
struct block *b, *tmp;
list_for_each_entry_safe (b, tmp, &clean_, list_) {
if (b->ref_count_)
continue;
hash_remove(*b);
list_del(&b->list_);
return b;
}
return NULL;
}
block_cache::block * block_cache::block *
block_cache::new_block(block_address index) block_cache::new_block(block_address index)
{ {
@ -374,11 +390,7 @@ namespace bcache {
wait_io(); wait_io();
} }
if (!list_empty(&clean_)) { b = find_unused_clean_block();
b = list_first_entry(&clean_, block, list_);
hash_remove(*b);
list_del(&b->list_);
}
} }
if (b) { if (b) {
@ -510,8 +522,10 @@ namespace bcache {
else { else {
if (b->v_.get() && if (b->v_.get() &&
b->v_.get() != v.get() && b->v_.get() != v.get() &&
b->test_flags(BF_DIRTY)) b->test_flags(BF_DIRTY)) {
b->v_->prepare(b->data_, b->index_); b->v_->prepare(b->data_, b->index_);
v->check(b->data_, b->index_);
}
} }
b->v_ = v; b->v_ = v;

View File

@ -139,9 +139,9 @@ namespace bcache {
int init_free_list(unsigned count); int init_free_list(unsigned count);
block *__alloc_block(); block *__alloc_block();
void complete_io(block &b, int result); void complete_io(block &b, int result);
int issue_low_level(block &b, enum io_iocb_cmd opcode, const char *desc); void issue_low_level(block &b, enum io_iocb_cmd opcode, const char *desc);
int issue_read(block &b); void issue_read(block &b);
int issue_write(block &b); void issue_write(block &b);
void wait_io(); void wait_io();
list_head *__categorise(block &b); list_head *__categorise(block &b);
void hit(block &b); void hit(block &b);
@ -154,6 +154,7 @@ namespace bcache {
void hash_insert(block &b); void hash_insert(block &b);
void hash_remove(block &b); void hash_remove(block &b);
void setup_control_block(block &b); void setup_control_block(block &b);
block *find_unused_clean_block();
block *new_block(block_address index); block *new_block(block_address index);
void mark_dirty(block &b); void mark_dirty(block &b);
unsigned calc_nr_cache_blocks(size_t mem, sector_t block_size); unsigned calc_nr_cache_blocks(size_t mem, sector_t block_size);