Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dm-3.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:
"A set of device-mapper fixes for 3.13.

A fix for possible memory corruption during DM table load, fix a
possible leak of snapshot space in case of a crash, fix a possible
deadlock due to a shared workqueue in the delay target, fix to
initialize read-only module parameters that are used to export metrics
for dm stats and dm bufio.

Quite a few stable fixes were identified for both the thin-
provisioning and caching targets as a result of increased regression
testing using the device-mapper-test-suite (dmts). The most notable
of these are the reference counting fixes for the space map btree that
is used by the dm-array interface -- without these the dm-cache
metadata will leak, resulting in dm-cache devices running out of
metadata blocks. Also, some important fixes related to the
thin-provisioning target's transition to read-only mode on error"

* tag 'dm-3.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm array: fix a reference counting bug in shadow_ablock
dm space map: disallow decrementing a reference count below zero
dm stats: initialize read-only module parameter
dm bufio: initialize read-only module parameters
dm cache: actually resize cache
dm cache: update Documentation for invalidate_cblocks's range syntax
dm cache policy mq: fix promotions to occur as expected
dm thin: allow pool in read-only mode to transition to read-write mode
dm thin: re-establish read-only state when switching to fail mode
dm thin: always fallback the pool mode if commit fails
dm thin: switch to read-only mode if metadata space is exhausted
dm thin: switch to read only mode if a mapping insert fails
dm space map metadata: return on failure in sm_metadata_new_block
dm table: fail dm_table_create on dm_round_up overflow
dm snapshot: avoid snapshot space leak on crash
dm delay: fix a possible deadlock due to shared workqueue

