]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/util.c
Update bcachefs sources to 1569db10e2 bcachefs: Use KEY_TYPE_deleted whitouts for...
[bcachefs-tools-debian] / libbcachefs / util.c
index 5c060e77fe0fef0cdb24f8381e8a12fe19dbcc49..e69d03d1109ff0cf4cd3acb1ecc886b65c5e3a4c 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * random utiility code, for bcache but in theory not specific to bcache
  *
@@ -133,6 +134,7 @@ void bch2_flags_to_text(struct printbuf *out,
                        const char * const list[], u64 flags)
 {
        unsigned bit, nr = 0;
+       bool first = true;
 
        if (out->pos != out->end)
                *out->pos = '\0';
@@ -141,7 +143,10 @@ void bch2_flags_to_text(struct printbuf *out,
                nr++;
 
        while (flags && (bit = __ffs(flags)) < nr) {
-               pr_buf(out, "%s,", list[bit]);
+               if (!first)
+                       pr_buf(out, ",");
+               first = false;
+               pr_buf(out, "%s", list[bit]);
                flags ^= 1 << bit;
        }
 }
@@ -499,48 +504,32 @@ size_t bch2_pd_controller_print_debug(struct bch_pd_controller *pd, char *buf)
 
 /* misc: */
 
-void bch2_bio_map(struct bio *bio, void *base)
+void bch2_bio_map(struct bio *bio, void *base, size_t size)
 {
-       size_t size = bio->bi_iter.bi_size;
-       struct bio_vec *bv = bio->bi_io_vec;
-
-       BUG_ON(!bio->bi_iter.bi_size);
-       BUG_ON(bio->bi_vcnt);
-       BUG_ON(!bio->bi_max_vecs);
-
-       bv->bv_offset = base ? offset_in_page(base) : 0;
-       goto start;
-
-       for (; size; bio->bi_vcnt++, bv++) {
-               BUG_ON(bio->bi_vcnt >= bio->bi_max_vecs);
-
-               bv->bv_offset   = 0;
-start:         bv->bv_len      = min_t(size_t, PAGE_SIZE - bv->bv_offset,
-                                       size);
-               if (base) {
-                       bv->bv_page = is_vmalloc_addr(base)
+       while (size) {
+               struct page *page = is_vmalloc_addr(base)
                                ? vmalloc_to_page(base)
                                : virt_to_page(base);
+               unsigned offset = offset_in_page(base);
+               unsigned len = min_t(size_t, PAGE_SIZE - offset, size);
 
-                       base += bv->bv_len;
-               }
-
-               size -= bv->bv_len;
+               BUG_ON(!bio_add_page(bio, page, len, offset));
+               size -= len;
+               base += len;
        }
 }
 
-int bch2_bio_alloc_pages(struct bio *bio, gfp_t gfp_mask)
+int bch2_bio_alloc_pages(struct bio *bio, size_t size, gfp_t gfp_mask)
 {
-       int i;
-       struct bio_vec *bv;
+       while (size) {
+               struct page *page = alloc_page(gfp_mask);
+               unsigned len = min(PAGE_SIZE, size);
 
-       bio_for_each_segment_all(bv, bio, i) {
-               bv->bv_page = alloc_page(gfp_mask);
-               if (!bv->bv_page) {
-                       while (--bv >= bio->bi_io_vec)
-                               __free_page(bv->bv_page);
+               if (!page)
                        return -ENOMEM;
-               }
+
+               BUG_ON(!bio_add_page(bio, page, len, 0));
+               size -= len;
        }
 
        return 0;
@@ -561,7 +550,7 @@ size_t bch2_rand_range(size_t max)
        return rand;
 }
 
-void memcpy_to_bio(struct bio *dst, struct bvec_iter dst_iter, void *src)
+void memcpy_to_bio(struct bio *dst, struct bvec_iter dst_iter, const void *src)
 {
        struct bio_vec bv;
        struct bvec_iter iter;
@@ -894,3 +883,28 @@ void eytzinger0_find_test(void)
        kfree(test_array);
 }
 #endif
+
+/*
+ * Accumulate percpu counters onto one cpu's copy - only valid when access
+ * against any percpu counter is guarded against
+ */
+u64 *bch2_acc_percpu_u64s(u64 __percpu *p, unsigned nr)
+{
+       u64 *ret;
+       int cpu;
+
+       preempt_disable();
+       ret = this_cpu_ptr(p);
+       preempt_enable();
+
+       for_each_possible_cpu(cpu) {
+               u64 *i = per_cpu_ptr(p, cpu);
+
+               if (i != ret) {
+                       acc_u64s(ret, i, nr);
+                       memset(i, 0, nr * sizeof(u64));
+               }
+       }
+
+       return ret;
+}