aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-snap.c9
-rw-r--r--drivers/md/dm-table.c36
-rw-r--r--include/linux/device-mapper.h2
3 files changed, 35 insertions, 12 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 62479ac4baf7..70bb0e8b62ce 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1105,6 +1105,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1105 int i; 1105 int i;
1106 int r = -EINVAL; 1106 int r = -EINVAL;
1107 char *origin_path, *cow_path; 1107 char *origin_path, *cow_path;
1108 dev_t origin_dev, cow_dev;
1108 unsigned args_used, num_flush_bios = 1; 1109 unsigned args_used, num_flush_bios = 1;
1109 fmode_t origin_mode = FMODE_READ; 1110 fmode_t origin_mode = FMODE_READ;
1110 1111
@@ -1135,11 +1136,19 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1135 ti->error = "Cannot get origin device"; 1136 ti->error = "Cannot get origin device";
1136 goto bad_origin; 1137 goto bad_origin;
1137 } 1138 }
1139 origin_dev = s->origin->bdev->bd_dev;
1138 1140
1139 cow_path = argv[0]; 1141 cow_path = argv[0];
1140 argv++; 1142 argv++;
1141 argc--; 1143 argc--;
1142 1144
1145 cow_dev = dm_get_dev_t(cow_path);
1146 if (cow_dev && cow_dev == origin_dev) {
1147 ti->error = "COW device cannot be the same as origin device";
1148 r = -EINVAL;
1149 goto bad_cow;
1150 }
1151
1143 r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow); 1152 r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow);
1144 if (r) { 1153 if (r) {
1145 ti->error = "Cannot get COW device"; 1154 ti->error = "Cannot get COW device";
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 7210e5392cc4..f9e8f0bef332 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -365,6 +365,26 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
365} 365}
366 366
367/* 367/*
368 * Convert the path to a device
369 */
370dev_t dm_get_dev_t(const char *path)
371{
372 dev_t uninitialized_var(dev);
373 struct block_device *bdev;
374
375 bdev = lookup_bdev(path);
376 if (IS_ERR(bdev))
377 dev = name_to_dev_t(path);
378 else {
379 dev = bdev->bd_dev;
380 bdput(bdev);
381 }
382
383 return dev;
384}
385EXPORT_SYMBOL_GPL(dm_get_dev_t);
386
387/*
368 * Add a device to the list, or just increment the usage count if 388 * Add a device to the list, or just increment the usage count if
369 * it's already present. 389 * it's already present.
370 */ 390 */
@@ -372,23 +392,15 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
372 struct dm_dev **result) 392 struct dm_dev **result)
373{ 393{
374 int r; 394 int r;
375 dev_t uninitialized_var(dev); 395 dev_t dev;
376 struct dm_dev_internal *dd; 396 struct dm_dev_internal *dd;
377 struct dm_table *t = ti->table; 397 struct dm_table *t = ti->table;
378 struct block_device *bdev;
379 398
380 BUG_ON(!t); 399 BUG_ON(!t);
381 400
382 /* convert the path to a device */ 401 dev = dm_get_dev_t(path);
383 bdev = lookup_bdev(path); 402 if (!dev)
384 if (IS_ERR(bdev)) { 403 return -ENODEV;
385 dev = name_to_dev_t(path);
386 if (!dev)
387 return -ENODEV;
388 } else {
389 dev = bdev->bd_dev;
390 bdput(bdev);
391 }
392 404
393 dd = find_device(&t->devices, dev); 405 dd = find_device(&t->devices, dev);
394 if (!dd) { 406 if (!dd) {
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 82ae3b5e2c45..0830c9e86f0d 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -124,6 +124,8 @@ struct dm_dev {
124 char name[16]; 124 char name[16];
125}; 125};
126 126
127dev_t dm_get_dev_t(const char *path);
128
127/* 129/*
128 * Constructors should call these functions to ensure destination devices 130 * Constructors should call these functions to ensure destination devices
129 * are opened/closed correctly. 131 * are opened/closed correctly.