^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2011 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-space-map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "dm-space-map-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "dm-space-map-metadata.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define DM_MSG_PREFIX "space map metadata"
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * An edge triggered threshold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct threshold {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) bool threshold_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) bool value_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) dm_block_t threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) dm_block_t current_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) dm_sm_threshold_fn fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) void *context;
^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) static void threshold_init(struct threshold *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) t->threshold_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) t->value_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static void set_threshold(struct threshold *t, dm_block_t value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) dm_sm_threshold_fn fn, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) t->threshold_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) t->threshold = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) t->fn = fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) t->context = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static bool below_threshold(struct threshold *t, dm_block_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return t->threshold_set && value <= t->threshold;
^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 bool threshold_already_triggered(struct threshold *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return t->value_set && below_threshold(t, t->current_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static void check_threshold(struct threshold *t, dm_block_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (below_threshold(t, value) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) !threshold_already_triggered(t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) t->fn(t->context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) t->value_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) t->current_value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Space map interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * The low level disk format is written using the standard btree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * transaction manager. This means that performing disk operations may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * cause us to recurse into the space map in order to allocate new blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * For this reason we have a pool of pre-allocated blocks large enough to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * service any metadata_ll_disk operation.
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * FIXME: we should calculate this based on the size of the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * Only the metadata space map needs this functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define MAX_RECURSIVE_ALLOCATIONS 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) enum block_op_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) BOP_INC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) BOP_DEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct block_op {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) enum block_op_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dm_block_t block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct bop_ring_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct block_op bops[MAX_RECURSIVE_ALLOCATIONS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void brb_init(struct bop_ring_buffer *brb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) brb->begin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) brb->end = 0;
^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) static bool brb_empty(struct bop_ring_buffer *brb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return brb->begin == brb->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static unsigned brb_next(struct bop_ring_buffer *brb, unsigned old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned r = old + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return r >= ARRAY_SIZE(brb->bops) ? 0 : r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int brb_push(struct bop_ring_buffer *brb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) enum block_op_type type, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct block_op *bop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) unsigned next = brb_next(brb, brb->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * We don't allow the last bop to be filled, this way we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * differentiate between full and empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (next == brb->begin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bop = brb->bops + brb->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) bop->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bop->block = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) brb->end = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int brb_peek(struct bop_ring_buffer *brb, struct block_op *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct block_op *bop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (brb_empty(brb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) bop = brb->bops + brb->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) result->type = bop->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) result->block = bop->block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int brb_pop(struct bop_ring_buffer *brb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (brb_empty(brb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) brb->begin = brb_next(brb, brb->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct sm_metadata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct dm_space_map sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct ll_disk ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct ll_disk old_ll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) dm_block_t begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned recursion_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned allocated_this_transaction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct bop_ring_buffer uncommitted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct threshold threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int r = brb_push(&smm->uncommitted, type, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) DMERR("too many recursive allocations");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int commit_bop(struct sm_metadata *smm, struct block_op *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) enum allocation_event ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) switch (op->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case BOP_INC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) r = sm_ll_inc(&smm->ll, op->block, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case BOP_DEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) r = sm_ll_dec(&smm->ll, op->block, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void in(struct sm_metadata *smm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) smm->recursion_count++;
^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) static int apply_bops(struct sm_metadata *smm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while (!brb_empty(&smm->uncommitted)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct block_op bop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) r = brb_peek(&smm->uncommitted, &bop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) DMERR("bug in bop ring buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) r = commit_bop(smm, &bop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) brb_pop(&smm->uncommitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int out(struct sm_metadata *smm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int r = 0;
^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) * If we're not recursing then very bad things are happening.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!smm->recursion_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) DMERR("lost track of recursion depth");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (smm->recursion_count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) r = apply_bops(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) smm->recursion_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * When using the out() function above, we often want to combine an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * code for the operation run in the recursive context with that from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * out().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int combine_errors(int r1, int r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return r1 ? r1 : r2;
^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) static int recursing(struct sm_metadata *smm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return smm->recursion_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static void sm_metadata_destroy(struct dm_space_map *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) kfree(smm);
^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) static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *count = smm->ll.nr_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int sm_metadata_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *count = smm->old_ll.nr_blocks - smm->old_ll.nr_allocated -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) smm->allocated_this_transaction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) uint32_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned adjustment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * We may have some uncommitted adjustments to add. This list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * should always be really short.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) for (i = smm->uncommitted.begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) i != smm->uncommitted.end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) i = brb_next(&smm->uncommitted, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct block_op *op = smm->uncommitted.bops + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (op->block != b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) switch (op->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) case BOP_INC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) adjustment++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case BOP_DEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) adjustment--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) r = sm_ll_lookup(&smm->ll, b, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) *result += adjustment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) dm_block_t b, int *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int r, adjustment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) uint32_t rc;
^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) * We may have some uncommitted adjustments to add. This list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * should always be really short.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) for (i = smm->uncommitted.begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) i != smm->uncommitted.end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) i = brb_next(&smm->uncommitted, i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct block_op *op = smm->uncommitted.bops + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (op->block != b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) switch (op->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case BOP_INC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) adjustment++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case BOP_DEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) adjustment--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (adjustment > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) *result = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) r = sm_ll_lookup_bitmap(&smm->ll, b, &rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (rc == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * We err on the side of caution, and always return true.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) *result = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) *result = rc + adjustment > 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int sm_metadata_set_count(struct dm_space_map *sm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) uint32_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) int r, r2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) enum allocation_event ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (smm->recursion_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) DMERR("cannot recurse set_count()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) in(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) r = sm_ll_insert(&smm->ll, b, count, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) r2 = out(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return combine_errors(r, r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static int sm_metadata_inc_block(struct dm_space_map *sm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int r, r2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) enum allocation_event ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (recursing(smm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) r = add_bop(smm, BOP_INC, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) in(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) r = sm_ll_inc(&smm->ll, b, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) r2 = out(smm);
^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) return combine_errors(r, r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int sm_metadata_dec_block(struct dm_space_map *sm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int r, r2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) enum allocation_event ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (recursing(smm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) r = add_bop(smm, BOP_DEC, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) in(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) r = sm_ll_dec(&smm->ll, b, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) r2 = out(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return combine_errors(r, r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int r, r2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) enum allocation_event ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Any block we allocate has to be free in both the old and current ll.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (r == -ENOSPC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * There's no free block between smm->begin and the end of the metadata device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * We search before smm->begin in case something has been freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b);
^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) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) smm->begin = *b + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (recursing(smm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) r = add_bop(smm, BOP_INC, *b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) in(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) r = sm_ll_inc(&smm->ll, *b, &ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) r2 = out(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) smm->allocated_this_transaction++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return combine_errors(r, r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int sm_metadata_new_block(struct dm_space_map *sm, dm_block_t *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dm_block_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int r = sm_metadata_new_block_(sm, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) DMERR_LIMIT("unable to allocate new metadata block");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) r = sm_metadata_get_nr_free(sm, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) DMERR_LIMIT("couldn't get free block count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return r;
^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) check_threshold(&smm->threshold, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int sm_metadata_commit(struct dm_space_map *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) r = sm_ll_commit(&smm->ll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) smm->allocated_this_transaction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int sm_metadata_register_threshold_callback(struct dm_space_map *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) dm_block_t threshold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dm_sm_threshold_fn fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) set_threshold(&smm->threshold, threshold, fn, context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^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 sm_metadata_root_size(struct dm_space_map *sm, size_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *result = sizeof(struct disk_sm_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int sm_metadata_copy_root(struct dm_space_map *sm, void *where_le, size_t max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct disk_sm_root root_le;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) root_le.nr_blocks = cpu_to_le64(smm->ll.nr_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) root_le.nr_allocated = cpu_to_le64(smm->ll.nr_allocated);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) root_le.bitmap_root = cpu_to_le64(smm->ll.bitmap_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) root_le.ref_count_root = cpu_to_le64(smm->ll.ref_count_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (max < sizeof(root_le))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) memcpy(where_le, &root_le, sizeof(root_le));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static const struct dm_space_map ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .destroy = sm_metadata_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .extend = sm_metadata_extend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .get_nr_blocks = sm_metadata_get_nr_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .get_nr_free = sm_metadata_get_nr_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .get_count = sm_metadata_get_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .count_is_more_than_one = sm_metadata_count_is_more_than_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .set_count = sm_metadata_set_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .inc_block = sm_metadata_inc_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .dec_block = sm_metadata_dec_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .new_block = sm_metadata_new_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .commit = sm_metadata_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .root_size = sm_metadata_root_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .copy_root = sm_metadata_copy_root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .register_threshold_callback = sm_metadata_register_threshold_callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * When a new space map is created that manages its own space. We use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * this tiny bootstrap allocator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static void sm_bootstrap_destroy(struct dm_space_map *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^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 int sm_bootstrap_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) DMERR("bootstrap doesn't support extend");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int sm_bootstrap_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *count = smm->ll.nr_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int sm_bootstrap_get_nr_free(struct dm_space_map *sm, dm_block_t *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) *count = smm->ll.nr_blocks - smm->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int sm_bootstrap_get_count(struct dm_space_map *sm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) uint32_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *result = (b < smm->begin) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int sm_bootstrap_count_is_more_than_one(struct dm_space_map *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dm_block_t b, int *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int sm_bootstrap_set_count(struct dm_space_map *sm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) uint32_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) DMERR("bootstrap doesn't support set_count");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int sm_bootstrap_new_block(struct dm_space_map *sm, dm_block_t *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * We know the entire device is unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (smm->begin == smm->ll.nr_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *b = smm->begin++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static int sm_bootstrap_inc_block(struct dm_space_map *sm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return add_bop(smm, BOP_INC, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static int sm_bootstrap_dec_block(struct dm_space_map *sm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return add_bop(smm, BOP_DEC, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int sm_bootstrap_commit(struct dm_space_map *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static int sm_bootstrap_root_size(struct dm_space_map *sm, size_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) DMERR("bootstrap doesn't support root_size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int sm_bootstrap_copy_root(struct dm_space_map *sm, void *where,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) size_t max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) DMERR("bootstrap doesn't support copy_root");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static const struct dm_space_map bootstrap_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) .destroy = sm_bootstrap_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .extend = sm_bootstrap_extend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) .get_nr_blocks = sm_bootstrap_get_nr_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) .get_nr_free = sm_bootstrap_get_nr_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .get_count = sm_bootstrap_get_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .count_is_more_than_one = sm_bootstrap_count_is_more_than_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .set_count = sm_bootstrap_set_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .inc_block = sm_bootstrap_inc_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .dec_block = sm_bootstrap_dec_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .new_block = sm_bootstrap_new_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) .commit = sm_bootstrap_commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .root_size = sm_bootstrap_root_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .copy_root = sm_bootstrap_copy_root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) .register_threshold_callback = NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int r, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dm_block_t old_len = smm->ll.nr_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Flick into a mode where all blocks get allocated in the new area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) smm->begin = old_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) memcpy(sm, &bootstrap_ops, sizeof(*sm));
^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) * Extend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) r = sm_ll_extend(&smm->ll, extra_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * We repeatedly increment then commit until the commit doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * allocate any new blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) for (i = old_len; !r && i < smm->begin; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) r = add_bop(smm, BOP_INC, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) old_len = smm->begin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) r = apply_bops(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) DMERR("%s: apply_bops failed", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) r = sm_ll_commit(&smm->ll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) } while (old_len != smm->begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * Switch back to normal behaviour.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) memcpy(sm, &ops, sizeof(*sm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^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) struct dm_space_map *dm_sm_metadata_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct sm_metadata *smm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) smm = kmalloc(sizeof(*smm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (!smm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) memcpy(&smm->sm, &ops, sizeof(smm->sm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return &smm->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int dm_sm_metadata_create(struct dm_space_map *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct dm_transaction_manager *tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dm_block_t nr_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dm_block_t superblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dm_block_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) smm->begin = superblock + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) smm->recursion_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) smm->allocated_this_transaction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) brb_init(&smm->uncommitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) threshold_init(&smm->threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) r = sm_ll_new_metadata(&smm->ll, tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) r = sm_ll_extend(&smm->ll, nr_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) memcpy(&smm->sm, &ops, sizeof(smm->sm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * Now we need to update the newly created data structures with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * allocated blocks that they were built from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) for (i = superblock; !r && i < smm->begin; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) r = add_bop(smm, BOP_INC, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) r = apply_bops(smm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) DMERR("%s: apply_bops failed", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return sm_metadata_commit(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int dm_sm_metadata_open(struct dm_space_map *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct dm_transaction_manager *tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) void *root_le, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) r = sm_ll_open_metadata(&smm->ll, tm, root_le, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) smm->begin = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) smm->recursion_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) smm->allocated_this_transaction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) brb_init(&smm->uncommitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) threshold_init(&smm->threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }