summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-04-25 16:25:07 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:36:20 -0800
commita671023bafbcd2355812c8e7ad1978f4787a2217 (patch)
treeaebd68249b12da4ffc3c4164d4899b49ce5f8ddb
parent9f98ff481e9e6231955251fee0dfa890b2bb54ad (diff)
bcache: fix a bucket marking thing with cached data
-rw-r--r--drivers/md/bcache/buckets.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/md/bcache/buckets.c b/drivers/md/bcache/buckets.c
index e075b2d6ca43..fff3577075a6 100644
--- a/drivers/md/bcache/buckets.c
+++ b/drivers/md/bcache/buckets.c
@@ -240,6 +240,18 @@ static struct bucket_mark bch_bucket_mark_set(struct cache *ca,
old.counter = xchg(&g->mark.counter, new.counter);
bucket_stats_update(ca, old, new, may_make_unavailable, &stats);
+
+ /*
+ * Ick:
+ *
+ * Only stats.sectors_cached should be nonzero: this is important
+ * because in this path we modify cache_set_stats based on how the
+ * bucket_mark was modified, and the sector counts in bucket_mark are
+ * subject to (saturating) overflow - and if they did overflow, the
+ * cache set stats will now be off. We can tolerate this for
+ * sectors_cached, but not anything else:
+ * */
+ stats.sectors_cached = 0;
BUG_ON(!bch_is_zero((void *) &stats, sizeof(stats)));
return old;