^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2012 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "dm-array.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "dm-space-map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "dm-transaction-manager.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define DM_MSG_PREFIX "array"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * The array is implemented as a fully populated btree, which points to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * blocks that contain the packed values. This is more space efficient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * than just using a btree since we don't store 1 key per value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct array_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) __le32 csum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __le32 max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __le32 nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __le32 value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) __le64 blocknr; /* Block this node is supposed to live in. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Validator methods. As usual we calculate a checksum, and also write the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * block location into the header (paranoia about ssds remapping areas by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * mistake).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CSUM_XOR 595846735
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static void array_block_prepare_for_write(struct dm_block_validator *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct dm_block *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) size_t size_of_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct array_block *bh_le = dm_block_data(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) bh_le->blocknr = cpu_to_le64(dm_block_location(b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) bh_le->csum = cpu_to_le32(dm_bm_checksum(&bh_le->max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) size_of_block - sizeof(__le32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) CSUM_XOR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static int array_block_check(struct dm_block_validator *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct dm_block *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) size_t size_of_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct array_block *bh_le = dm_block_data(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __le32 csum_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (dm_block_location(b) != le64_to_cpu(bh_le->blocknr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) DMERR_LIMIT("array_block_check failed: blocknr %llu != wanted %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) (unsigned long long) le64_to_cpu(bh_le->blocknr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) (unsigned long long) dm_block_location(b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return -ENOTBLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) csum_disk = cpu_to_le32(dm_bm_checksum(&bh_le->max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) size_of_block - sizeof(__le32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) CSUM_XOR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (csum_disk != bh_le->csum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) DMERR_LIMIT("array_block_check failed: csum %u != wanted %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) (unsigned) le32_to_cpu(csum_disk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) (unsigned) le32_to_cpu(bh_le->csum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct dm_block_validator array_validator = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .name = "array",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .prepare_for_write = array_block_prepare_for_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .check = array_block_check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Functions for manipulating the array blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Returns a pointer to a value within an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * index - The index into _this_ specific block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void *element_at(struct dm_array_info *info, struct array_block *ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) unsigned char *entry = (unsigned char *) (ab + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) entry += index * info->value_type.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Utility function that calls one of the value_type methods on every value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * in an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void on_entries(struct dm_array_info *info, struct array_block *ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) void (*fn)(void *, const void *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned i, nr_entries = le32_to_cpu(ab->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for (i = 0; i < nr_entries; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) fn(info->value_type.context, element_at(info, ab, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Increment every value in an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void inc_ablock_entries(struct dm_array_info *info, struct array_block *ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (vt->inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) on_entries(info, ab, vt->inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * Decrement every value in an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void dec_ablock_entries(struct dm_array_info *info, struct array_block *ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (vt->dec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) on_entries(info, ab, vt->dec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Each array block can hold this many values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static uint32_t calc_max_entries(size_t value_size, size_t size_of_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return (size_of_block - sizeof(struct array_block)) / value_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Allocate a new array block. The caller will need to unlock block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int alloc_ablock(struct dm_array_info *info, size_t size_of_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) uint32_t max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct dm_block **block, struct array_block **ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) r = dm_tm_new_block(info->btree_info.tm, &array_validator, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) (*ab) = dm_block_data(*block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) (*ab)->max_entries = cpu_to_le32(max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) (*ab)->nr_entries = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (*ab)->value_size = cpu_to_le32(info->value_type.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Pad an array block out with a particular value. Every instance will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * cause an increment of the value_type. new_nr must always be more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * the current number of entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void fill_ablock(struct dm_array_info *info, struct array_block *ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) const void *value, unsigned new_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) uint32_t nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) BUG_ON(new_nr > le32_to_cpu(ab->max_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) BUG_ON(new_nr < le32_to_cpu(ab->nr_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) nr_entries = le32_to_cpu(ab->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) for (i = nr_entries; i < new_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (vt->inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) vt->inc(vt->context, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) memcpy(element_at(info, ab, i), value, vt->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ab->nr_entries = cpu_to_le32(new_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Remove some entries from the back of an array block. Every value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * removed will be decremented. new_nr must be <= the current number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void trim_ablock(struct dm_array_info *info, struct array_block *ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned new_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) uint32_t nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) BUG_ON(new_nr > le32_to_cpu(ab->max_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) BUG_ON(new_nr > le32_to_cpu(ab->nr_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) nr_entries = le32_to_cpu(ab->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for (i = nr_entries; i > new_nr; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (vt->dec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) vt->dec(vt->context, element_at(info, ab, i - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ab->nr_entries = cpu_to_le32(new_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * Read locks a block, and coerces it to an array block. The caller must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * unlock 'block' when finished.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int get_ablock(struct dm_array_info *info, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct dm_block **block, struct array_block **ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) r = dm_tm_read_lock(info->btree_info.tm, b, &array_validator, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *ab = dm_block_data(*block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Unlocks an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void unlock_ablock(struct dm_array_info *info, struct dm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dm_tm_unlock(info->btree_info.tm, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Btree manipulation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Looks up an array block in the btree, and then read locks it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * index is the index of the index of the array_block, (ie. the array index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * / max_entries).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int lookup_ablock(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) unsigned index, struct dm_block **block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct array_block **ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) uint64_t key = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) __le64 block_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) r = dm_btree_lookup(&info->btree_info, root, &key, &block_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return get_ablock(info, le64_to_cpu(block_le), block, ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Insert an array block into the btree. The block is _not_ unlocked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int insert_ablock(struct dm_array_info *info, uint64_t index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct dm_block *block, dm_block_t *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) __le64 block_le = cpu_to_le64(dm_block_location(block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) __dm_bless_for_disk(block_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return dm_btree_insert(&info->btree_info, *root, &index, &block_le, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int __shadow_ablock(struct dm_array_info *info, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct dm_block **block, struct array_block **ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int r = dm_tm_shadow_block(info->btree_info.tm, b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) &array_validator, block, &inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) *ab = dm_block_data(*block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) inc_ablock_entries(info, *ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * The shadow op will often be a noop. Only insert if it really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * copied data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int __reinsert_ablock(struct dm_array_info *info, unsigned index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct dm_block *block, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dm_block_t *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (dm_block_location(block) != b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * dm_tm_shadow_block will have already decremented the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * block, but it is still referenced by the btree. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * increment to stop the insert decrementing it below zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * when overwriting the old value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dm_tm_inc(info->btree_info.tm, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) r = insert_ablock(info, index, block, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * Looks up an array block in the btree. Then shadows it, and updates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * btree to point to this new shadow. 'root' is an input/output parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * for both the current root block, and the new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int shadow_ablock(struct dm_array_info *info, dm_block_t *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned index, struct dm_block **block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct array_block **ab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) uint64_t key = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) dm_block_t b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) __le64 block_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) r = dm_btree_lookup(&info->btree_info, *root, &key, &block_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) b = le64_to_cpu(block_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) r = __shadow_ablock(info, b, block, ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return __reinsert_ablock(info, index, *block, b, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * Allocate an new array block, and fill it with some values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int insert_new_ablock(struct dm_array_info *info, size_t size_of_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) uint32_t max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) unsigned block_index, uint32_t nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) const void *value, dm_block_t *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) r = alloc_ablock(info, size_of_block, max_entries, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) fill_ablock(info, ab, value, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) r = insert_ablock(info, block_index, block, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static int insert_full_ablocks(struct dm_array_info *info, size_t size_of_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned begin_block, unsigned end_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned max_entries, const void *value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dm_block_t *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) for (; !r && begin_block != end_block; begin_block++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) r = insert_new_ablock(info, size_of_block, max_entries, begin_block, max_entries, value, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * There are a bunch of functions involved with resizing an array. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * structure holds information that commonly needed by them. Purely here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * to reduce parameter count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct resize {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * Describes the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct dm_array_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * The current root of the array. This gets updated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dm_block_t root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Metadata block size. Used to calculate the nr entries in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) size_t size_of_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * Maximum nr entries in an array block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) unsigned max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * nr of completely full blocks in the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * 'old' refers to before the resize, 'new' after.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned old_nr_full_blocks, new_nr_full_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * Number of entries in the final block. 0 iff only full blocks in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) unsigned old_nr_entries_in_last_block, new_nr_entries_in_last_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * The default value used when growing the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) const void *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * Removes a consecutive set of array blocks from the btree. The values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * in block are decremented as a side effect of the btree remove.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * begin_index - the index of the first array block to remove.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * end_index - the one-past-the-end value. ie. this block is not removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int drop_blocks(struct resize *resize, unsigned begin_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unsigned end_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) while (begin_index != end_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) uint64_t key = begin_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) r = dm_btree_remove(&resize->info->btree_info, resize->root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) &key, &resize->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * Calculates how many blocks are needed for the array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static unsigned total_nr_blocks_needed(unsigned nr_full_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) unsigned nr_entries_in_last_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return nr_full_blocks + (nr_entries_in_last_block ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * Shrink an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int shrink(struct resize *resize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) unsigned begin, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Lose some blocks from the back?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (resize->new_nr_full_blocks < resize->old_nr_full_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) begin = total_nr_blocks_needed(resize->new_nr_full_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) resize->new_nr_entries_in_last_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) end = total_nr_blocks_needed(resize->old_nr_full_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) resize->old_nr_entries_in_last_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) r = drop_blocks(resize, begin, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * Trim the new tail block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (resize->new_nr_entries_in_last_block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) r = shadow_ablock(resize->info, &resize->root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) resize->new_nr_full_blocks, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) trim_ablock(resize->info, ab, resize->new_nr_entries_in_last_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unlock_ablock(resize->info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * Grow an array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static int grow_extend_tail_block(struct resize *resize, uint32_t new_nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) r = shadow_ablock(resize->info, &resize->root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) resize->old_nr_full_blocks, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) fill_ablock(resize->info, ab, resize->value, new_nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unlock_ablock(resize->info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int grow_add_tail_block(struct resize *resize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return insert_new_ablock(resize->info, resize->size_of_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) resize->max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) resize->new_nr_full_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) resize->new_nr_entries_in_last_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) resize->value, &resize->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int grow_needs_more_blocks(struct resize *resize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) unsigned old_nr_blocks = resize->old_nr_full_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (resize->old_nr_entries_in_last_block > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) old_nr_blocks++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) r = grow_extend_tail_block(resize, resize->max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) r = insert_full_ablocks(resize->info, resize->size_of_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) old_nr_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) resize->new_nr_full_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) resize->max_entries, resize->value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) &resize->root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (resize->new_nr_entries_in_last_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) r = grow_add_tail_block(resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int grow(struct resize *resize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (resize->new_nr_full_blocks > resize->old_nr_full_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return grow_needs_more_blocks(resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) else if (resize->old_nr_entries_in_last_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return grow_extend_tail_block(resize, resize->new_nr_entries_in_last_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return grow_add_tail_block(resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * These are the value_type functions for the btree elements, which point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * to array blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void block_inc(void *context, const void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __le64 block_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct dm_array_info *info = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) memcpy(&block_le, value, sizeof(block_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dm_tm_inc(info->btree_info.tm, le64_to_cpu(block_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void block_dec(void *context, const void *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) uint64_t b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) __le64 block_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) uint32_t ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct dm_array_info *info = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) memcpy(&block_le, value, sizeof(block_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) b = le64_to_cpu(block_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) r = dm_tm_ref(info->btree_info.tm, b, &ref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) DMERR_LIMIT("couldn't get reference count for block %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) (unsigned long long) b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ref_count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * We're about to drop the last reference to this ablock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * So we need to decrement the ref count of the contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) r = get_ablock(info, b, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) DMERR_LIMIT("couldn't get array block %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) (unsigned long long) b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dec_ablock_entries(info, ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dm_tm_dec(info->btree_info.tm, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int block_equal(void *context, const void *value1, const void *value2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return !memcmp(value1, value2, sizeof(__le64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) void dm_array_info_init(struct dm_array_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct dm_transaction_manager *tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct dm_btree_value_type *vt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct dm_btree_value_type *bvt = &info->btree_info.value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) memcpy(&info->value_type, vt, sizeof(info->value_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) info->btree_info.tm = tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) info->btree_info.levels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) bvt->context = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) bvt->size = sizeof(__le64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) bvt->inc = block_inc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) bvt->dec = block_dec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) bvt->equal = block_equal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) EXPORT_SYMBOL_GPL(dm_array_info_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int dm_array_empty(struct dm_array_info *info, dm_block_t *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return dm_btree_empty(&info->btree_info, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) EXPORT_SYMBOL_GPL(dm_array_empty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int array_resize(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) uint32_t old_size, uint32_t new_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct resize resize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (old_size == new_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *new_root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) resize.info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) resize.root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) resize.size_of_block = dm_bm_block_size(dm_tm_get_bm(info->btree_info.tm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) resize.max_entries = calc_max_entries(info->value_type.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) resize.size_of_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) resize.old_nr_full_blocks = old_size / resize.max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) resize.old_nr_entries_in_last_block = old_size % resize.max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) resize.new_nr_full_blocks = new_size / resize.max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) resize.new_nr_entries_in_last_block = new_size % resize.max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) resize.value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) r = ((new_size > old_size) ? grow : shrink)(&resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *new_root = resize.root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) int dm_array_resize(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) uint32_t old_size, uint32_t new_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) __dm_written_to_disk(value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) int r = array_resize(info, root, old_size, new_size, value, new_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) __dm_unbless_for_disk(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) EXPORT_SYMBOL_GPL(dm_array_resize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int populate_ablock_with_values(struct dm_array_info *info, struct array_block *ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) value_fn fn, void *context, unsigned base, unsigned new_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) BUG_ON(le32_to_cpu(ab->nr_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) BUG_ON(new_nr > le32_to_cpu(ab->max_entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) for (i = 0; i < new_nr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) r = fn(base + i, element_at(info, ab, i), context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (vt->inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) vt->inc(vt->context, element_at(info, ab, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ab->nr_entries = cpu_to_le32(new_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) int dm_array_new(struct dm_array_info *info, dm_block_t *root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) uint32_t size, value_fn fn, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned block_index, end_block, size_of_block, max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) r = dm_array_empty(info, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) size_of_block = dm_bm_block_size(dm_tm_get_bm(info->btree_info.tm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) max_entries = calc_max_entries(info->value_type.size, size_of_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) end_block = dm_div_up(size, max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) for (block_index = 0; block_index != end_block; block_index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) r = alloc_ablock(info, size_of_block, max_entries, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) r = populate_ablock_with_values(info, ab, fn, context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) block_index * max_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) min(max_entries, size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) r = insert_ablock(info, block_index, block, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) size -= max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) EXPORT_SYMBOL_GPL(dm_array_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int dm_array_del(struct dm_array_info *info, dm_block_t root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return dm_btree_del(&info->btree_info, root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) EXPORT_SYMBOL_GPL(dm_array_del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int dm_array_get_value(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) uint32_t index, void *value_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) size_t size_of_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) unsigned entry, max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) size_of_block = dm_bm_block_size(dm_tm_get_bm(info->btree_info.tm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) max_entries = calc_max_entries(info->value_type.size, size_of_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) r = lookup_ablock(info, root, index / max_entries, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) entry = index % max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (entry >= le32_to_cpu(ab->nr_entries))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) r = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) memcpy(value_le, element_at(info, ab, entry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) info->value_type.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) EXPORT_SYMBOL_GPL(dm_array_get_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static int array_set_value(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) uint32_t index, const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) size_t size_of_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) unsigned max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) unsigned entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) void *old_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct dm_btree_value_type *vt = &info->value_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) size_of_block = dm_bm_block_size(dm_tm_get_bm(info->btree_info.tm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) max_entries = calc_max_entries(info->value_type.size, size_of_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) r = shadow_ablock(info, &root, index / max_entries, &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) *new_root = root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) entry = index % max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (entry >= le32_to_cpu(ab->nr_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) r = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) old_value = element_at(info, ab, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (vt->dec &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) (!vt->equal || !vt->equal(vt->context, old_value, value))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) vt->dec(vt->context, old_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (vt->inc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) vt->inc(vt->context, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) memcpy(old_value, value, info->value_type.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unlock_ablock(info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int dm_array_set_value(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) uint32_t index, const void *value, dm_block_t *new_root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) __dm_written_to_disk(value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) r = array_set_value(info, root, index, value, new_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) __dm_unbless_for_disk(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) EXPORT_SYMBOL_GPL(dm_array_set_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct walk_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct dm_array_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int (*fn)(void *context, uint64_t key, void *leaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) void *context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static int walk_ablock(void *context, uint64_t *keys, void *leaf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct walk_info *wi = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) __le64 block_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) unsigned nr_entries, max_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct dm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct array_block *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) memcpy(&block_le, leaf, sizeof(block_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) r = get_ablock(wi->info, le64_to_cpu(block_le), &block, &ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) max_entries = le32_to_cpu(ab->max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) nr_entries = le32_to_cpu(ab->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) for (i = 0; i < nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) r = wi->fn(wi->context, keys[0] * max_entries + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) element_at(wi->info, ab, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) unlock_ablock(wi->info, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int dm_array_walk(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) int (*fn)(void *, uint64_t key, void *leaf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) struct walk_info wi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) wi.info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) wi.fn = fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) wi.context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return dm_btree_walk(&info->btree_info, root, walk_ablock, &wi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) EXPORT_SYMBOL_GPL(dm_array_walk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static int load_ablock(struct dm_array_cursor *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) __le64 value_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) uint64_t key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (c->block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) unlock_ablock(c->info, c->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) c->block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) c->ab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) c->index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) DMERR("dm_btree_cursor_get_value failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dm_btree_cursor_end(&c->cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) DMERR("get_ablock failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) dm_btree_cursor_end(&c->cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) int dm_array_cursor_begin(struct dm_array_info *info, dm_block_t root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct dm_array_cursor *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) memset(c, 0, sizeof(*c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) c->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) r = dm_btree_cursor_begin(&info->btree_info, root, true, &c->cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) DMERR("couldn't create btree cursor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return load_ablock(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) EXPORT_SYMBOL_GPL(dm_array_cursor_begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) void dm_array_cursor_end(struct dm_array_cursor *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (c->block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) unlock_ablock(c->info, c->block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) dm_btree_cursor_end(&c->cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) EXPORT_SYMBOL_GPL(dm_array_cursor_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) int dm_array_cursor_next(struct dm_array_cursor *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!c->block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) c->index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (c->index >= le32_to_cpu(c->ab->nr_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) r = dm_btree_cursor_next(&c->cursor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) r = load_ablock(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) EXPORT_SYMBOL_GPL(dm_array_cursor_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) uint32_t remaining = le32_to_cpu(c->ab->nr_entries) - c->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (count < remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) c->index += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) count -= remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) r = dm_array_cursor_next(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) } while (!r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) EXPORT_SYMBOL_GPL(dm_array_cursor_skip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) void dm_array_cursor_get_value(struct dm_array_cursor *c, void **value_le)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) *value_le = element_at(c->info, c->ab, c->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) EXPORT_SYMBOL_GPL(dm_array_cursor_get_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /*----------------------------------------------------------------*/