diff options
Diffstat (limited to 'drivers/md/bcache')
-rw-r--r-- | drivers/md/bcache/bset.c | 49 | ||||
-rw-r--r-- | drivers/md/bcache/bset.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/btree.h | 13 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 4 |
4 files changed, 49 insertions, 21 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 6bffde478926..b615348c45fc 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
@@ -73,19 +73,9 @@ void bch_keylist_pop_front(struct keylist *l) | |||
73 | 73 | ||
74 | /* Pointer validation */ | 74 | /* Pointer validation */ |
75 | 75 | ||
76 | bool __bch_ptr_invalid(struct cache_set *c, int level, const struct bkey *k) | 76 | static bool __ptr_invalid(struct cache_set *c, const struct bkey *k) |
77 | { | 77 | { |
78 | unsigned i; | 78 | unsigned i; |
79 | char buf[80]; | ||
80 | |||
81 | if (level && (!KEY_PTRS(k) || !KEY_SIZE(k) || KEY_DIRTY(k))) | ||
82 | goto bad; | ||
83 | |||
84 | if (!level && KEY_SIZE(k) > KEY_OFFSET(k)) | ||
85 | goto bad; | ||
86 | |||
87 | if (!KEY_SIZE(k)) | ||
88 | return true; | ||
89 | 79 | ||
90 | for (i = 0; i < KEY_PTRS(k); i++) | 80 | for (i = 0; i < KEY_PTRS(k); i++) |
91 | if (ptr_available(c, k, i)) { | 81 | if (ptr_available(c, k, i)) { |
@@ -96,13 +86,46 @@ bool __bch_ptr_invalid(struct cache_set *c, int level, const struct bkey *k) | |||
96 | if (KEY_SIZE(k) + r > c->sb.bucket_size || | 86 | if (KEY_SIZE(k) + r > c->sb.bucket_size || |
97 | bucket < ca->sb.first_bucket || | 87 | bucket < ca->sb.first_bucket || |
98 | bucket >= ca->sb.nbuckets) | 88 | bucket >= ca->sb.nbuckets) |
99 | goto bad; | 89 | return true; |
100 | } | 90 | } |
101 | 91 | ||
102 | return false; | 92 | return false; |
93 | } | ||
94 | |||
95 | bool bch_btree_ptr_invalid(struct cache_set *c, const struct bkey *k) | ||
96 | { | ||
97 | char buf[80]; | ||
98 | |||
99 | if (!KEY_PTRS(k) || !KEY_SIZE(k) || KEY_DIRTY(k)) | ||
100 | goto bad; | ||
101 | |||
102 | if (__ptr_invalid(c, k)) | ||
103 | goto bad; | ||
104 | |||
105 | return false; | ||
106 | bad: | ||
107 | bch_bkey_to_text(buf, sizeof(buf), k); | ||
108 | cache_bug(c, "spotted btree ptr %s: %s", buf, bch_ptr_status(c, k)); | ||
109 | return true; | ||
110 | } | ||
111 | |||
112 | bool bch_extent_ptr_invalid(struct cache_set *c, const struct bkey *k) | ||
113 | { | ||
114 | char buf[80]; | ||
115 | |||
116 | if (!KEY_SIZE(k)) | ||
117 | return true; | ||
118 | |||
119 | if (KEY_SIZE(k) > KEY_OFFSET(k)) | ||
120 | goto bad; | ||
121 | |||
122 | if (__ptr_invalid(c, k)) | ||
123 | goto bad; | ||
124 | |||
125 | return false; | ||
103 | bad: | 126 | bad: |
104 | bch_bkey_to_text(buf, sizeof(buf), k); | 127 | bch_bkey_to_text(buf, sizeof(buf), k); |
105 | cache_bug(c, "spotted bad key %s: %s", buf, bch_ptr_status(c, k)); | 128 | cache_bug(c, "spotted extent %s: %s", buf, bch_ptr_status(c, k)); |
106 | return true; | 129 | return true; |
107 | } | 130 | } |
108 | 131 | ||
diff --git a/drivers/md/bcache/bset.h b/drivers/md/bcache/bset.h index a043a92d4dc9..e67386001814 100644 --- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h | |||
@@ -277,7 +277,9 @@ static inline bool bch_cut_back(const struct bkey *where, struct bkey *k) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | const char *bch_ptr_status(struct cache_set *, const struct bkey *); | 279 | const char *bch_ptr_status(struct cache_set *, const struct bkey *); |
280 | bool __bch_ptr_invalid(struct cache_set *, int level, const struct bkey *); | 280 | bool bch_btree_ptr_invalid(struct cache_set *, const struct bkey *); |
281 | bool bch_extent_ptr_invalid(struct cache_set *, const struct bkey *); | ||
282 | |||
281 | bool bch_ptr_bad(struct btree *, const struct bkey *); | 283 | bool bch_ptr_bad(struct btree *, const struct bkey *); |
282 | 284 | ||
283 | static inline uint8_t gen_after(uint8_t a, uint8_t b) | 285 | static inline uint8_t gen_after(uint8_t a, uint8_t b) |
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index d4b705eeec24..e11bb8571d24 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h | |||
@@ -204,11 +204,6 @@ static inline void set_gc_sectors(struct cache_set *c) | |||
204 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 8); | 204 | atomic_set(&c->sectors_to_gc, c->sb.bucket_size * c->nbuckets / 8); |
205 | } | 205 | } |
206 | 206 | ||
207 | static inline bool bch_ptr_invalid(struct btree *b, const struct bkey *k) | ||
208 | { | ||
209 | return __bch_ptr_invalid(b->c, b->level, k); | ||
210 | } | ||
211 | |||
212 | static inline struct bkey *bch_btree_iter_init(struct btree *b, | 207 | static inline struct bkey *bch_btree_iter_init(struct btree *b, |
213 | struct btree_iter *iter, | 208 | struct btree_iter *iter, |
214 | struct bkey *search) | 209 | struct bkey *search) |
@@ -216,6 +211,14 @@ static inline struct bkey *bch_btree_iter_init(struct btree *b, | |||
216 | return __bch_btree_iter_init(b, iter, search, b->sets); | 211 | return __bch_btree_iter_init(b, iter, search, b->sets); |
217 | } | 212 | } |
218 | 213 | ||
214 | static inline bool bch_ptr_invalid(struct btree *b, const struct bkey *k) | ||
215 | { | ||
216 | if (b->level) | ||
217 | return bch_btree_ptr_invalid(b->c, k); | ||
218 | else | ||
219 | return bch_extent_ptr_invalid(b->c, k); | ||
220 | } | ||
221 | |||
219 | void bkey_put(struct cache_set *c, struct bkey *k); | 222 | void bkey_put(struct cache_set *c, struct bkey *k); |
220 | 223 | ||
221 | /* Looping macros */ | 224 | /* Looping macros */ |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 05f8ccb9f8ca..7ab926d94d81 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -373,7 +373,7 @@ static char *uuid_read(struct cache_set *c, struct jset *j, struct closure *cl) | |||
373 | { | 373 | { |
374 | struct bkey *k = &j->uuid_bucket; | 374 | struct bkey *k = &j->uuid_bucket; |
375 | 375 | ||
376 | if (__bch_ptr_invalid(c, 1, k)) | 376 | if (bch_btree_ptr_invalid(c, k)) |
377 | return "bad uuid pointer"; | 377 | return "bad uuid pointer"; |
378 | 378 | ||
379 | bkey_copy(&c->uuid_bucket, k); | 379 | bkey_copy(&c->uuid_bucket, k); |
@@ -1522,7 +1522,7 @@ static void run_cache_set(struct cache_set *c) | |||
1522 | k = &j->btree_root; | 1522 | k = &j->btree_root; |
1523 | 1523 | ||
1524 | err = "bad btree root"; | 1524 | err = "bad btree root"; |
1525 | if (__bch_ptr_invalid(c, j->btree_level + 1, k)) | 1525 | if (bch_btree_ptr_invalid(c, k)) |
1526 | goto err; | 1526 | goto err; |
1527 | 1527 | ||
1528 | err = "error reading btree root"; | 1528 | err = "error reading btree root"; |