1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

[device/bcache] Add a couple of invalidate methods

This commit is contained in:
Joe Thornber 2018-02-02 07:59:49 +00:00 committed by David Teigland
parent 0f0eb04edb
commit c4c4acfd42
2 changed files with 73 additions and 0 deletions

View File

@ -884,5 +884,65 @@ int bcache_flush(struct bcache *cache)
return dm_list_empty(&cache->errored) ? 0 : -EIO;
}
static void _recycle_block(struct bcache *cache, struct block *b)
{
_unlink_block(b);
_hash_remove(b);
dm_list_add(&cache->free, &b->list);
}
/*
* You can safely call this with a NULL block.
*/
static void _invalidate_block(struct bcache *cache, struct block *b)
{
if (!b)
return;
if (_test_flags(b, BF_IO_PENDING))
_wait_specific(b);
if (b->ref_count)
log_warn("bcache_invalidate: block (%d, %llu) still held",
b->fd, (unsigned long long) index);
else {
if (_test_flags(b, BF_DIRTY)) {
_issue_write(b);
_wait_specific(b);
}
_recycle_block(cache, b);
}
}
void bcache_invalidate(struct bcache *cache, int fd, block_address index)
{
_invalidate_block(cache, _hash_lookup(cache, fd, index));
}
// FIXME: switch to a trie, or maybe 1 hash table per fd? To save iterating
// through the whole cache.
void bcache_invalidate_fd(struct bcache *cache, int fd)
{
struct block *b, *tmp;
// Start writing back any dirty blocks on this fd.
dm_list_iterate_items_safe (b, tmp, &cache->dirty)
if (b->fd == fd)
_issue_write(b);
_wait_all(cache);
// Everything should be in the clean list now.
dm_list_iterate_items_safe (b, tmp, &cache->clean)
if (b->fd == fd)
_invalidate_block(cache, b);
// Except they could be in the errored list :)
dm_list_iterate_items_safe (b, tmp, &cache->errored)
if (b->fd == fd)
_recycle_block(cache, b);
}
//----------------------------------------------------------------

View File

@ -93,6 +93,19 @@ void bcache_put(struct block *b);
int bcache_flush(struct bcache *cache);
/*
* Removes a block from the cache. If the block is dirty it will be written
* back first. If the block is currently held a warning will be issued, and it
* will not be removed.
*/
void bcache_invalidate(struct bcache *cache, int fd, block_address index);
/*
* Invalidates all blocks on the given descriptor. Call this before closing
* the descriptor to make sure everything is written back.
*/
void bcache_invalidate_fd(struct bcache *cache, int fd);
/*----------------------------------------------------------------*/
#endif