mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-02 20:44:00 +00:00
btrfs: hooks for readahead
This adds the hooks needed for readahead. In the readpage_end_io_hook, the extent state is checked for the EXTENT_READAHEAD flag. Only in this case the readahead hook is called, to keep the impact on non-ra as low as possible. Additionally, a hook for a failed IO is added, otherwise readahead would wait indefinitely for the extent to finish. Changes for v2: - eliminate race condition Signed-off-by: Arne Jansen <sensille@gmx.net>
This commit is contained in:
parent
7414a03fbf
commit
4bb31e928d
2 changed files with 38 additions and 1 deletions
|
@ -609,11 +609,47 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
|
||||||
end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
|
end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
|
||||||
end = eb->start + end - 1;
|
end = eb->start + end - 1;
|
||||||
err:
|
err:
|
||||||
|
if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
|
||||||
|
clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
|
||||||
|
btree_readahead_hook(root, eb, eb->start, ret);
|
||||||
|
}
|
||||||
|
|
||||||
free_extent_buffer(eb);
|
free_extent_buffer(eb);
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int btree_io_failed_hook(struct bio *failed_bio,
|
||||||
|
struct page *page, u64 start, u64 end,
|
||||||
|
struct extent_state *state)
|
||||||
|
{
|
||||||
|
struct extent_io_tree *tree;
|
||||||
|
unsigned long len;
|
||||||
|
struct extent_buffer *eb;
|
||||||
|
struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
|
||||||
|
|
||||||
|
tree = &BTRFS_I(page->mapping->host)->io_tree;
|
||||||
|
if (page->private == EXTENT_PAGE_PRIVATE)
|
||||||
|
goto out;
|
||||||
|
if (!page->private)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
len = page->private >> 2;
|
||||||
|
WARN_ON(len == 0);
|
||||||
|
|
||||||
|
eb = alloc_extent_buffer(tree, start, len, page);
|
||||||
|
if (eb == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
|
||||||
|
clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
|
||||||
|
btree_readahead_hook(root, eb, eb->start, -EIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return -EIO; /* we fixed nothing */
|
||||||
|
}
|
||||||
|
|
||||||
static void end_workqueue_bio(struct bio *bio, int err)
|
static void end_workqueue_bio(struct bio *bio, int err)
|
||||||
{
|
{
|
||||||
struct end_io_wq *end_io_wq = bio->bi_private;
|
struct end_io_wq *end_io_wq = bio->bi_private;
|
||||||
|
@ -3166,6 +3202,7 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root)
|
||||||
static struct extent_io_ops btree_extent_io_ops = {
|
static struct extent_io_ops btree_extent_io_ops = {
|
||||||
.write_cache_pages_lock_hook = btree_lock_page_hook,
|
.write_cache_pages_lock_hook = btree_lock_page_hook,
|
||||||
.readpage_end_io_hook = btree_readpage_end_io_hook,
|
.readpage_end_io_hook = btree_readpage_end_io_hook,
|
||||||
|
.readpage_io_failed_hook = btree_io_failed_hook,
|
||||||
.submit_bio_hook = btree_submit_bio_hook,
|
.submit_bio_hook = btree_submit_bio_hook,
|
||||||
/* note we're sharing with inode.c for the merge bio hook */
|
/* note we're sharing with inode.c for the merge bio hook */
|
||||||
.merge_bio_hook = btrfs_merge_bio_hook,
|
.merge_bio_hook = btrfs_merge_bio_hook,
|
||||||
|
|
|
@ -1731,7 +1731,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
|
||||||
if (!uptodate && tree->ops &&
|
if (!uptodate && tree->ops &&
|
||||||
tree->ops->readpage_io_failed_hook) {
|
tree->ops->readpage_io_failed_hook) {
|
||||||
ret = tree->ops->readpage_io_failed_hook(bio, page,
|
ret = tree->ops->readpage_io_failed_hook(bio, page,
|
||||||
start, end, NULL);
|
start, end, state);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
uptodate =
|
uptodate =
|
||||||
test_bit(BIO_UPTODATE, &bio->bi_flags);
|
test_bit(BIO_UPTODATE, &bio->bi_flags);
|
||||||
|
|
Loading…
Add table
Reference in a new issue