summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/extents.c42
-rw-r--r--drivers/md/bcache/io.c3
-rw-r--r--drivers/md/bcache/move.c6
3 files changed, 26 insertions, 25 deletions
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c
index 6af7d34cee88..6e92e3e82743 100644
--- a/drivers/md/bcache/extents.c
+++ b/drivers/md/bcache/extents.c
@@ -1376,32 +1376,24 @@ bool bch_extent_normalize(struct cache_set *c, struct bkey *k)
bool cached;
switch (k->type) {
- case KEY_TYPE_DELETED:
case KEY_TYPE_ERROR:
- break;
-
- case KEY_TYPE_DISCARD:
- if (!k->version)
- set_bkey_deleted(k);
- break;
+ return false;
+ case KEY_TYPE_DELETED:
case KEY_TYPE_COOKIE:
- set_bkey_deleted(k);
- break;
+ return true;
+
+ case KEY_TYPE_DISCARD:
+ return !k->version;
case BCH_EXTENT:
e = bkey_i_to_extent(k);
- if (!e->k.size) {
- set_bkey_deleted(&e->k);
- return true;
- }
-
/*
* Preserve cached status since its stored in the
* first pointer
*/
- cached = EXTENT_CACHED(&e->v);
+ cached = bch_extent_ptrs(e) && EXTENT_CACHED(&e->v);
bch_extent_drop_stale(c, &e->k);
@@ -1425,20 +1417,24 @@ bool bch_extent_normalize(struct cache_set *c, struct bkey *k)
if (PTR_DEV(ptr) != PTR_LOST_DEV)
have_data = true;
- if (!have_data)
+ if (!have_data) {
bch_set_extent_ptrs(e, 0);
-
- if (!bch_extent_ptrs(e))
- k->type = KEY_TYPE_DELETED;
- else
+ if (cached) {
+ k->type = KEY_TYPE_DISCARD;
+ if (!k->version)
+ return true;
+ } else {
+ k->type = KEY_TYPE_ERROR;
+ }
+ } else {
SET_EXTENT_CACHED(&e->v, cached);
+ }
- break;
+ return false;
default:
BUG();
+ return false;
}
-
- return bkey_deleted(k);
}
/*
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index cbaa60c3e762..139686e45090 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -475,7 +475,8 @@ static void __bch_write(struct closure *cl)
bio_set_op_attrs(n, REQ_OP_WRITE, 0);
bch_submit_bbio_replicas(n, op->c, k, ptrs_from, false);
- bch_extent_normalize(op->c, k);
+ BUG_ON(bch_extent_normalize(op->c, k));
+
bch_check_mark_super(op->c, k, false);
/*
diff --git a/drivers/md/bcache/move.c b/drivers/md/bcache/move.c
index 5503a461c573..3eff18c5845a 100644
--- a/drivers/md/bcache/move.c
+++ b/drivers/md/bcache/move.c
@@ -1188,7 +1188,11 @@ static int bch_flag_key_bad(struct btree_iter *iter,
* bch_extent_normalize() needs to know how to turn a key with only
* pointers to PTR_LOST_DEV into a KEY_BAD() key anyways - because we
* might have a cached pointer that will go stale later - so just call
- * it here:
+ * it here.
+ *
+ * If the key was cached, we may have dropped all pointers above --
+ * in this case, bch_extent_normalize() will change the key type to
+ * DISCARD.
*/
bch_extent_normalize(c, &e->k);