Fix a bug in the block cache read path.
This commit is contained in:
parent
f06a2673c5
commit
a99d6896a8
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user