Commit 44bbd7ac2658eb1118342493026ef141e259b739
Exists in
master
and in
7 other branches
Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
* git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm: dm stripe: implement merge method dm mpath: allow table load with no priority groups dm mpath: fail message ioctl if specified path is not valid dm ioctl: add flag to wipe buffers for secure data dm ioctl: prepare for crypt key wiping dm crypt: wipe keys string immediately after key is set dm: add flakey target dm: fix opening log and cow devices for read only tables
Showing 11 changed files Side-by-side Diff
Documentation/device-mapper/dm-flakey.txt
1 | +dm-flakey | |
2 | +========= | |
3 | + | |
4 | +This target is the same as the linear target except that it returns I/O | |
5 | +errors periodically. It's been found useful in simulating failing | |
6 | +devices for testing purposes. | |
7 | + | |
8 | +Starting from the time the table is loaded, the device is available for | |
9 | +<up interval> seconds, then returns errors for <down interval> seconds, | |
10 | +and then this cycle repeats. | |
11 | + | |
12 | +Parameters: <dev path> <offset> <up interval> <down interval> | |
13 | + <dev path>: Full pathname to the underlying block-device, or a | |
14 | + "major:minor" device-number. | |
15 | + <offset>: Starting sector within the device. | |
16 | + <up interval>: Number of seconds device is available. | |
17 | + <down interval>: Number of seconds device returns errors. |
drivers/md/Kconfig
... | ... | @@ -327,5 +327,11 @@ |
327 | 327 | ---help--- |
328 | 328 | Generate udev events for DM events. |
329 | 329 | |
330 | +config DM_FLAKEY | |
331 | + tristate "Flakey target (EXPERIMENTAL)" | |
332 | + depends on BLK_DEV_DM && EXPERIMENTAL | |
333 | + ---help--- | |
334 | + A target that intermittently fails I/O for debugging purposes. | |
335 | + | |
330 | 336 | endif # MD |
drivers/md/Makefile
... | ... | @@ -29,6 +29,7 @@ |
29 | 29 | obj-$(CONFIG_BLK_DEV_DM) += dm-mod.o |
30 | 30 | obj-$(CONFIG_DM_CRYPT) += dm-crypt.o |
31 | 31 | obj-$(CONFIG_DM_DELAY) += dm-delay.o |
32 | +obj-$(CONFIG_DM_FLAKEY) += dm-flakey.o | |
32 | 33 | obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o |
33 | 34 | obj-$(CONFIG_DM_MULTIPATH_QL) += dm-queue-length.o |
34 | 35 | obj-$(CONFIG_DM_MULTIPATH_ST) += dm-service-time.o |
drivers/md/dm-crypt.c
... | ... | @@ -1324,20 +1324,29 @@ |
1324 | 1324 | |
1325 | 1325 | static int crypt_set_key(struct crypt_config *cc, char *key) |
1326 | 1326 | { |
1327 | + int r = -EINVAL; | |
1328 | + int key_string_len = strlen(key); | |
1329 | + | |
1327 | 1330 | /* The key size may not be changed. */ |
1328 | - if (cc->key_size != (strlen(key) >> 1)) | |
1329 | - return -EINVAL; | |
1331 | + if (cc->key_size != (key_string_len >> 1)) | |
1332 | + goto out; | |
1330 | 1333 | |
1331 | 1334 | /* Hyphen (which gives a key_size of zero) means there is no key. */ |
1332 | 1335 | if (!cc->key_size && strcmp(key, "-")) |
1333 | - return -EINVAL; | |
1336 | + goto out; | |
1334 | 1337 | |
1335 | 1338 | if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0) |
1336 | - return -EINVAL; | |
1339 | + goto out; | |
1337 | 1340 | |
1338 | 1341 | set_bit(DM_CRYPT_KEY_VALID, &cc->flags); |
1339 | 1342 | |
1340 | - return crypt_setkey_allcpus(cc); | |
1343 | + r = crypt_setkey_allcpus(cc); | |
1344 | + | |
1345 | +out: | |
1346 | + /* Hex key string not needed after here, so wipe it. */ | |
1347 | + memset(key, '0', key_string_len); | |
1348 | + | |
1349 | + return r; | |
1341 | 1350 | } |
1342 | 1351 | |
1343 | 1352 | static int crypt_wipe_key(struct crypt_config *cc) |
drivers/md/dm-flakey.c
1 | +/* | |
2 | + * Copyright (C) 2003 Sistina Software (UK) Limited. | |
3 | + * Copyright (C) 2004, 2010 Red Hat, Inc. All rights reserved. | |
4 | + * | |
5 | + * This file is released under the GPL. | |
6 | + */ | |
7 | + | |
8 | +#include <linux/device-mapper.h> | |
9 | + | |
10 | +#include <linux/module.h> | |
11 | +#include <linux/init.h> | |
12 | +#include <linux/blkdev.h> | |
13 | +#include <linux/bio.h> | |
14 | +#include <linux/slab.h> | |
15 | + | |
16 | +#define DM_MSG_PREFIX "flakey" | |
17 | + | |
18 | +/* | |
19 | + * Flakey: Used for testing only, simulates intermittent, | |
20 | + * catastrophic device failure. | |
21 | + */ | |
22 | +struct flakey_c { | |
23 | + struct dm_dev *dev; | |
24 | + unsigned long start_time; | |
25 | + sector_t start; | |
26 | + unsigned up_interval; | |
27 | + unsigned down_interval; | |
28 | +}; | |
29 | + | |
30 | +/* | |
31 | + * Construct a flakey mapping: <dev_path> <offset> <up interval> <down interval> | |
32 | + */ | |
33 | +static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |
34 | +{ | |
35 | + struct flakey_c *fc; | |
36 | + unsigned long long tmp; | |
37 | + | |
38 | + if (argc != 4) { | |
39 | + ti->error = "dm-flakey: Invalid argument count"; | |
40 | + return -EINVAL; | |
41 | + } | |
42 | + | |
43 | + fc = kmalloc(sizeof(*fc), GFP_KERNEL); | |
44 | + if (!fc) { | |
45 | + ti->error = "dm-flakey: Cannot allocate linear context"; | |
46 | + return -ENOMEM; | |
47 | + } | |
48 | + fc->start_time = jiffies; | |
49 | + | |
50 | + if (sscanf(argv[1], "%llu", &tmp) != 1) { | |
51 | + ti->error = "dm-flakey: Invalid device sector"; | |
52 | + goto bad; | |
53 | + } | |
54 | + fc->start = tmp; | |
55 | + | |
56 | + if (sscanf(argv[2], "%u", &fc->up_interval) != 1) { | |
57 | + ti->error = "dm-flakey: Invalid up interval"; | |
58 | + goto bad; | |
59 | + } | |
60 | + | |
61 | + if (sscanf(argv[3], "%u", &fc->down_interval) != 1) { | |
62 | + ti->error = "dm-flakey: Invalid down interval"; | |
63 | + goto bad; | |
64 | + } | |
65 | + | |
66 | + if (!(fc->up_interval + fc->down_interval)) { | |
67 | + ti->error = "dm-flakey: Total (up + down) interval is zero"; | |
68 | + goto bad; | |
69 | + } | |
70 | + | |
71 | + if (fc->up_interval + fc->down_interval < fc->up_interval) { | |
72 | + ti->error = "dm-flakey: Interval overflow"; | |
73 | + goto bad; | |
74 | + } | |
75 | + | |
76 | + if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &fc->dev)) { | |
77 | + ti->error = "dm-flakey: Device lookup failed"; | |
78 | + goto bad; | |
79 | + } | |
80 | + | |
81 | + ti->num_flush_requests = 1; | |
82 | + ti->private = fc; | |
83 | + return 0; | |
84 | + | |
85 | +bad: | |
86 | + kfree(fc); | |
87 | + return -EINVAL; | |
88 | +} | |
89 | + | |
90 | +static void flakey_dtr(struct dm_target *ti) | |
91 | +{ | |
92 | + struct flakey_c *fc = ti->private; | |
93 | + | |
94 | + dm_put_device(ti, fc->dev); | |
95 | + kfree(fc); | |
96 | +} | |
97 | + | |
98 | +static sector_t flakey_map_sector(struct dm_target *ti, sector_t bi_sector) | |
99 | +{ | |
100 | + struct flakey_c *fc = ti->private; | |
101 | + | |
102 | + return fc->start + (bi_sector - ti->begin); | |
103 | +} | |
104 | + | |
105 | +static void flakey_map_bio(struct dm_target *ti, struct bio *bio) | |
106 | +{ | |
107 | + struct flakey_c *fc = ti->private; | |
108 | + | |
109 | + bio->bi_bdev = fc->dev->bdev; | |
110 | + if (bio_sectors(bio)) | |
111 | + bio->bi_sector = flakey_map_sector(ti, bio->bi_sector); | |
112 | +} | |
113 | + | |
114 | +static int flakey_map(struct dm_target *ti, struct bio *bio, | |
115 | + union map_info *map_context) | |
116 | +{ | |
117 | + struct flakey_c *fc = ti->private; | |
118 | + unsigned elapsed; | |
119 | + | |
120 | + /* Are we alive ? */ | |
121 | + elapsed = (jiffies - fc->start_time) / HZ; | |
122 | + if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) | |
123 | + return -EIO; | |
124 | + | |
125 | + flakey_map_bio(ti, bio); | |
126 | + | |
127 | + return DM_MAPIO_REMAPPED; | |
128 | +} | |
129 | + | |
130 | +static int flakey_status(struct dm_target *ti, status_type_t type, | |
131 | + char *result, unsigned int maxlen) | |
132 | +{ | |
133 | + struct flakey_c *fc = ti->private; | |
134 | + | |
135 | + switch (type) { | |
136 | + case STATUSTYPE_INFO: | |
137 | + result[0] = '\0'; | |
138 | + break; | |
139 | + | |
140 | + case STATUSTYPE_TABLE: | |
141 | + snprintf(result, maxlen, "%s %llu %u %u", fc->dev->name, | |
142 | + (unsigned long long)fc->start, fc->up_interval, | |
143 | + fc->down_interval); | |
144 | + break; | |
145 | + } | |
146 | + return 0; | |
147 | +} | |
148 | + | |
149 | +static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg) | |
150 | +{ | |
151 | + struct flakey_c *fc = ti->private; | |
152 | + | |
153 | + return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg); | |
154 | +} | |
155 | + | |
156 | +static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | |
157 | + struct bio_vec *biovec, int max_size) | |
158 | +{ | |
159 | + struct flakey_c *fc = ti->private; | |
160 | + struct request_queue *q = bdev_get_queue(fc->dev->bdev); | |
161 | + | |
162 | + if (!q->merge_bvec_fn) | |
163 | + return max_size; | |
164 | + | |
165 | + bvm->bi_bdev = fc->dev->bdev; | |
166 | + bvm->bi_sector = flakey_map_sector(ti, bvm->bi_sector); | |
167 | + | |
168 | + return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); | |
169 | +} | |
170 | + | |
171 | +static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data) | |
172 | +{ | |
173 | + struct flakey_c *fc = ti->private; | |
174 | + | |
175 | + return fn(ti, fc->dev, fc->start, ti->len, data); | |
176 | +} | |
177 | + | |
178 | +static struct target_type flakey_target = { | |
179 | + .name = "flakey", | |
180 | + .version = {1, 1, 0}, | |
181 | + .module = THIS_MODULE, | |
182 | + .ctr = flakey_ctr, | |
183 | + .dtr = flakey_dtr, | |
184 | + .map = flakey_map, | |
185 | + .status = flakey_status, | |
186 | + .ioctl = flakey_ioctl, | |
187 | + .merge = flakey_merge, | |
188 | + .iterate_devices = flakey_iterate_devices, | |
189 | +}; | |
190 | + | |
191 | +static int __init dm_flakey_init(void) | |
192 | +{ | |
193 | + int r = dm_register_target(&flakey_target); | |
194 | + | |
195 | + if (r < 0) | |
196 | + DMERR("register failed %d", r); | |
197 | + | |
198 | + return r; | |
199 | +} | |
200 | + | |
201 | +static void __exit dm_flakey_exit(void) | |
202 | +{ | |
203 | + dm_unregister_target(&flakey_target); | |
204 | +} | |
205 | + | |
206 | +/* Module hooks */ | |
207 | +module_init(dm_flakey_init); | |
208 | +module_exit(dm_flakey_exit); | |
209 | + | |
210 | +MODULE_DESCRIPTION(DM_NAME " flakey target"); | |
211 | +MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); | |
212 | +MODULE_LICENSE("GPL"); |
drivers/md/dm-ioctl.c
... | ... | @@ -1501,14 +1501,10 @@ |
1501 | 1501 | return r; |
1502 | 1502 | } |
1503 | 1503 | |
1504 | -static void free_params(struct dm_ioctl *param) | |
1505 | -{ | |
1506 | - vfree(param); | |
1507 | -} | |
1508 | - | |
1509 | 1504 | static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param) |
1510 | 1505 | { |
1511 | 1506 | struct dm_ioctl tmp, *dmi; |
1507 | + int secure_data; | |
1512 | 1508 | |
1513 | 1509 | if (copy_from_user(&tmp, user, sizeof(tmp) - sizeof(tmp.data))) |
1514 | 1510 | return -EFAULT; |
1515 | 1511 | |
1516 | 1512 | |
1517 | 1513 | |
1518 | 1514 | |
... | ... | @@ -1516,17 +1512,30 @@ |
1516 | 1512 | if (tmp.data_size < (sizeof(tmp) - sizeof(tmp.data))) |
1517 | 1513 | return -EINVAL; |
1518 | 1514 | |
1515 | + secure_data = tmp.flags & DM_SECURE_DATA_FLAG; | |
1516 | + | |
1519 | 1517 | dmi = vmalloc(tmp.data_size); |
1520 | - if (!dmi) | |
1518 | + if (!dmi) { | |
1519 | + if (secure_data && clear_user(user, tmp.data_size)) | |
1520 | + return -EFAULT; | |
1521 | 1521 | return -ENOMEM; |
1522 | - | |
1523 | - if (copy_from_user(dmi, user, tmp.data_size)) { | |
1524 | - vfree(dmi); | |
1525 | - return -EFAULT; | |
1526 | 1522 | } |
1527 | 1523 | |
1524 | + if (copy_from_user(dmi, user, tmp.data_size)) | |
1525 | + goto bad; | |
1526 | + | |
1527 | + /* Wipe the user buffer so we do not return it to userspace */ | |
1528 | + if (secure_data && clear_user(user, tmp.data_size)) | |
1529 | + goto bad; | |
1530 | + | |
1528 | 1531 | *param = dmi; |
1529 | 1532 | return 0; |
1533 | + | |
1534 | +bad: | |
1535 | + if (secure_data) | |
1536 | + memset(dmi, 0, tmp.data_size); | |
1537 | + vfree(dmi); | |
1538 | + return -EFAULT; | |
1530 | 1539 | } |
1531 | 1540 | |
1532 | 1541 | static int validate_params(uint cmd, struct dm_ioctl *param) |
... | ... | @@ -1534,6 +1543,7 @@ |
1534 | 1543 | /* Always clear this flag */ |
1535 | 1544 | param->flags &= ~DM_BUFFER_FULL_FLAG; |
1536 | 1545 | param->flags &= ~DM_UEVENT_GENERATED_FLAG; |
1546 | + param->flags &= ~DM_SECURE_DATA_FLAG; | |
1537 | 1547 | |
1538 | 1548 | /* Ignores parameters */ |
1539 | 1549 | if (cmd == DM_REMOVE_ALL_CMD || |
1540 | 1550 | |
... | ... | @@ -1561,10 +1571,11 @@ |
1561 | 1571 | static int ctl_ioctl(uint command, struct dm_ioctl __user *user) |
1562 | 1572 | { |
1563 | 1573 | int r = 0; |
1574 | + int wipe_buffer; | |
1564 | 1575 | unsigned int cmd; |
1565 | 1576 | struct dm_ioctl *uninitialized_var(param); |
1566 | 1577 | ioctl_fn fn = NULL; |
1567 | - size_t param_size; | |
1578 | + size_t input_param_size; | |
1568 | 1579 | |
1569 | 1580 | /* only root can play with this */ |
1570 | 1581 | if (!capable(CAP_SYS_ADMIN)) |
1571 | 1582 | |
1572 | 1583 | |
... | ... | @@ -1611,13 +1622,15 @@ |
1611 | 1622 | if (r) |
1612 | 1623 | return r; |
1613 | 1624 | |
1625 | + input_param_size = param->data_size; | |
1626 | + wipe_buffer = param->flags & DM_SECURE_DATA_FLAG; | |
1627 | + | |
1614 | 1628 | r = validate_params(cmd, param); |
1615 | 1629 | if (r) |
1616 | 1630 | goto out; |
1617 | 1631 | |
1618 | - param_size = param->data_size; | |
1619 | 1632 | param->data_size = sizeof(*param); |
1620 | - r = fn(param, param_size); | |
1633 | + r = fn(param, input_param_size); | |
1621 | 1634 | |
1622 | 1635 | /* |
1623 | 1636 | * Copy the results back to userland. |
... | ... | @@ -1625,8 +1638,11 @@ |
1625 | 1638 | if (!r && copy_to_user(user, param, param->data_size)) |
1626 | 1639 | r = -EFAULT; |
1627 | 1640 | |
1628 | - out: | |
1629 | - free_params(param); | |
1641 | +out: | |
1642 | + if (wipe_buffer) | |
1643 | + memset(param, 0, input_param_size); | |
1644 | + | |
1645 | + vfree(param); | |
1630 | 1646 | return r; |
1631 | 1647 | } |
1632 | 1648 |
drivers/md/dm-log.c
drivers/md/dm-mpath.c
... | ... | @@ -844,8 +844,8 @@ |
844 | 844 | { |
845 | 845 | /* target parameters */ |
846 | 846 | static struct param _params[] = { |
847 | - {1, 1024, "invalid number of priority groups"}, | |
848 | - {1, 1024, "invalid initial priority group number"}, | |
847 | + {0, 1024, "invalid number of priority groups"}, | |
848 | + {0, 1024, "invalid initial priority group number"}, | |
849 | 849 | }; |
850 | 850 | |
851 | 851 | int r; |
... | ... | @@ -879,6 +879,13 @@ |
879 | 879 | if (r) |
880 | 880 | goto bad; |
881 | 881 | |
882 | + if ((!m->nr_priority_groups && next_pg_num) || | |
883 | + (m->nr_priority_groups && !next_pg_num)) { | |
884 | + ti->error = "invalid initial priority group"; | |
885 | + r = -EINVAL; | |
886 | + goto bad; | |
887 | + } | |
888 | + | |
882 | 889 | /* parse the priority groups */ |
883 | 890 | while (as.argc) { |
884 | 891 | struct priority_group *pg; |
... | ... | @@ -1065,7 +1072,7 @@ |
1065 | 1072 | static int action_dev(struct multipath *m, struct dm_dev *dev, |
1066 | 1073 | action_fn action) |
1067 | 1074 | { |
1068 | - int r = 0; | |
1075 | + int r = -EINVAL; | |
1069 | 1076 | struct pgpath *pgpath; |
1070 | 1077 | struct priority_group *pg; |
1071 | 1078 | |
... | ... | @@ -1415,7 +1422,7 @@ |
1415 | 1422 | else if (m->current_pg) |
1416 | 1423 | pg_num = m->current_pg->pg_num; |
1417 | 1424 | else |
1418 | - pg_num = 1; | |
1425 | + pg_num = (m->nr_priority_groups ? 1 : 0); | |
1419 | 1426 | |
1420 | 1427 | DMEMIT("%u ", pg_num); |
1421 | 1428 | |
... | ... | @@ -1669,7 +1676,7 @@ |
1669 | 1676 | *---------------------------------------------------------------*/ |
1670 | 1677 | static struct target_type multipath_target = { |
1671 | 1678 | .name = "multipath", |
1672 | - .version = {1, 2, 0}, | |
1679 | + .version = {1, 3, 0}, | |
1673 | 1680 | .module = THIS_MODULE, |
1674 | 1681 | .ctr = multipath_ctr, |
1675 | 1682 | .dtr = multipath_dtr, |
drivers/md/dm-snap.c
... | ... | @@ -1080,7 +1080,7 @@ |
1080 | 1080 | argv++; |
1081 | 1081 | argc--; |
1082 | 1082 | |
1083 | - r = dm_get_device(ti, cow_path, FMODE_READ | FMODE_WRITE, &s->cow); | |
1083 | + r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow); | |
1084 | 1084 | if (r) { |
1085 | 1085 | ti->error = "Cannot get COW device"; |
1086 | 1086 | goto bad_cow; |
drivers/md/dm-stripe.c
... | ... | @@ -396,9 +396,29 @@ |
396 | 396 | blk_limits_io_opt(limits, chunk_size * sc->stripes); |
397 | 397 | } |
398 | 398 | |
399 | +static int stripe_merge(struct dm_target *ti, struct bvec_merge_data *bvm, | |
400 | + struct bio_vec *biovec, int max_size) | |
401 | +{ | |
402 | + struct stripe_c *sc = ti->private; | |
403 | + sector_t bvm_sector = bvm->bi_sector; | |
404 | + uint32_t stripe; | |
405 | + struct request_queue *q; | |
406 | + | |
407 | + stripe_map_sector(sc, bvm_sector, &stripe, &bvm_sector); | |
408 | + | |
409 | + q = bdev_get_queue(sc->stripe[stripe].dev->bdev); | |
410 | + if (!q->merge_bvec_fn) | |
411 | + return max_size; | |
412 | + | |
413 | + bvm->bi_bdev = sc->stripe[stripe].dev->bdev; | |
414 | + bvm->bi_sector = sc->stripe[stripe].physical_start + bvm_sector; | |
415 | + | |
416 | + return min(max_size, q->merge_bvec_fn(q, bvm, biovec)); | |
417 | +} | |
418 | + | |
399 | 419 | static struct target_type stripe_target = { |
400 | 420 | .name = "striped", |
401 | - .version = {1, 3, 1}, | |
421 | + .version = {1, 4, 0}, | |
402 | 422 | .module = THIS_MODULE, |
403 | 423 | .ctr = stripe_ctr, |
404 | 424 | .dtr = stripe_dtr, |
... | ... | @@ -407,6 +427,7 @@ |
407 | 427 | .status = stripe_status, |
408 | 428 | .iterate_devices = stripe_iterate_devices, |
409 | 429 | .io_hints = stripe_io_hints, |
430 | + .merge = stripe_merge, | |
410 | 431 | }; |
411 | 432 | |
412 | 433 | int __init dm_stripe_init(void) |
include/linux/dm-ioctl.h
... | ... | @@ -267,9 +267,9 @@ |
267 | 267 | #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) |
268 | 268 | |
269 | 269 | #define DM_VERSION_MAJOR 4 |
270 | -#define DM_VERSION_MINOR 19 | |
271 | -#define DM_VERSION_PATCHLEVEL 1 | |
272 | -#define DM_VERSION_EXTRA "-ioctl (2011-01-07)" | |
270 | +#define DM_VERSION_MINOR 20 | |
271 | +#define DM_VERSION_PATCHLEVEL 0 | |
272 | +#define DM_VERSION_EXTRA "-ioctl (2011-02-02)" | |
273 | 273 | |
274 | 274 | /* Status bits */ |
275 | 275 | #define DM_READONLY_FLAG (1 << 0) /* In/Out */ |
... | ... | @@ -327,6 +327,12 @@ |
327 | 327 | * if no uuid was previously supplied: an existing uuid cannot be changed. |
328 | 328 | */ |
329 | 329 | #define DM_UUID_FLAG (1 << 14) /* In */ |
330 | + | |
331 | +/* | |
332 | + * If set, all buffers are wiped after use. Use when sending | |
333 | + * or requesting sensitive data such as an encryption key. | |
334 | + */ | |
335 | +#define DM_SECURE_DATA_FLAG (1 << 15) /* In */ | |
330 | 336 | |
331 | 337 | #endif /* _LINUX_DM_IOCTL_H */ |