static const char *bch_ptr_status(struct cache_set *c, const struct bkey *k) { unsigned i; for (i = 0; i < KEY_PTRS(k); i++) if (ptr_available(c, k, i)) { struct cache *ca = PTR_CACHE(c, k, i); size_t bucket = PTR_BUCKET_NR(c, k, i); size_t r = bucket_remainder(c, PTR_OFFSET(k, i)); if (KEY_SIZE(k) + r > c->sb.bucket_size) return "bad, length too big"; if (bucket < ca->sb.first_bucket) return "bad, short offset"; if (bucket >= ca->sb.nbuckets) return "bad, offset past end of device"; if (ptr_stale(c, k, i)) return "stale"; } if (!bkey_cmp(k, &ZERO_KEY)) return "bad, null key"; if (!KEY_PTRS(k)) return "bad, no pointers"; if (!KEY_SIZE(k)) return "zeroed key"; return ""; }
void bch_bucket_free(struct cache_set *c, struct bkey *k) { unsigned i; for (i = 0; i < KEY_PTRS(k); i++) __bch_bucket_free(PTR_CACHE(c, k, i), PTR_BUCKET(c, k, i)); }
void bch_bucket_free(struct cache_set *c, struct bkey *k) { unsigned i; for (i = 0; i < KEY_PTRS(k); i++) { struct bucket *b = PTR_BUCKET(c, k, i); SET_GC_MARK(b, GC_MARK_RECLAIMABLE); SET_GC_SECTORS_USED(b, 0); bch_bucket_add_unused(PTR_CACHE(c, k, i), b); } }
static bool __ptr_invalid(struct cache_set *c, const struct bkey *k) { unsigned i; for (i = 0; i < KEY_PTRS(k); i++) if (ptr_available(c, k, i)) { struct cache *ca = PTR_CACHE(c, k, i); size_t bucket = PTR_BUCKET_NR(c, k, i); size_t r = bucket_remainder(c, PTR_OFFSET(k, i)); if (KEY_SIZE(k) + r > c->sb.bucket_size || bucket < ca->sb.first_bucket || bucket >= ca->sb.nbuckets) return true; } return false; }