diff options
Diffstat (limited to 'drivers/md/bcache/bset.c')
-rw-r--r-- | drivers/md/bcache/bset.c | 49 |
1 files changed, 36 insertions, 13 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 | ||