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.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:
"A few dm-thinp fixes for changes merged in 3.15-rc1.

A dm-verity fix for an immutable biovec regression that affects 3.14+.

A dm-cache fix to properly quiesce when using writethrough mode (3.14+)"

* tag 'dm-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm cache: fix writethrough mode quiescing in cache_map
dm thin: use INIT_WORK_ONSTACK in noflush_work to avoid ODEBUG warning
dm verity: fix biovecs hash calculation regression
dm thin: fix rcu_read_lock being held in code that can sleep
dm thin: irqsave must always be used with the pool->lock spinlock

+81 -12
+1
drivers/md/dm-cache-target.c
··· 2488 2488 2489 2489 } else { 2490 2490 inc_hit_counter(cache, bio); 2491 + pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); 2491 2492 2492 2493 if (bio_data_dir(bio) == WRITE && writethrough_mode(&cache->features) && 2493 2494 !is_dirty(cache, lookup_result.cblock))
+71 -6
drivers/md/dm-thin.c
··· 232 232 struct bio_list deferred_bio_list; 233 233 struct bio_list retry_on_resume_list; 234 234 struct rb_root sort_bio_list; /* sorted list of deferred bios */ 235 + 236 + /* 237 + * Ensures the thin is not destroyed until the worker has finished 238 + * iterating the active_thins list. 239 + */ 240 + atomic_t refcount; 241 + struct completion can_destroy; 235 242 }; 236 243 237 244 /*----------------------------------------------------------------*/ ··· 1493 1486 blk_finish_plug(&plug); 1494 1487 } 1495 1488 1489 + static void thin_get(struct thin_c *tc); 1490 + static void thin_put(struct thin_c *tc); 1491 + 1492 + /* 1493 + * We can't hold rcu_read_lock() around code that can block. So we 1494 + * find a thin with the rcu lock held; bump a refcount; then drop 1495 + * the lock. 1496 + */ 1497 + static struct thin_c *get_first_thin(struct pool *pool) 1498 + { 1499 + struct thin_c *tc = NULL; 1500 + 1501 + rcu_read_lock(); 1502 + if (!list_empty(&pool->active_thins)) { 1503 + tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); 1504 + thin_get(tc); 1505 + } 1506 + rcu_read_unlock(); 1507 + 1508 + return tc; 1509 + } 1510 + 1511 + static struct thin_c *get_next_thin(struct pool *pool, struct thin_c *tc) 1512 + { 1513 + struct thin_c *old_tc = tc; 1514 + 1515 + rcu_read_lock(); 1516 + list_for_each_entry_continue_rcu(tc, &pool->active_thins, list) { 1517 + thin_get(tc); 1518 + thin_put(old_tc); 1519 + rcu_read_unlock(); 1520 + return tc; 1521 + } 1522 + thin_put(old_tc); 1523 + rcu_read_unlock(); 1524 + 1525 + return NULL; 1526 + } 1527 + 1496 1528 static void process_deferred_bios(struct pool *pool) 1497 1529 { 1498 1530 unsigned long flags; ··· 1539 1493 struct bio_list bios; 1540 1494 struct thin_c *tc; 1541 1495 1542 - rcu_read_lock(); 1543 - list_for_each_entry_rcu(tc, &pool->active_thins, list) 1496 + tc = get_first_thin(pool); 1497 + while (tc) { 1544 1498 process_thin_deferred_bios(tc); 1545 - rcu_read_unlock(); 1499 + tc = get_next_thin(pool, tc); 1500 + } 1546 1501 1547 1502 /* 1548 1503 * If there are any deferred flush bios, we must commit ··· 1625 1578 { 1626 1579 struct noflush_work w; 1627 1580 1628 - INIT_WORK(&w.worker, fn); 1581 + INIT_WORK_ONSTACK(&w.worker, fn); 1629 1582 w.tc = tc; 1630 1583 atomic_set(&w.complete, 0); 1631 1584 init_waitqueue_head(&w.wait); ··· 3108 3061 /*---------------------------------------------------------------- 3109 3062 * Thin target methods 3110 3063 *--------------------------------------------------------------*/ 3064 + static void thin_get(struct thin_c *tc) 3065 + { 3066 + atomic_inc(&tc->refcount); 3067 + } 3068 + 3069 + static void thin_put(struct thin_c *tc) 3070 + { 3071 + if (atomic_dec_and_test(&tc->refcount)) 3072 + complete(&tc->can_destroy); 3073 + } 3074 + 3111 3075 static void thin_dtr(struct dm_target *ti) 3112 3076 { 3113 3077 struct thin_c *tc = ti->private; 3114 3078 unsigned long flags; 3079 + 3080 + thin_put(tc); 3081 + wait_for_completion(&tc->can_destroy); 3115 3082 3116 3083 spin_lock_irqsave(&tc->pool->lock, flags); 3117 3084 list_del_rcu(&tc->list); ··· 3162 3101 struct thin_c *tc; 3163 3102 struct dm_dev *pool_dev, *origin_dev; 3164 3103 struct mapped_device *pool_md; 3104 + unsigned long flags; 3165 3105 3166 3106 mutex_lock(&dm_thin_pool_table.mutex); 3167 3107 ··· 3253 3191 3254 3192 mutex_unlock(&dm_thin_pool_table.mutex); 3255 3193 3256 - spin_lock(&tc->pool->lock); 3194 + atomic_set(&tc->refcount, 1); 3195 + init_completion(&tc->can_destroy); 3196 + 3197 + spin_lock_irqsave(&tc->pool->lock, flags); 3257 3198 list_add_tail_rcu(&tc->list, &tc->pool->active_thins); 3258 - spin_unlock(&tc->pool->lock); 3199 + spin_unlock_irqrestore(&tc->pool->lock, flags); 3259 3200 /* 3260 3201 * This synchronize_rcu() call is needed here otherwise we risk a 3261 3202 * wake_worker() call finding no bios to process (because the newly
+9 -6
drivers/md/dm-verity.c
··· 330 330 return r; 331 331 } 332 332 } 333 - 334 333 todo = 1 << v->data_dev_block_bits; 335 - while (io->iter.bi_size) { 334 + do { 336 335 u8 *page; 336 + unsigned len; 337 337 struct bio_vec bv = bio_iter_iovec(bio, io->iter); 338 338 339 339 page = kmap_atomic(bv.bv_page); 340 - r = crypto_shash_update(desc, page + bv.bv_offset, 341 - bv.bv_len); 340 + len = bv.bv_len; 341 + if (likely(len >= todo)) 342 + len = todo; 343 + r = crypto_shash_update(desc, page + bv.bv_offset, len); 342 344 kunmap_atomic(page); 343 345 344 346 if (r < 0) { ··· 348 346 return r; 349 347 } 350 348 351 - bio_advance_iter(bio, &io->iter, bv.bv_len); 352 - } 349 + bio_advance_iter(bio, &io->iter, len); 350 + todo -= len; 351 + } while (todo); 353 352 354 353 if (!v->version) { 355 354 r = crypto_shash_update(desc, v->salt, v->salt_size);