summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-11 17:46:58 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-05-11 17:56:08 -0400
commit24a2cb228bf4aa7cfa9ace47379d193727347bbb (patch)
treeb66d27a188f72ff4ba27500c8ed0677db918a6aa
parenta29d753c13062aa4a3739f10db400d3baa40504e (diff)
bcachefs: fix creation of unneeded crc entries
bch2_alloc_sectors_append_ptrs() doesn't use bch2_extent_ptr_decoded_append(), which is smarter about creating crc entries.
-rw-r--r--fs/bcachefs/extents.c7
-rw-r--r--fs/bcachefs/io.c31
2 files changed, 27 insertions, 11 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 72f28e427b78..b3e4286a2001 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -1429,10 +1429,15 @@ static inline void __extent_entry_insert(struct bkey_i_extent *e,
void bch2_extent_ptr_decoded_append(struct bkey_i_extent *e,
struct extent_ptr_decoded *p)
{
- struct bch_extent_crc_unpacked crc;
+ struct bch_extent_crc_unpacked crc = bch2_extent_crc_unpack(&e->k, NULL);
union bch_extent_entry *pos;
unsigned i;
+ if (!bch2_crc_unpacked_cmp(crc, p->crc)) {
+ pos = e->v.start;
+ goto found;
+ }
+
extent_for_each_crc(extent_i_to_s(e), crc, pos)
if (!bch2_crc_unpacked_cmp(crc, p->crc)) {
pos = extent_entry_next(pos);
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c
index 5df690f9afe4..db3298a74613 100644
--- a/fs/bcachefs/io.c
+++ b/fs/bcachefs/io.c
@@ -432,21 +432,32 @@ static void init_append_extent(struct bch_write_op *op,
struct bversion version,
struct bch_extent_crc_unpacked crc)
{
+ struct bch_fs *c = op->c;
struct bkey_i_extent *e = bkey_extent_init(op->insert_keys.top);
- struct bch_extent_ptr *ptr;
+ struct extent_ptr_decoded p = { .crc = crc };
+ struct open_bucket *ob;
+ unsigned i;
op->pos.offset += crc.uncompressed_size;
- e->k.p = op->pos;
- e->k.size = crc.uncompressed_size;
- e->k.version = version;
+ e->k.p = op->pos;
+ e->k.size = crc.uncompressed_size;
+ e->k.version = version;
- bch2_extent_crc_append(e, crc);
- bch2_alloc_sectors_append_ptrs(op->c, wp, &e->k_i,
- crc.compressed_size);
+ BUG_ON(crc.compressed_size > wp->sectors_free);
+ wp->sectors_free -= crc.compressed_size;
- if (op->flags & BCH_WRITE_CACHED)
- extent_for_each_ptr(extent_i_to_s(e), ptr)
- ptr->cached = true;
+ open_bucket_for_each(c, &wp->ptrs, ob, i) {
+ struct bch_dev *ca = bch_dev_bkey_exists(c, ob->ptr.dev);
+
+ p.ptr = ob->ptr;
+ p.ptr.cached = !ca->mi.durability ||
+ (op->flags & BCH_WRITE_CACHED) != 0;
+ p.ptr.offset += ca->mi.bucket_size - ob->sectors_free;
+ bch2_extent_ptr_decoded_append(e, &p);
+
+ BUG_ON(crc.compressed_size > ob->sectors_free);
+ ob->sectors_free -= crc.compressed_size;
+ }
bch2_keylist_push(&op->insert_keys);
}