summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-09-27 21:08:39 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-11-01 15:13:08 -0400
commit76fef698480bab60ccaf3ee34611e1fa99a0d1a1 (patch)
tree9391752a4e83f1442c3f8dab5594d3adb91fedc1 /fs
parenta0665c1d6485ca0a40442f9c72777970f2ab4252 (diff)
bcachefs: bch2_extent_ptr_decoded_append()
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/extents.c112
-rw-r--r--fs/bcachefs/extents.h21
-rw-r--r--fs/bcachefs/move.c3
3 files changed, 45 insertions, 91 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 119feb201162..400570331136 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -332,36 +332,36 @@ bool bch2_extent_narrow_crcs(struct bkey_i_extent *e,
struct bch_extent_crc_unpacked u;
struct extent_ptr_decoded p;
union bch_extent_entry *i;
+ bool ret = false;
/* Find a checksum entry that covers only live data: */
- if (!n.csum_type)
+ if (!n.csum_type) {
extent_for_each_crc(extent_i_to_s(e), u, i)
if (!u.compression_type &&
u.csum_type &&
u.live_size == u.uncompressed_size) {
n = u;
- break;
+ goto found;
}
-
- if (!bch2_can_narrow_extent_crcs(extent_i_to_s_c(e), n))
return false;
-
+ }
+found:
BUG_ON(n.compression_type);
BUG_ON(n.offset);
BUG_ON(n.live_size != e->k.size);
- bch2_extent_crc_append(e, n);
restart_narrow_pointers:
extent_for_each_ptr_decode(extent_i_to_s(e), p, i)
if (can_narrow_crc(p.crc, n)) {
- i->ptr.offset += p.crc.offset;
- extent_ptr_append(e, i->ptr);
bch2_extent_drop_ptr(extent_i_to_s(e), &i->ptr);
+ p.ptr.offset += p.crc.offset;
+ p.crc = n;
+ bch2_extent_ptr_decoded_append(e, &p);
+ ret = true;
goto restart_narrow_pointers;
}
- bch2_extent_drop_redundant_crcs(extent_i_to_s(e));
- return true;
+ return ret;
}
/* returns true if not equal */
@@ -378,66 +378,6 @@ static inline bool bch2_crc_unpacked_cmp(struct bch_extent_crc_unpacked l,
bch2_crc_cmp(l.csum, r.csum));
}
-void bch2_extent_drop_redundant_crcs(struct bkey_s_extent e)
-{
- union bch_extent_entry *entry = e.v->start;
- union bch_extent_crc *crc, *prev = NULL;
- struct bch_extent_crc_unpacked u, prev_u = { 0 };
-
- while (entry != extent_entry_last(e)) {
- union bch_extent_entry *next = extent_entry_next(entry);
- size_t crc_u64s = extent_entry_u64s(entry);
-
- if (!extent_entry_is_crc(entry))
- goto next;
-
- crc = entry_to_crc(entry);
- u = bch2_extent_crc_unpack(e.k, crc);
-
- if (next == extent_entry_last(e)) {
- /* crc entry with no pointers after it: */
- goto drop;
- }
-
- if (extent_entry_is_crc(next)) {
- /* no pointers before next crc entry: */
- goto drop;
- }
-
- if (prev && !bch2_crc_unpacked_cmp(u, prev_u)) {
- /* identical to previous crc entry: */
- goto drop;
- }
-
- if (!prev &&
- !u.csum_type &&
- !u.compression_type) {
- /* null crc entry: */
- union bch_extent_entry *e2;
-
- extent_for_each_entry_from(e, e2, extent_entry_next(entry)) {
- if (!extent_entry_is_ptr(e2))
- break;
-
- e2->ptr.offset += u.offset;
- }
- goto drop;
- }
-
- prev = crc;
- prev_u = u;
-next:
- entry = next;
- continue;
-drop:
- memmove_u64s_down(crc, next,
- (u64 *) extent_entry_last(e) - (u64 *) next);
- e.k->u64s -= crc_u64s;
- }
-
- EBUG_ON(bkey_val_u64s(e.k) && !bch2_extent_nr_ptrs(e.c));
-}
-
static void bch2_extent_drop_stale(struct bch_fs *c, struct bkey_s_extent e)
{
struct bch_extent_ptr *ptr;
@@ -1846,25 +1786,25 @@ static void bch2_extent_crc_init(union bch_extent_crc *crc,
void bch2_extent_crc_append(struct bkey_i_extent *e,
struct bch_extent_crc_unpacked new)
{
- struct bch_extent_crc_unpacked crc;
- const union bch_extent_entry *i;
-
- BUG_ON(new.compressed_size > new.uncompressed_size);
- BUG_ON(new.live_size != e->k.size);
- BUG_ON(!new.compressed_size || !new.uncompressed_size);
+ bch2_extent_crc_init((void *) extent_entry_last(extent_i_to_s(e)), new);
+ __extent_entry_push(e);
+}
- /*
- * Look up the last crc entry, so we can check if we need to add
- * another:
- */
- extent_for_each_crc(extent_i_to_s(e), crc, i)
- ;
+void bch2_extent_ptr_decoded_append(struct bkey_i_extent *e,
+ struct extent_ptr_decoded *p)
+{
+ struct bch_extent_crc_unpacked crc;
+ union bch_extent_entry *pos;
- if (!bch2_crc_unpacked_cmp(crc, new))
- return;
+ extent_for_each_crc(extent_i_to_s(e), crc, pos)
+ if (!bch2_crc_unpacked_cmp(crc, p->crc))
+ goto found;
- bch2_extent_crc_init((void *) extent_entry_last(extent_i_to_s(e)), new);
- __extent_entry_push(e);
+ bch2_extent_crc_append(e, p->crc);
+ pos = extent_entry_last(extent_i_to_s(e));
+found:
+ p->ptr.type = 1 << BCH_EXTENT_ENTRY_ptr;
+ __extent_entry_insert(e, pos, to_entry(&p->ptr));
}
/*
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
index cbb599c47370..2c7045f3f538 100644
--- a/fs/bcachefs/extents.h
+++ b/fs/bcachefs/extents.h
@@ -212,11 +212,13 @@ union bch_extent_crc {
#define to_entry(_entry) \
({ \
BUILD_BUG_ON(!type_is(_entry, union bch_extent_crc *) && \
- !type_is(_entry, struct bch_extent_ptr *)); \
+ !type_is(_entry, struct bch_extent_ptr *) && \
+ !type_is(_entry, struct bch_extent_stripe_ptr *)); \
\
__builtin_choose_expr( \
(type_is_exact(_entry, const union bch_extent_crc *) || \
- type_is_exact(_entry, const struct bch_extent_ptr *)), \
+ type_is_exact(_entry, const struct bch_extent_ptr *) ||\
+ type_is_exact(_entry, const struct bch_extent_stripe_ptr *)),\
(const union bch_extent_entry *) (_entry), \
(union bch_extent_entry *) (_entry)); \
})
@@ -401,6 +403,20 @@ out: \
void bch2_extent_crc_append(struct bkey_i_extent *,
struct bch_extent_crc_unpacked);
+void bch2_extent_ptr_decoded_append(struct bkey_i_extent *,
+ struct extent_ptr_decoded *);
+
+static inline void __extent_entry_insert(struct bkey_i_extent *e,
+ union bch_extent_entry *dst,
+ union bch_extent_entry *new)
+{
+ union bch_extent_entry *end = extent_entry_last(extent_i_to_s(e));
+
+ memmove_u64s_up((u64 *) dst + extent_entry_u64s(new),
+ dst, (u64 *) end - (u64 *) dst);
+ e->k.u64s += extent_entry_u64s(new);
+ memcpy(dst, new, extent_entry_bytes(new));
+}
static inline void __extent_entry_push(struct bkey_i_extent *e)
{
@@ -491,7 +507,6 @@ static inline struct bch_devs_list bch2_bkey_cached_devs(struct bkey_s_c k)
bool bch2_can_narrow_extent_crcs(struct bkey_s_c_extent,
struct bch_extent_crc_unpacked);
bool bch2_extent_narrow_crcs(struct bkey_i_extent *, struct bch_extent_crc_unpacked);
-void bch2_extent_drop_redundant_crcs(struct bkey_s_extent);
union bch_extent_entry *bch2_extent_drop_ptr(struct bkey_s_extent ,
struct bch_extent_ptr *);
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index b5c117be2320..a6b044de0dab 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -112,8 +112,7 @@ static int bch2_migrate_index_update(struct bch_write_op *op)
continue;
}
- bch2_extent_crc_append(insert, p.crc);
- extent_ptr_append(insert, p.ptr);
+ bch2_extent_ptr_decoded_append(insert, &p);
did_work = true;
}