aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c49
1 files changed, 19 insertions, 30 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index dc48c2585feb..6963ad148408 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -75,7 +75,6 @@ union map_info *dm_get_mapinfo(struct bio *bio)
75 */ 75 */
76struct dm_wq_req { 76struct dm_wq_req {
77 enum { 77 enum {
78 DM_WQ_FLUSH_ALL,
79 DM_WQ_FLUSH_DEFERRED, 78 DM_WQ_FLUSH_DEFERRED,
80 } type; 79 } type;
81 struct work_struct work; 80 struct work_struct work;
@@ -150,40 +149,40 @@ static struct kmem_cache *_tio_cache;
150 149
151static int __init local_init(void) 150static int __init local_init(void)
152{ 151{
153 int r; 152 int r = -ENOMEM;
154 153
155 /* allocate a slab for the dm_ios */ 154 /* allocate a slab for the dm_ios */
156 _io_cache = KMEM_CACHE(dm_io, 0); 155 _io_cache = KMEM_CACHE(dm_io, 0);
157 if (!_io_cache) 156 if (!_io_cache)
158 return -ENOMEM; 157 return r;
159 158
160 /* allocate a slab for the target ios */ 159 /* allocate a slab for the target ios */
161 _tio_cache = KMEM_CACHE(dm_target_io, 0); 160 _tio_cache = KMEM_CACHE(dm_target_io, 0);
162 if (!_tio_cache) { 161 if (!_tio_cache)
163 kmem_cache_destroy(_io_cache); 162 goto out_free_io_cache;
164 return -ENOMEM;
165 }
166 163
167 r = dm_uevent_init(); 164 r = dm_uevent_init();
168 if (r) { 165 if (r)
169 kmem_cache_destroy(_tio_cache); 166 goto out_free_tio_cache;
170 kmem_cache_destroy(_io_cache);
171 return r;
172 }
173 167
174 _major = major; 168 _major = major;
175 r = register_blkdev(_major, _name); 169 r = register_blkdev(_major, _name);
176 if (r < 0) { 170 if (r < 0)
177 kmem_cache_destroy(_tio_cache); 171 goto out_uevent_exit;
178 kmem_cache_destroy(_io_cache);
179 dm_uevent_exit();
180 return r;
181 }
182 172
183 if (!_major) 173 if (!_major)
184 _major = r; 174 _major = r;
185 175
186 return 0; 176 return 0;
177
178out_uevent_exit:
179 dm_uevent_exit();
180out_free_tio_cache:
181 kmem_cache_destroy(_tio_cache);
182out_free_io_cache:
183 kmem_cache_destroy(_io_cache);
184
185 return r;
187} 186}
188 187
189static void local_exit(void) 188static void local_exit(void)
@@ -658,6 +657,7 @@ static struct bio *split_bvec(struct bio *bio, sector_t sector,
658 clone->bi_size = to_bytes(len); 657 clone->bi_size = to_bytes(len);
659 clone->bi_io_vec->bv_offset = offset; 658 clone->bi_io_vec->bv_offset = offset;
660 clone->bi_io_vec->bv_len = clone->bi_size; 659 clone->bi_io_vec->bv_len = clone->bi_size;
660 clone->bi_flags |= 1 << BIO_CLONED;
661 661
662 return clone; 662 return clone;
663} 663}
@@ -1383,9 +1383,6 @@ static void dm_wq_work(struct work_struct *work)
1383 1383
1384 down_write(&md->io_lock); 1384 down_write(&md->io_lock);
1385 switch (req->type) { 1385 switch (req->type) {
1386 case DM_WQ_FLUSH_ALL:
1387 __merge_pushback_list(md);
1388 /* pass through */
1389 case DM_WQ_FLUSH_DEFERRED: 1386 case DM_WQ_FLUSH_DEFERRED:
1390 __flush_deferred_io(md); 1387 __flush_deferred_io(md);
1391 break; 1388 break;
@@ -1515,7 +1512,7 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
1515 if (!md->suspended_bdev) { 1512 if (!md->suspended_bdev) {
1516 DMWARN("bdget failed in dm_suspend"); 1513 DMWARN("bdget failed in dm_suspend");
1517 r = -ENOMEM; 1514 r = -ENOMEM;
1518 goto flush_and_out; 1515 goto out;
1519 } 1516 }
1520 1517
1521 /* 1518 /*
@@ -1566,14 +1563,6 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
1566 1563
1567 set_bit(DMF_SUSPENDED, &md->flags); 1564 set_bit(DMF_SUSPENDED, &md->flags);
1568 1565
1569flush_and_out:
1570 if (r && noflush)
1571 /*
1572 * Because there may be already I/Os in the pushback list,
1573 * flush them before return.
1574 */
1575 dm_queue_flush(md, DM_WQ_FLUSH_ALL, NULL);
1576
1577out: 1566out:
1578 if (r && md->suspended_bdev) { 1567 if (r && md->suspended_bdev) {
1579 bdput(md->suspended_bdev); 1568 bdput(md->suspended_bdev);