Commit 9aa61a992acceeec0d1de2cd99938421498659d5

Authored by Kent Overstreet
1 parent 5b1016e62f

bcache: Fix a journal replay bug

journal replay wansn't validating pointers with bch_extent_invalid() before
derefing, fixed

Signed-off-by: Kent Overstreet <kmo@daterainc.com>

Showing 3 changed files with 19 additions and 11 deletions Side-by-side Diff

drivers/md/bcache/extents.c
... ... @@ -474,9 +474,8 @@
474 474 return false;
475 475 }
476 476  
477   -static bool bch_extent_invalid(struct btree_keys *bk, const struct bkey *k)
  477 +bool __bch_extent_invalid(struct cache_set *c, const struct bkey *k)
478 478 {
479   - struct btree *b = container_of(bk, struct btree, keys);
480 479 char buf[80];
481 480  
482 481 if (!KEY_SIZE(k))
483 482  
484 483  
... ... @@ -485,14 +484,20 @@
485 484 if (KEY_SIZE(k) > KEY_OFFSET(k))
486 485 goto bad;
487 486  
488   - if (__ptr_invalid(b->c, k))
  487 + if (__ptr_invalid(c, k))
489 488 goto bad;
490 489  
491 490 return false;
492 491 bad:
493 492 bch_extent_to_text(buf, sizeof(buf), k);
494   - cache_bug(b->c, "spotted extent %s: %s", buf, bch_ptr_status(b->c, k));
  493 + cache_bug(c, "spotted extent %s: %s", buf, bch_ptr_status(c, k));
495 494 return true;
  495 +}
  496 +
  497 +static bool bch_extent_invalid(struct btree_keys *bk, const struct bkey *k)
  498 +{
  499 + struct btree *b = container_of(bk, struct btree, keys);
  500 + return __bch_extent_invalid(b->c, k);
496 501 }
497 502  
498 503 static bool bch_extent_bad_expensive(struct btree *b, const struct bkey *k,
drivers/md/bcache/extents.h
... ... @@ -9,6 +9,7 @@
9 9  
10 10 void bch_extent_to_text(char *, size_t, const struct bkey *);
11 11 bool __bch_btree_ptr_invalid(struct cache_set *, const struct bkey *);
  12 +bool __bch_extent_invalid(struct cache_set *, const struct bkey *);
12 13  
13 14 #endif /* _BCACHE_EXTENTS_H */
drivers/md/bcache/journal.c
... ... @@ -7,6 +7,7 @@
7 7 #include "bcache.h"
8 8 #include "btree.h"
9 9 #include "debug.h"
  10 +#include "extents.h"
10 11  
11 12 #include <trace/events/bcache.h>
12 13  
13 14  
14 15  
... ... @@ -291,15 +292,16 @@
291 292  
292 293 for (k = i->j.start;
293 294 k < bset_bkey_last(&i->j);
294   - k = bkey_next(k)) {
295   - unsigned j;
  295 + k = bkey_next(k))
  296 + if (!__bch_extent_invalid(c, k)) {
  297 + unsigned j;
296 298  
297   - for (j = 0; j < KEY_PTRS(k); j++)
298   - if (ptr_available(c, k, j))
299   - atomic_inc(&PTR_BUCKET(c, k, j)->pin);
  299 + for (j = 0; j < KEY_PTRS(k); j++)
  300 + if (ptr_available(c, k, j))
  301 + atomic_inc(&PTR_BUCKET(c, k, j)->pin);
300 302  
301   - bch_initial_mark_key(c, 0, k);
302   - }
  303 + bch_initial_mark_key(c, 0, k);
  304 + }
303 305 }
304 306 }
305 307