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