diff options
Diffstat (limited to 'drivers/md/bcache/btree.c')
-rw-r--r-- | drivers/md/bcache/btree.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index be90596a9e2a..4c340c85b122 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -1641,7 +1641,7 @@ static void btree_gc_start(struct cache_set *c) | |||
1641 | mutex_unlock(&c->bucket_lock); | 1641 | mutex_unlock(&c->bucket_lock); |
1642 | } | 1642 | } |
1643 | 1643 | ||
1644 | size_t bch_btree_gc_finish(struct cache_set *c) | 1644 | static size_t bch_btree_gc_finish(struct cache_set *c) |
1645 | { | 1645 | { |
1646 | size_t available = 0; | 1646 | size_t available = 0; |
1647 | struct bucket *b; | 1647 | struct bucket *b; |
@@ -1703,9 +1703,6 @@ size_t bch_btree_gc_finish(struct cache_set *c) | |||
1703 | 1703 | ||
1704 | if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) | 1704 | if (!GC_MARK(b) || GC_MARK(b) == GC_MARK_RECLAIMABLE) |
1705 | available++; | 1705 | available++; |
1706 | |||
1707 | if (!GC_MARK(b)) | ||
1708 | bch_bucket_add_unused(ca, b); | ||
1709 | } | 1706 | } |
1710 | } | 1707 | } |
1711 | 1708 | ||
@@ -1836,6 +1833,42 @@ int bch_btree_check(struct cache_set *c) | |||
1836 | return btree_root(check_recurse, c, &op); | 1833 | return btree_root(check_recurse, c, &op); |
1837 | } | 1834 | } |
1838 | 1835 | ||
1836 | void bch_initial_gc_finish(struct cache_set *c) | ||
1837 | { | ||
1838 | struct cache *ca; | ||
1839 | struct bucket *b; | ||
1840 | unsigned i; | ||
1841 | |||
1842 | bch_btree_gc_finish(c); | ||
1843 | |||
1844 | mutex_lock(&c->bucket_lock); | ||
1845 | |||
1846 | /* | ||
1847 | * We need to put some unused buckets directly on the prio freelist in | ||
1848 | * order to get the allocator thread started - it needs freed buckets in | ||
1849 | * order to rewrite the prios and gens, and it needs to rewrite prios | ||
1850 | * and gens in order to free buckets. | ||
1851 | * | ||
1852 | * This is only safe for buckets that have no live data in them, which | ||
1853 | * there should always be some of. | ||
1854 | */ | ||
1855 | for_each_cache(ca, c, i) { | ||
1856 | for_each_bucket(b, ca) { | ||
1857 | if (fifo_full(&ca->free[RESERVE_PRIO])) | ||
1858 | break; | ||
1859 | |||
1860 | if (bch_can_invalidate_bucket(ca, b) && | ||
1861 | !GC_MARK(b)) { | ||
1862 | __bch_invalidate_one_bucket(ca, b); | ||
1863 | fifo_push(&ca->free[RESERVE_PRIO], | ||
1864 | b - ca->buckets); | ||
1865 | } | ||
1866 | } | ||
1867 | } | ||
1868 | |||
1869 | mutex_unlock(&c->bucket_lock); | ||
1870 | } | ||
1871 | |||
1839 | /* Btree insertion */ | 1872 | /* Btree insertion */ |
1840 | 1873 | ||
1841 | static bool btree_insert_key(struct btree *b, struct bkey *k, | 1874 | static bool btree_insert_key(struct btree *b, struct bkey *k, |