aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-10-09 19:58:11 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-10-09 19:58:11 -0400
commit0444555670350b419496686f4012b9cef808c105 (patch)
treee9f20837bc0772829c6585ef21d70ee510a0e172
parent175d58cfed70f132b8d4df39e19267ad6094bd16 (diff)
parentb0d3cc011e532d8c9db76cf717bcafa53c135595 (diff)
Merge tag 'dm-4.3-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm
Pull dm fixes from Mike Snitzer: "Three stable fixes: - DM core AB-BA deadlock fix in the device destruction path (vs device creation's DM table swap). - DM raid fix to properly round up the region_size to the next power-of-2. - DM cache fix for a NULL pointer seen while switching from the "cleaner" cache policy. Two fixes for regressions introduced during the 4.3 merge: - request-based DM error propagation regressed due to incorrect changes introduced when adding the bi_error field to bio. - DM snapshot fix to only support snapshots that overflow if the client (e.g. lvm2) is prepared to deal with the associated snapshot status interface change" * tag 'dm-4.3-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm: dm snapshot: add new persistent store option to support overflow dm cache: fix NULL pointer when switching from cleaner policy dm: fix request-based dm error reporting dm raid: fix round up of default region size dm: fix AB-BA deadlock in __dm_destroy()
-rw-r--r--Documentation/device-mapper/snapshot.txt10
-rw-r--r--drivers/md/dm-cache-policy-cleaner.c2
-rw-r--r--drivers/md/dm-exception-store.c6
-rw-r--r--drivers/md/dm-exception-store.h5
-rw-r--r--drivers/md/dm-raid.c3
-rw-r--r--drivers/md/dm-snap-persistent.c17
-rw-r--r--drivers/md/dm-snap-transient.c3
-rw-r--r--drivers/md/dm-snap.c14
-rw-r--r--drivers/md/dm.c11
9 files changed, 44 insertions, 27 deletions
diff --git a/Documentation/device-mapper/snapshot.txt b/Documentation/device-mapper/snapshot.txt
index 0d5bc46dc167..ad6949bff2e3 100644
--- a/Documentation/device-mapper/snapshot.txt
+++ b/Documentation/device-mapper/snapshot.txt
@@ -41,9 +41,13 @@ useless and be disabled, returning errors. So it is important to monitor
41the amount of free space and expand the <COW device> before it fills up. 41the amount of free space and expand the <COW device> before it fills up.
42 42
43<persistent?> is P (Persistent) or N (Not persistent - will not survive 43<persistent?> is P (Persistent) or N (Not persistent - will not survive
44after reboot). 44after reboot). O (Overflow) can be added as a persistent store option
45The difference is that for transient snapshots less metadata must be 45to allow userspace to advertise its support for seeing "Overflow" in the
46saved on disk - they can be kept in memory by the kernel. 46snapshot status. So supported store types are "P", "PO" and "N".
47
48The difference between persistent and transient is with transient
49snapshots less metadata must be saved on disk - they can be kept in
50memory by the kernel.
47 51
48 52
49* snapshot-merge <origin> <COW device> <persistent> <chunksize> 53* snapshot-merge <origin> <COW device> <persistent> <chunksize>
diff --git a/drivers/md/dm-cache-policy-cleaner.c b/drivers/md/dm-cache-policy-cleaner.c
index 240c9f0e85e7..8a096456579b 100644
--- a/drivers/md/dm-cache-policy-cleaner.c
+++ b/drivers/md/dm-cache-policy-cleaner.c
@@ -436,7 +436,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size,
436static struct dm_cache_policy_type wb_policy_type = { 436static struct dm_cache_policy_type wb_policy_type = {
437 .name = "cleaner", 437 .name = "cleaner",
438 .version = {1, 0, 0}, 438 .version = {1, 0, 0},
439 .hint_size = 0, 439 .hint_size = 4,
440 .owner = THIS_MODULE, 440 .owner = THIS_MODULE,
441 .create = wb_create 441 .create = wb_create
442}; 442};
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index ebaa4f803eec..192bb8beeb6b 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -203,7 +203,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
203 return -EINVAL; 203 return -EINVAL;
204 } 204 }
205 205
206 tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL); 206 tmp_store = kzalloc(sizeof(*tmp_store), GFP_KERNEL);
207 if (!tmp_store) { 207 if (!tmp_store) {
208 ti->error = "Exception store allocation failed"; 208 ti->error = "Exception store allocation failed";
209 return -ENOMEM; 209 return -ENOMEM;
@@ -215,7 +215,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
215 else if (persistent == 'N') 215 else if (persistent == 'N')
216 type = get_type("N"); 216 type = get_type("N");
217 else { 217 else {
218 ti->error = "Persistent flag is not P or N"; 218 ti->error = "Exception store type is not P or N";
219 r = -EINVAL; 219 r = -EINVAL;
220 goto bad_type; 220 goto bad_type;
221 } 221 }
@@ -233,7 +233,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
233 if (r) 233 if (r)
234 goto bad; 234 goto bad;
235 235
236 r = type->ctr(tmp_store, 0, NULL); 236 r = type->ctr(tmp_store, (strlen(argv[0]) > 1 ? &argv[0][1] : NULL));
237 if (r) { 237 if (r) {
238 ti->error = "Exception store type constructor failed"; 238 ti->error = "Exception store type constructor failed";
239 goto bad; 239 goto bad;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index 0b2536247cf5..fae34e7a0b1e 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -42,8 +42,7 @@ struct dm_exception_store_type {
42 const char *name; 42 const char *name;
43 struct module *module; 43 struct module *module;
44 44
45 int (*ctr) (struct dm_exception_store *store, 45 int (*ctr) (struct dm_exception_store *store, char *options);
46 unsigned argc, char **argv);
47 46
48 /* 47 /*
49 * Destroys this object when you've finished with it. 48 * Destroys this object when you've finished with it.
@@ -123,6 +122,8 @@ struct dm_exception_store {
123 unsigned chunk_shift; 122 unsigned chunk_shift;
124 123
125 void *context; 124 void *context;
125
126 bool userspace_supports_overflow;
126}; 127};
127 128
128/* 129/*
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 97e165183e79..a0901214aef5 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -329,8 +329,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size)
329 */ 329 */
330 if (min_region_size > (1 << 13)) { 330 if (min_region_size > (1 << 13)) {
331 /* If not a power of 2, make it the next power of 2 */ 331 /* If not a power of 2, make it the next power of 2 */
332 if (min_region_size & (min_region_size - 1)) 332 region_size = roundup_pow_of_two(min_region_size);
333 region_size = 1 << fls(region_size);
334 DMINFO("Choosing default region size of %lu sectors", 333 DMINFO("Choosing default region size of %lu sectors",
335 region_size); 334 region_size);
336 } else { 335 } else {
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index bf71583296f7..aeacad9be51d 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -7,6 +7,7 @@
7 7
8#include "dm-exception-store.h" 8#include "dm-exception-store.h"
9 9
10#include <linux/ctype.h>
10#include <linux/mm.h> 11#include <linux/mm.h>
11#include <linux/pagemap.h> 12#include <linux/pagemap.h>
12#include <linux/vmalloc.h> 13#include <linux/vmalloc.h>
@@ -843,8 +844,7 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
843 DMWARN("write header failed"); 844 DMWARN("write header failed");
844} 845}
845 846
846static int persistent_ctr(struct dm_exception_store *store, 847static int persistent_ctr(struct dm_exception_store *store, char *options)
847 unsigned argc, char **argv)
848{ 848{
849 struct pstore *ps; 849 struct pstore *ps;
850 850
@@ -873,6 +873,16 @@ static int persistent_ctr(struct dm_exception_store *store,
873 return -ENOMEM; 873 return -ENOMEM;
874 } 874 }
875 875
876 if (options) {
877 char overflow = toupper(options[0]);
878 if (overflow == 'O')
879 store->userspace_supports_overflow = true;
880 else {
881 DMERR("Unsupported persistent store option: %s", options);
882 return -EINVAL;
883 }
884 }
885
876 store->context = ps; 886 store->context = ps;
877 887
878 return 0; 888 return 0;
@@ -888,7 +898,8 @@ static unsigned persistent_status(struct dm_exception_store *store,
888 case STATUSTYPE_INFO: 898 case STATUSTYPE_INFO:
889 break; 899 break;
890 case STATUSTYPE_TABLE: 900 case STATUSTYPE_TABLE:
891 DMEMIT(" P %llu", (unsigned long long)store->chunk_size); 901 DMEMIT(" %s %llu", store->userspace_supports_overflow ? "PO" : "P",
902 (unsigned long long)store->chunk_size);
892 } 903 }
893 904
894 return sz; 905 return sz;
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 1ce9a2586e41..9b7c8c8049d6 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -70,8 +70,7 @@ static void transient_usage(struct dm_exception_store *store,
70 *metadata_sectors = 0; 70 *metadata_sectors = 0;
71} 71}
72 72
73static int transient_ctr(struct dm_exception_store *store, 73static int transient_ctr(struct dm_exception_store *store, char *options)
74 unsigned argc, char **argv)
75{ 74{
76 struct transient_c *tc; 75 struct transient_c *tc;
77 76
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index c0bcd6516dfe..c06b74e91cd6 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1098,7 +1098,7 @@ static void stop_merge(struct dm_snapshot *s)
1098} 1098}
1099 1099
1100/* 1100/*
1101 * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size> 1101 * Construct a snapshot mapping: <origin_dev> <COW-dev> <p|po|n> <chunk-size>
1102 */ 1102 */
1103static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) 1103static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1104{ 1104{
@@ -1302,6 +1302,7 @@ static void __handover_exceptions(struct dm_snapshot *snap_src,
1302 1302
1303 u.store_swap = snap_dest->store; 1303 u.store_swap = snap_dest->store;
1304 snap_dest->store = snap_src->store; 1304 snap_dest->store = snap_src->store;
1305 snap_dest->store->userspace_supports_overflow = u.store_swap->userspace_supports_overflow;
1305 snap_src->store = u.store_swap; 1306 snap_src->store = u.store_swap;
1306 1307
1307 snap_dest->store->snap = snap_dest; 1308 snap_dest->store->snap = snap_dest;
@@ -1739,8 +1740,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
1739 1740
1740 pe = __find_pending_exception(s, pe, chunk); 1741 pe = __find_pending_exception(s, pe, chunk);
1741 if (!pe) { 1742 if (!pe) {
1742 s->snapshot_overflowed = 1; 1743 if (s->store->userspace_supports_overflow) {
1743 DMERR("Snapshot overflowed: Unable to allocate exception."); 1744 s->snapshot_overflowed = 1;
1745 DMERR("Snapshot overflowed: Unable to allocate exception.");
1746 } else
1747 __invalidate_snapshot(s, -ENOMEM);
1744 r = -EIO; 1748 r = -EIO;
1745 goto out_unlock; 1749 goto out_unlock;
1746 } 1750 }
@@ -2365,7 +2369,7 @@ static struct target_type origin_target = {
2365 2369
2366static struct target_type snapshot_target = { 2370static struct target_type snapshot_target = {
2367 .name = "snapshot", 2371 .name = "snapshot",
2368 .version = {1, 14, 0}, 2372 .version = {1, 15, 0},
2369 .module = THIS_MODULE, 2373 .module = THIS_MODULE,
2370 .ctr = snapshot_ctr, 2374 .ctr = snapshot_ctr,
2371 .dtr = snapshot_dtr, 2375 .dtr = snapshot_dtr,
@@ -2379,7 +2383,7 @@ static struct target_type snapshot_target = {
2379 2383
2380static struct target_type merge_target = { 2384static struct target_type merge_target = {
2381 .name = dm_snapshot_merge_target_name, 2385 .name = dm_snapshot_merge_target_name,
2382 .version = {1, 3, 0}, 2386 .version = {1, 4, 0},
2383 .module = THIS_MODULE, 2387 .module = THIS_MODULE,
2384 .ctr = snapshot_ctr, 2388 .ctr = snapshot_ctr,
2385 .dtr = snapshot_dtr, 2389 .dtr = snapshot_dtr,
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 6264781dc69a..1b5c6047e4f1 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1001,6 +1001,7 @@ static void end_clone_bio(struct bio *clone)
1001 struct dm_rq_target_io *tio = info->tio; 1001 struct dm_rq_target_io *tio = info->tio;
1002 struct bio *bio = info->orig; 1002 struct bio *bio = info->orig;
1003 unsigned int nr_bytes = info->orig->bi_iter.bi_size; 1003 unsigned int nr_bytes = info->orig->bi_iter.bi_size;
1004 int error = clone->bi_error;
1004 1005
1005 bio_put(clone); 1006 bio_put(clone);
1006 1007
@@ -1011,13 +1012,13 @@ static void end_clone_bio(struct bio *clone)
1011 * the remainder. 1012 * the remainder.
1012 */ 1013 */
1013 return; 1014 return;
1014 else if (bio->bi_error) { 1015 else if (error) {
1015 /* 1016 /*
1016 * Don't notice the error to the upper layer yet. 1017 * Don't notice the error to the upper layer yet.
1017 * The error handling decision is made by the target driver, 1018 * The error handling decision is made by the target driver,
1018 * when the request is completed. 1019 * when the request is completed.
1019 */ 1020 */
1020 tio->error = bio->bi_error; 1021 tio->error = error;
1021 return; 1022 return;
1022 } 1023 }
1023 1024
@@ -2837,8 +2838,6 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
2837 2838
2838 might_sleep(); 2839 might_sleep();
2839 2840
2840 map = dm_get_live_table(md, &srcu_idx);
2841
2842 spin_lock(&_minor_lock); 2841 spin_lock(&_minor_lock);
2843 idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); 2842 idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
2844 set_bit(DMF_FREEING, &md->flags); 2843 set_bit(DMF_FREEING, &md->flags);
@@ -2852,14 +2851,14 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
2852 * do not race with internal suspend. 2851 * do not race with internal suspend.
2853 */ 2852 */
2854 mutex_lock(&md->suspend_lock); 2853 mutex_lock(&md->suspend_lock);
2854 map = dm_get_live_table(md, &srcu_idx);
2855 if (!dm_suspended_md(md)) { 2855 if (!dm_suspended_md(md)) {
2856 dm_table_presuspend_targets(map); 2856 dm_table_presuspend_targets(map);
2857 dm_table_postsuspend_targets(map); 2857 dm_table_postsuspend_targets(map);
2858 } 2858 }
2859 mutex_unlock(&md->suspend_lock);
2860
2861 /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ 2859 /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
2862 dm_put_live_table(md, srcu_idx); 2860 dm_put_live_table(md, srcu_idx);
2861 mutex_unlock(&md->suspend_lock);
2863 2862
2864 /* 2863 /*
2865 * Rare, but there may be I/O requests still going to complete, 2864 * Rare, but there may be I/O requests still going to complete,