Ignore:
Timestamp:
Apr 16, 2017, 3:07:01 PM (3 months ago)
Author:
brainslayer
Message:

update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.18/drivers/md/dm.c

    r26746 r31869  
    13011301EXPORT_SYMBOL_GPL(dm_accept_partial_bio);
    13021302
     1303/*
     1304 * Flush current->bio_list when the target map method blocks.
     1305 * This fixes deadlocks in snapshot and possibly in other targets.
     1306 */
     1307struct dm_offload {
     1308        struct blk_plug plug;
     1309        struct blk_plug_cb cb;
     1310};
     1311
     1312static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
     1313{
     1314        struct dm_offload *o = container_of(cb, struct dm_offload, cb);
     1315        struct bio_list list;
     1316        struct bio *bio;
     1317
     1318        INIT_LIST_HEAD(&o->cb.list);
     1319
     1320        if (unlikely(!current->bio_list))
     1321                return;
     1322
     1323        list = *current->bio_list;
     1324        bio_list_init(current->bio_list);
     1325
     1326        while ((bio = bio_list_pop(&list))) {
     1327                struct bio_set *bs = bio->bi_pool;
     1328                if (unlikely(!bs) || bs == fs_bio_set) {
     1329                        bio_list_add(current->bio_list, bio);
     1330                        continue;
     1331                }
     1332
     1333                spin_lock(&bs->rescue_lock);
     1334                bio_list_add(&bs->rescue_list, bio);
     1335                queue_work(bs->rescue_workqueue, &bs->rescue_work);
     1336                spin_unlock(&bs->rescue_lock);
     1337        }
     1338}
     1339
     1340static void dm_offload_start(struct dm_offload *o)
     1341{
     1342        blk_start_plug(&o->plug);
     1343        o->cb.callback = flush_current_bio_list;
     1344        list_add(&o->cb.list, &current->plug->cb_list);
     1345}
     1346
     1347static void dm_offload_end(struct dm_offload *o)
     1348{
     1349        list_del(&o->cb.list);
     1350        blk_finish_plug(&o->plug);
     1351}
     1352
    13031353static void __map_bio(struct dm_target_io *tio)
    13041354{
     
    13061356        sector_t sector;
    13071357        struct mapped_device *md;
     1358        struct dm_offload o;
    13081359        struct bio *clone = &tio->clone;
    13091360        struct dm_target *ti = tio->ti;
     
    13181369        atomic_inc(&tio->io->io_count);
    13191370        sector = clone->bi_iter.bi_sector;
     1371
     1372        dm_offload_start(&o);
    13201373        r = ti->type->map(ti, clone);
     1374        dm_offload_end(&o);
     1375
    13211376        if (r == DM_MAPIO_REMAPPED) {
    13221377                /* the bio has been remapped so dispatch it */
Note: See TracChangeset for help on using the changeset viewer.