+197 -71
+6 -4
Documentation/device-mapper/cache.txt
··· 266 266 Invalidation is removing an entry from the cache without writing it 267 267 back. Cache blocks can be invalidated via the invalidate_cblocks 268 268 message, which takes an arbitrary number of cblock ranges. Each cblock 269 - must be expressed as a decimal value, in the future a variant message 270 - that takes cblock ranges expressed in hexidecimal may be needed to 271 - better support efficient invalidation of larger caches. The cache must 272 - be in passthrough mode when invalidate_cblocks is used. 269 + range's end value is "one past the end", meaning 5-10 expresses a range 270 + of values from 5 to 9. Each cblock must be expressed as a decimal 271 + value, in the future a variant message that takes cblock ranges 272 + expressed in hexidecimal may be needed to better support efficient 273 + invalidation of larger caches. The cache must be in passthrough mode 274 + when invalidate_cblocks is used. 273 275 274 276 invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]* 275 277
+5
drivers/md/dm-bufio.c
··· 1717 1717 { 1718 1718 __u64 mem; 1719 1719 1720 + dm_bufio_allocated_kmem_cache = 0; 1721 + dm_bufio_allocated_get_free_pages = 0; 1722 + dm_bufio_allocated_vmalloc = 0; 1723 + dm_bufio_current_allocated = 0; 1724 + 1720 1725 memset(&dm_bufio_caches, 0, sizeof dm_bufio_caches); 1721 1726 memset(&dm_bufio_cache_names, 0, sizeof dm_bufio_cache_names); 1722 1727
+8 -5
drivers/md/dm-cache-policy-mq.c
··· 730 730 int r = 0; 731 731 bool updated = updated_this_tick(mq, e); 732 732 733 - requeue_and_update_tick(mq, e); 734 - 735 733 if ((!discarded_oblock && updated) || 736 - !should_promote(mq, e, discarded_oblock, data_dir)) 734 + !should_promote(mq, e, discarded_oblock, data_dir)) { 735 + requeue_and_update_tick(mq, e); 737 736 result->op = POLICY_MISS; 738 - else if (!can_migrate) 737 + 738 + } else if (!can_migrate) 739 739 r = -EWOULDBLOCK; 740 - else 740 + 741 + else { 742 + requeue_and_update_tick(mq, e); 741 743 r = pre_cache_to_cache(mq, e, result); 744 + } 742 745 743 746 return r; 744 747 }
+1 -1
drivers/md/dm-cache-target.c
··· 2755 2755 { 2756 2756 int r; 2757 2757 2758 - r = dm_cache_resize(cache->cmd, cache->cache_size); 2758 + r = dm_cache_resize(cache->cmd, new_size); 2759 2759 if (r) { 2760 2760 DMERR("could not resize cache metadata"); 2761 2761 return r;
+11 -12
drivers/md/dm-delay.c
··· 20 20 struct delay_c { 21 21 struct timer_list delay_timer; 22 22 struct mutex timer_lock; 23 + struct workqueue_struct *kdelayd_wq; 23 24 struct work_struct flush_expired_bios; 24 25 struct list_head delayed_bios; 25 26 atomic_t may_delay; ··· 46 45 47 46 static DEFINE_MUTEX(delayed_bios_lock); 48 47 49 - static struct workqueue_struct *kdelayd_wq; 50 48 static struct kmem_cache *delayed_cache; 51 49 52 50 static void handle_delayed_timer(unsigned long data) 53 51 { 54 52 struct delay_c *dc = (struct delay_c *)data; 55 53 56 - queue_work(kdelayd_wq, &dc->flush_expired_bios); 54 + queue_work(dc->kdelayd_wq, &dc->flush_expired_bios); 57 55 } 58 56 59 57 static void queue_timeout(struct delay_c *dc, unsigned long expires) ··· 191 191 goto bad_dev_write; 192 192 } 193 193 194 + dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); 195 + if (!dc->kdelayd_wq) { 196 + DMERR("Couldn't start kdelayd"); 197 + goto bad_queue; 198 + } 199 + 194 200 setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc); 195 201 196 202 INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); ··· 209 203 ti->private = dc; 210 204 return 0; 211 205 206 + bad_queue: 207 + mempool_destroy(dc->delayed_pool); 212 208 bad_dev_write: 213 209 if (dc->dev_write) 214 210 dm_put_device(ti, dc->dev_write); ··· 225 217 { 226 218 struct delay_c *dc = ti->private; 227 219 228 - flush_workqueue(kdelayd_wq); 220 + destroy_workqueue(dc->kdelayd_wq); 229 221 230 222 dm_put_device(ti, dc->dev_read); 231 223 ··· 358 350 { 359 351 int r = -ENOMEM; 360 352 361 - kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); 362 - if (!kdelayd_wq) { 363 - DMERR("Couldn't start kdelayd"); 364 - goto bad_queue; 365 - } 366 - 367 353 delayed_cache = KMEM_CACHE(dm_delay_info, 0); 368 354 if (!delayed_cache) { 369 355 DMERR("Couldn't create delayed bio cache."); ··· 375 373 bad_register: 376 374 kmem_cache_destroy(delayed_cache); 377 375 bad_memcache: 378 - destroy_workqueue(kdelayd_wq); 379 - bad_queue: 380 376 return r; 381 377 } 382 378 ··· 382 382 { 383 383 dm_unregister_target(&delay_target); 384 384 kmem_cache_destroy(delayed_cache); 385 - destroy_workqueue(kdelayd_wq); 386 385 } 387 386 388 387 /* Module hooks */
+64 -7
drivers/md/dm-snap.c
··· 66 66 67 67 atomic_t pending_exceptions_count; 68 68 69 + /* Protected by "lock" */ 70 + sector_t exception_start_sequence; 71 + 72 + /* Protected by kcopyd single-threaded callback */ 73 + sector_t exception_complete_sequence; 74 + 75 + /* 76 + * A list of pending exceptions that completed out of order. 77 + * Protected by kcopyd single-threaded callback. 78 + */ 79 + struct list_head out_of_order_list; 80 + 69 81 mempool_t *pending_pool; 70 82 71 83 struct dm_exception_table pending; ··· 184 172 * kcopyd. 185 173 */ 186 174 int started; 175 + 176 + /* There was copying error. */ 177 + int copy_error; 178 + 179 + /* A sequence number, it is used for in-order completion. */ 180 + sector_t exception_sequence; 181 + 182 + struct list_head out_of_order_entry; 187 183 188 184 /* 189 185 * For writing a complete chunk, bypassing the copy. ··· 1114 1094 s->valid = 1; 1115 1095 s->active = 0; 1116 1096 atomic_set(&s->pending_exceptions_count, 0); 1097 + s->exception_start_sequence = 0; 1098 + s->exception_complete_sequence = 0; 1099 + INIT_LIST_HEAD(&s->out_of_order_list); 1117 1100 init_rwsem(&s->lock); 1118 1101 INIT_LIST_HEAD(&s->list); 1119 1102 spin_lock_init(&s->pe_lock); ··· 1466 1443 pending_complete(pe, success); 1467 1444 } 1468 1445 1446 + static void complete_exception(struct dm_snap_pending_exception *pe) 1447 + { 1448 + struct dm_snapshot *s = pe->snap; 1449 + 1450 + if (unlikely(pe->copy_error)) 1451 + pending_complete(pe, 0); 1452 + 1453 + else 1454 + /* Update the metadata if we are persistent */ 1455 + s->store->type->commit_exception(s->store, &pe->e, 1456 + commit_callback, pe); 1457 + } 1458 + 1469 1459 /* 1470 1460 * Called when the copy I/O has finished. kcopyd actually runs 1471 1461 * this code so don't block. ··· 1488 1452 struct dm_snap_pending_exception *pe = context; 1489 1453 struct dm_snapshot *s = pe->snap; 1490 1454 1491 - if (read_err || write_err) 1492 - pending_complete(pe, 0); 1455 + pe->copy_error = read_err || write_err; 1493 1456 1494 - else 1495 - /* Update the metadata if we are persistent */ 1496 - s->store->type->commit_exception(s->store, &pe->e, 1497 - commit_callback, pe); 1457 + if (pe->exception_sequence == s->exception_complete_sequence) { 1458 + s->exception_complete_sequence++; 1459 + complete_exception(pe); 1460 + 1461 + while (!list_empty(&s->out_of_order_list)) { 1462 + pe = list_entry(s->out_of_order_list.next, 1463 + struct dm_snap_pending_exception, out_of_order_entry); 1464 + if (pe->exception_sequence != s->exception_complete_sequence) 1465 + break; 1466 + s->exception_complete_sequence++; 1467 + list_del(&pe->out_of_order_entry); 1468 + complete_exception(pe); 1469 + } 1470 + } else { 1471 + struct list_head *lh; 1472 + struct dm_snap_pending_exception *pe2; 1473 + 1474 + list_for_each_prev(lh, &s->out_of_order_list) { 1475 + pe2 = list_entry(lh, struct dm_snap_pending_exception, out_of_order_entry); 1476 + if (pe2->exception_sequence < pe->exception_sequence) 1477 + break; 1478 + } 1479 + list_add(&pe->out_of_order_entry, lh); 1480 + } 1498 1481 } 1499 1482 1500 1483 /* ··· 1607 1552 free_pending_exception(pe); 1608 1553 return NULL; 1609 1554 } 1555 + 1556 + pe->exception_sequence = s->exception_start_sequence++; 1610 1557 1611 1558 dm_insert_exception(&s->pending, &pe->e); 1612 1559 ··· 2249 2192 2250 2193 static struct target_type snapshot_target = { 2251 2194 .name = "snapshot", 2252 - .version = {1, 11, 1}, 2195 + .version = {1, 12, 0}, 2253 2196 .module = THIS_MODULE, 2254 2197 .ctr = snapshot_ctr, 2255 2198 .dtr = snapshot_dtr,
+1
drivers/md/dm-stats.c
··· 964 964 965 965 int __init dm_statistics_init(void) 966 966 { 967 + shared_memory_amount = 0; 967 968 dm_stat_need_rcu_barrier = 0; 968 969 return 0; 969 970 }
+5
drivers/md/dm-table.c
··· 200 200 201 201 num_targets = dm_round_up(num_targets, KEYS_PER_NODE); 202 202 203 + if (!num_targets) { 204 + kfree(t); 205 + return -ENOMEM; 206 + } 207 + 203 208 if (alloc_targets(t, num_targets)) { 204 209 kfree(t); 205 210 return -ENOMEM;
+8
drivers/md/dm-thin-metadata.c
··· 1697 1697 up_write(&pmd->root_lock); 1698 1698 } 1699 1699 1700 + void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd) 1701 + { 1702 + down_write(&pmd->root_lock); 1703 + pmd->read_only = false; 1704 + dm_bm_set_read_write(pmd->bm); 1705 + up_write(&pmd->root_lock); 1706 + } 1707 + 1700 1708 int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, 1701 1709 dm_block_t threshold, 1702 1710 dm_sm_threshold_fn fn,
+1
drivers/md/dm-thin-metadata.h
··· 193 193 * that nothing is changing. 194 194 */ 195 195 void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd); 196 + void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd); 196 197 197 198 int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, 198 199 dm_block_t threshold,
+39 -27
drivers/md/dm-thin.c
··· 640 640 */ 641 641 r = dm_thin_insert_block(tc->td, m->virt_block, m->data_block); 642 642 if (r) { 643 - DMERR_LIMIT("dm_thin_insert_block() failed"); 643 + DMERR_LIMIT("%s: dm_thin_insert_block() failed: error = %d", 644 + dm_device_name(pool->pool_md), r); 645 + set_pool_mode(pool, PM_READ_ONLY); 644 646 cell_error(pool, m->cell); 645 647 goto out; 646 648 } ··· 883 881 } 884 882 } 885 883 886 - static int commit(struct pool *pool) 887 - { 888 - int r; 889 - 890 - r = dm_pool_commit_metadata(pool->pmd); 891 - if (r) 892 - DMERR_LIMIT("%s: commit failed: error = %d", 893 - dm_device_name(pool->pool_md), r); 894 - 895 - return r; 896 - } 897 - 898 884 /* 899 885 * A non-zero return indicates read_only or fail_io mode. 900 886 * Many callers don't care about the return value. 901 887 */ 902 - static int commit_or_fallback(struct pool *pool) 888 + static int commit(struct pool *pool) 903 889 { 904 890 int r; 905 891 906 892 if (get_pool_mode(pool) != PM_WRITE) 907 893 return -EINVAL; 908 894 909 - r = commit(pool); 910 - if (r) 895 + r = dm_pool_commit_metadata(pool->pmd); 896 + if (r) { 897 + DMERR_LIMIT("%s: dm_pool_commit_metadata failed: error = %d", 898 + dm_device_name(pool->pool_md), r); 911 899 set_pool_mode(pool, PM_READ_ONLY); 900 + } 912 901 913 902 return r; 914 903 } ··· 936 943 * Try to commit to see if that will free up some 937 944 * more space. 938 945 */ 939 - (void) commit_or_fallback(pool); 946 + r = commit(pool); 947 + if (r) 948 + return r; 940 949 941 950 r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); 942 951 if (r) ··· 952 957 * table reload). 953 958 */ 954 959 if (!free_blocks) { 955 - DMWARN("%s: no free space available.", 960 + DMWARN("%s: no free data space available.", 956 961 dm_device_name(pool->pool_md)); 957 962 spin_lock_irqsave(&pool->lock, flags); 958 963 pool->no_free_space = 1; ··· 962 967 } 963 968 964 969 r = dm_pool_alloc_data_block(pool->pmd, result); 965 - if (r) 970 + if (r) { 971 + if (r == -ENOSPC && 972 + !dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks) && 973 + !free_blocks) { 974 + DMWARN("%s: no free metadata space available.", 975 + dm_device_name(pool->pool_md)); 976 + set_pool_mode(pool, PM_READ_ONLY); 977 + } 966 978 return r; 979 + } 967 980 968 981 return 0; 969 982 } ··· 1352 1349 if (bio_list_empty(&bios) && !need_commit_due_to_time(pool)) 1353 1350 return; 1354 1351 1355 - if (commit_or_fallback(pool)) { 1352 + if (commit(pool)) { 1356 1353 while ((bio = bio_list_pop(&bios))) 1357 1354 bio_io_error(bio); 1358 1355 return; ··· 1400 1397 case PM_FAIL: 1401 1398 DMERR("%s: switching pool to failure mode", 1402 1399 dm_device_name(pool->pool_md)); 1400 + dm_pool_metadata_read_only(pool->pmd); 1403 1401 pool->process_bio = process_bio_fail; 1404 1402 pool->process_discard = process_bio_fail; 1405 1403 pool->process_prepared_mapping = process_prepared_mapping_fail; ··· 1425 1421 break; 1426 1422 1427 1423 case PM_WRITE: 1424 + dm_pool_metadata_read_write(pool->pmd); 1428 1425 pool->process_bio = process_bio; 1429 1426 pool->process_discard = process_discard; 1430 1427 pool->process_prepared_mapping = process_prepared_mapping; ··· 1642 1637 struct pool_c *pt = ti->private; 1643 1638 1644 1639 /* 1645 - * We want to make sure that degraded pools are never upgraded. 1640 + * We want to make sure that a pool in PM_FAIL mode is never upgraded. 1646 1641 */ 1647 1642 enum pool_mode old_mode = pool->pf.mode; 1648 1643 enum pool_mode new_mode = pt->adjusted_pf.mode; 1649 1644 1650 - if (old_mode > new_mode) 1645 + /* 1646 + * If we were in PM_FAIL mode, rollback of metadata failed. We're 1647 + * not going to recover without a thin_repair. So we never let the 1648 + * pool move out of the old mode. On the other hand a PM_READ_ONLY 1649 + * may have been due to a lack of metadata or data space, and may 1650 + * now work (ie. if the underlying devices have been resized). 1651 + */ 1652 + if (old_mode == PM_FAIL) 1651 1653 new_mode = old_mode; 1652 1654 1653 1655 pool->ti = ti; ··· 2278 2266 return r; 2279 2267 2280 2268 if (need_commit1 || need_commit2) 2281 - (void) commit_or_fallback(pool); 2269 + (void) commit(pool); 2282 2270 2283 2271 return 0; 2284 2272 } ··· 2305 2293 2306 2294 cancel_delayed_work(&pool->waker); 2307 2295 flush_workqueue(pool->wq); 2308 - (void) commit_or_fallback(pool); 2296 + (void) commit(pool); 2309 2297 } 2310 2298 2311 2299 static int check_arg_count(unsigned argc, unsigned args_required) ··· 2439 2427 if (r) 2440 2428 return r; 2441 2429 2442 - (void) commit_or_fallback(pool); 2430 + (void) commit(pool); 2443 2431 2444 2432 r = dm_pool_reserve_metadata_snap(pool->pmd); 2445 2433 if (r) ··· 2501 2489 DMWARN("Unrecognised thin pool target message received: %s", argv[0]); 2502 2490 2503 2491 if (!r) 2504 - (void) commit_or_fallback(pool); 2492 + (void) commit(pool); 2505 2493 2506 2494 return r; 2507 2495 } ··· 2556 2544 2557 2545 /* Commit to ensure statistics aren't out-of-date */ 2558 2546 if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) 2559 - (void) commit_or_fallback(pool); 2547 + (void) commit(pool); 2560 2548 2561 2549 r = dm_pool_get_metadata_transaction_id(pool->pmd, &transaction_id); 2562 2550 if (r) {
+9 -1
drivers/md/persistent-data/dm-array.c
··· 317 317 * The shadow op will often be a noop. Only insert if it really 318 318 * copied data. 319 319 */ 320 - if (dm_block_location(*block) != b) 320 + if (dm_block_location(*block) != b) { 321 + /* 322 + * dm_tm_shadow_block will have already decremented the old 323 + * block, but it is still referenced by the btree. We 324 + * increment to stop the insert decrementing it below zero 325 + * when overwriting the old value. 326 + */ 327 + dm_tm_inc(info->btree_info.tm, b); 321 328 r = insert_ablock(info, index, *block, root); 329 + } 322 330 323 331 return r; 324 332 }
+6
drivers/md/persistent-data/dm-block-manager.c
··· 626 626 } 627 627 EXPORT_SYMBOL_GPL(dm_bm_set_read_only); 628 628 629 + void dm_bm_set_read_write(struct dm_block_manager *bm) 630 + { 631 + bm->read_only = false; 632 + } 633 + EXPORT_SYMBOL_GPL(dm_bm_set_read_write); 634 + 629 635 u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor) 630 636 { 631 637 return crc32c(~(u32) 0, data, len) ^ init_xor;
+4 -3
drivers/md/persistent-data/dm-block-manager.h
··· 108 108 int dm_bm_flush_and_unlock(struct dm_block_manager *bm, 109 109 struct dm_block *superblock); 110 110 111 - /* 112 - * Request data be prefetched into the cache. 113 - */ 111 + /* 112 + * Request data is prefetched into the cache. 113 + */ 114 114 void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b); 115 115 116 116 /* ··· 125 125 * be returned if you do. 126 126 */ 127 127 void dm_bm_set_read_only(struct dm_block_manager *bm); 128 + void dm_bm_set_read_write(struct dm_block_manager *bm); 128 129 129 130 u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor); 130 131
+23 -9
drivers/md/persistent-data/dm-space-map-common.c
··· 381 381 } 382 382 383 383 static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b, 384 - uint32_t (*mutator)(void *context, uint32_t old), 384 + int (*mutator)(void *context, uint32_t old, uint32_t *new), 385 385 void *context, enum allocation_event *ev) 386 386 { 387 387 int r; ··· 410 410 411 411 if (old > 2) { 412 412 r = sm_ll_lookup_big_ref_count(ll, b, &old); 413 - if (r < 0) 413 + if (r < 0) { 414 + dm_tm_unlock(ll->tm, nb); 414 415 return r; 416 + } 415 417 } 416 418 417 - ref_count = mutator(context, old); 419 + r = mutator(context, old, &ref_count); 420 + if (r) { 421 + dm_tm_unlock(ll->tm, nb); 422 + return r; 423 + } 418 424 419 425 if (ref_count <= 2) { 420 426 sm_set_bitmap(bm_le, bit, ref_count); ··· 471 465 return ll->save_ie(ll, index, &ie_disk); 472 466 } 473 467 474 - static uint32_t set_ref_count(void *context, uint32_t old) 468 + static int set_ref_count(void *context, uint32_t old, uint32_t *new) 475 469 { 476 - return *((uint32_t *) context); 470 + *new = *((uint32_t *) context); 471 + return 0; 477 472 } 478 473 479 474 int sm_ll_insert(struct ll_disk *ll, dm_block_t b, ··· 483 476 return sm_ll_mutate(ll, b, set_ref_count, &ref_count, ev); 484 477 } 485 478 486 - static uint32_t inc_ref_count(void *context, uint32_t old) 479 + static int inc_ref_count(void *context, uint32_t old, uint32_t *new) 487 480 { 488 - return old + 1; 481 + *new = old + 1; 482 + return 0; 489 483 } 490 484 491 485 int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev) ··· 494 486 return sm_ll_mutate(ll, b, inc_ref_count, NULL, ev); 495 487 } 496 488 497 - static uint32_t dec_ref_count(void *context, uint32_t old) 489 + static int dec_ref_count(void *context, uint32_t old, uint32_t *new) 498 490 { 499 - return old - 1; 491 + if (!old) { 492 + DMERR_LIMIT("unable to decrement a reference count below 0"); 493 + return -EINVAL; 494 + } 495 + 496 + *new = old - 1; 497 + return 0; 500 498 } 501 499 502 500 int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev)
+6 -2
drivers/md/persistent-data/dm-space-map-metadata.c
··· 384 384 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 385 385 386 386 int r = sm_metadata_new_block_(sm, b); 387 - if (r) 387 + if (r) { 388 388 DMERR("unable to allocate new metadata block"); 389 + return r; 390 + } 389 391 390 392 r = sm_metadata_get_nr_free(sm, &count); 391 - if (r) 393 + if (r) { 392 394 DMERR("couldn't get free block count"); 395 + return r; 396 + } 393 397 394 398 check_threshold(&smm->threshold, count); 395 399