Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) #include "dm-transaction-manager.h"
^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-disk.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) #include "dm-persistent-data-internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define DM_MSG_PREFIX "transaction manager"
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define PREFETCH_SIZE 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define PREFETCH_BITS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define PREFETCH_SENTINEL ((dm_block_t) -1ULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct prefetch_set {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	dm_block_t blocks[PREFETCH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static unsigned prefetch_hash(dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	return hash_64(b, PREFETCH_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static void prefetch_wipe(struct prefetch_set *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	for (i = 0; i < PREFETCH_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		p->blocks[i] = PREFETCH_SENTINEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static void prefetch_init(struct prefetch_set *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	mutex_init(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	prefetch_wipe(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static void prefetch_add(struct prefetch_set *p, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	unsigned h = prefetch_hash(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	mutex_lock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (p->blocks[h] == PREFETCH_SENTINEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		p->blocks[h] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	mutex_unlock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static void prefetch_issue(struct prefetch_set *p, struct dm_block_manager *bm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	mutex_lock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	for (i = 0; i < PREFETCH_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		if (p->blocks[i] != PREFETCH_SENTINEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 			dm_bm_prefetch(bm, p->blocks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			p->blocks[i] = PREFETCH_SENTINEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	mutex_unlock(&p->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) struct shadow_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct hlist_node hlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	dm_block_t where;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * It would be nice if we scaled with the size of transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define DM_HASH_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define DM_HASH_MASK (DM_HASH_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) struct dm_transaction_manager {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	int is_clone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	struct dm_transaction_manager *real;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct dm_block_manager *bm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	struct dm_space_map *sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct hlist_head buckets[DM_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct prefetch_set prefetches;
^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) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int is_shadow(struct dm_transaction_manager *tm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	unsigned bucket = dm_hash_block(b, DM_HASH_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct shadow_info *si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	spin_lock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	hlist_for_each_entry(si, tm->buckets + bucket, hlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		if (si->where == b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			r = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	spin_unlock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return r;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * This can silently fail if there's no memory.  We're ok with this since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * creating redundant shadows causes no harm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static void insert_shadow(struct dm_transaction_manager *tm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	unsigned bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct shadow_info *si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	si = kmalloc(sizeof(*si), GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (si) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		si->where = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		bucket = dm_hash_block(b, DM_HASH_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		spin_lock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		hlist_add_head(&si->hlist, tm->buckets + bucket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		spin_unlock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static void wipe_shadow_table(struct dm_transaction_manager *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct shadow_info *si;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct hlist_node *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct hlist_head *bucket;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	spin_lock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	for (i = 0; i < DM_HASH_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		bucket = tm->buckets + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		hlist_for_each_entry_safe(si, tmp, bucket, hlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			kfree(si);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		INIT_HLIST_HEAD(bucket);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	spin_unlock(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct dm_transaction_manager *dm_tm_create(struct dm_block_manager *bm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 						   struct dm_space_map *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct dm_transaction_manager *tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	tm = kmalloc(sizeof(*tm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (!tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	tm->is_clone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	tm->real = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	tm->bm = bm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	tm->sm = sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	spin_lock_init(&tm->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	for (i = 0; i < DM_HASH_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		INIT_HLIST_HEAD(tm->buckets + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	prefetch_init(&tm->prefetches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transaction_manager *real)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct dm_transaction_manager *tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	tm = kmalloc(sizeof(*tm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (tm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		tm->is_clone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		tm->real = real;
^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) 	return tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) void dm_tm_destroy(struct dm_transaction_manager *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (!tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		wipe_shadow_table(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	kfree(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EXPORT_SYMBOL_GPL(dm_tm_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int dm_tm_pre_commit(struct dm_transaction_manager *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	r = dm_sm_commit(tm->sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return dm_bm_flush(tm->bm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) EXPORT_SYMBOL_GPL(dm_tm_pre_commit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int dm_tm_commit(struct dm_transaction_manager *tm, struct dm_block *root)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	wipe_shadow_table(tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	dm_bm_unlock(root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return dm_bm_flush(tm->bm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) EXPORT_SYMBOL_GPL(dm_tm_commit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int dm_tm_new_block(struct dm_transaction_manager *tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		    struct dm_block_validator *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		    struct dm_block **result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	dm_block_t new_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	if (tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	r = dm_sm_new_block(tm->sm, &new_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	r = dm_bm_write_lock_zero(tm->bm, new_block, v, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (r < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		dm_sm_dec_block(tm->sm, new_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 * New blocks count as shadows in that they don't need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	 * shadowed again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	insert_shadow(tm, new_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int __shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			  struct dm_block_validator *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			  struct dm_block **result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	dm_block_t new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	struct dm_block *orig_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	r = dm_sm_new_block(tm->sm, &new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	r = dm_sm_dec_block(tm->sm, orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	r = dm_bm_read_lock(tm->bm, orig, v, &orig_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 * It would be tempting to use dm_bm_unlock_move here, but some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 * code, such as the space maps, keeps using the old data structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	 * secure in the knowledge they won't be changed until the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	 * transaction.  Using unlock_move would force a synchronous read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	 * since the old block would no longer be in the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	r = dm_bm_write_lock_zero(tm->bm, new, v, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		dm_bm_unlock(orig_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	memcpy(dm_block_data(*result), dm_block_data(orig_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	       dm_bm_block_size(tm->bm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	dm_bm_unlock(orig_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int dm_tm_shadow_block(struct dm_transaction_manager *tm, dm_block_t orig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		       struct dm_block_validator *v, struct dm_block **result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		       int *inc_children)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	r = dm_sm_count_is_more_than_one(tm->sm, orig, inc_children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (is_shadow(tm, orig) && !*inc_children)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return dm_bm_write_lock(tm->bm, orig, v, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	r = __shadow_block(tm, orig, v, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (r < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	insert_shadow(tm, dm_block_location(*result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) EXPORT_SYMBOL_GPL(dm_tm_shadow_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int dm_tm_read_lock(struct dm_transaction_manager *tm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		    struct dm_block_validator *v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		    struct dm_block **blk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	if (tm->is_clone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		int r = dm_bm_read_try_lock(tm->real->bm, b, v, blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (r == -EWOULDBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			prefetch_add(&tm->real->prefetches, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	return dm_bm_read_lock(tm->bm, b, v, blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) EXPORT_SYMBOL_GPL(dm_tm_read_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void dm_tm_unlock(struct dm_transaction_manager *tm, struct dm_block *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	dm_bm_unlock(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) EXPORT_SYMBOL_GPL(dm_tm_unlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) void dm_tm_inc(struct dm_transaction_manager *tm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	 * The non-blocking clone doesn't support this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	BUG_ON(tm->is_clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	dm_sm_inc_block(tm->sm, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) EXPORT_SYMBOL_GPL(dm_tm_inc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) void dm_tm_dec(struct dm_transaction_manager *tm, dm_block_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	 * The non-blocking clone doesn't support this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	BUG_ON(tm->is_clone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	dm_sm_dec_block(tm->sm, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) EXPORT_SYMBOL_GPL(dm_tm_dec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int dm_tm_ref(struct dm_transaction_manager *tm, dm_block_t b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	      uint32_t *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	if (tm->is_clone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return dm_sm_get_count(tm->sm, b, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct dm_block_manager *dm_tm_get_bm(struct dm_transaction_manager *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	return tm->bm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) void dm_tm_issue_prefetches(struct dm_transaction_manager *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	prefetch_issue(&tm->prefetches, tm->bm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) EXPORT_SYMBOL_GPL(dm_tm_issue_prefetches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /*----------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int dm_tm_create_internal(struct dm_block_manager *bm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 				 dm_block_t sb_location,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				 struct dm_transaction_manager **tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				 struct dm_space_map **sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				 int create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 				 void *sm_root, size_t sm_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	*sm = dm_sm_metadata_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	if (IS_ERR(*sm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return PTR_ERR(*sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	*tm = dm_tm_create(bm, *sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (IS_ERR(*tm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		dm_sm_destroy(*sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return PTR_ERR(*tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (create) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		r = dm_sm_metadata_create(*sm, *tm, dm_bm_nr_blocks(bm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 					  sb_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			DMERR("couldn't create metadata space map");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		r = dm_sm_metadata_open(*sm, *tm, sm_root, sm_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			DMERR("couldn't open metadata space map");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		}
^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) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	dm_tm_destroy(*tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	dm_sm_destroy(*sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int dm_tm_create_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			 struct dm_transaction_manager **tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			 struct dm_space_map **sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	return dm_tm_create_internal(bm, sb_location, tm, sm, 1, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) EXPORT_SYMBOL_GPL(dm_tm_create_with_sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int dm_tm_open_with_sm(struct dm_block_manager *bm, dm_block_t sb_location,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		       void *sm_root, size_t root_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		       struct dm_transaction_manager **tm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		       struct dm_space_map **sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	return dm_tm_create_internal(bm, sb_location, tm, sm, 0, sm_root, root_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) EXPORT_SYMBOL_GPL(dm_tm_open_with_sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*----------------------------------------------------------------*/