aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan E Brassow <jbrassow@redhat.com>2011-10-31 16:21:24 -0400
committerAlasdair G Kergon <agk@redhat.com>2011-10-31 16:21:24 -0400
commit5a25f0eb707bbb4a5aaaf19c933605a6dbaf77a5 (patch)
tree62f9af5013d252b0fdff5449b3adcaeadfff31aa /drivers/md
parentb89544575d0096735edc9b0ad187e635487905ad (diff)
dm log userspace: add log device dependency
Allow userspace dm log implementations to register their log device so it is no longer missing from the list of device dependencies. When device mapper targets use a device they normally call dm_get_device which includes it in the device list returned to userspace applications such as LVM through the DM_TABLE_DEPS ioctl. Userspace log devices don't use dm_get_device as userspace opens them so they are missing from the list of dependencies. This patch extends the DM_ULOG_CTR operation to allow userspace to respond with the name of the log device (if appropriate) to be registered via 'dm_get_device'. DM_ULOG_REQUEST_VERSION is incremented. This is backwards compatible. If the kernel and userspace log server have both been updated, the new information will be passed down to the kernel and the device will be registered. If the kernel is new, but the log server is old, the log server will not pass down any device information and the kernel will simply bypass the device registration as before. If the kernel is old but the log server is new, the log server will see the old version number and not pass the device info. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-log-userspace-base.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index 3c27978890b7..8db3862dade5 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -30,6 +30,7 @@ struct flush_entry {
30 30
31struct log_c { 31struct log_c {
32 struct dm_target *ti; 32 struct dm_target *ti;
33 struct dm_dev *log_dev;
33 uint32_t region_size; 34 uint32_t region_size;
34 region_t region_count; 35 region_t region_count;
35 uint64_t luid; 36 uint64_t luid;
@@ -161,13 +162,15 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
161 struct log_c *lc = NULL; 162 struct log_c *lc = NULL;
162 uint64_t rdata; 163 uint64_t rdata;
163 size_t rdata_size = sizeof(rdata); 164 size_t rdata_size = sizeof(rdata);
165 char *devices_rdata = NULL;
166 size_t devices_rdata_size = DM_NAME_LEN;
164 167
165 if (argc < 3) { 168 if (argc < 3) {
166 DMWARN("Too few arguments to userspace dirty log"); 169 DMWARN("Too few arguments to userspace dirty log");
167 return -EINVAL; 170 return -EINVAL;
168 } 171 }
169 172
170 lc = kmalloc(sizeof(*lc), GFP_KERNEL); 173 lc = kzalloc(sizeof(*lc), GFP_KERNEL);
171 if (!lc) { 174 if (!lc) {
172 DMWARN("Unable to allocate userspace log context."); 175 DMWARN("Unable to allocate userspace log context.");
173 return -ENOMEM; 176 return -ENOMEM;
@@ -195,9 +198,19 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
195 return str_size; 198 return str_size;
196 } 199 }
197 200
198 /* Send table string */ 201 devices_rdata = kzalloc(devices_rdata_size, GFP_KERNEL);
202 if (!devices_rdata) {
203 DMERR("Failed to allocate memory for device information");
204 r = -ENOMEM;
205 goto out;
206 }
207
208 /*
209 * Send table string and get back any opened device.
210 */
199 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR, 211 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR,
200 ctr_str, str_size, NULL, NULL); 212 ctr_str, str_size,
213 devices_rdata, &devices_rdata_size);
201 214
202 if (r < 0) { 215 if (r < 0) {
203 if (r == -ESRCH) 216 if (r == -ESRCH)
@@ -220,7 +233,20 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
220 lc->region_size = (uint32_t)rdata; 233 lc->region_size = (uint32_t)rdata;
221 lc->region_count = dm_sector_div_up(ti->len, lc->region_size); 234 lc->region_count = dm_sector_div_up(ti->len, lc->region_size);
222 235
236 if (devices_rdata_size) {
237 if (devices_rdata[devices_rdata_size - 1] != '\0') {
238 DMERR("DM_ULOG_CTR device return string not properly terminated");
239 r = -EINVAL;
240 goto out;
241 }
242 r = dm_get_device(ti, devices_rdata,
243 dm_table_get_mode(ti->table), &lc->log_dev);
244 if (r)
245 DMERR("Failed to register %s with device-mapper",
246 devices_rdata);
247 }
223out: 248out:
249 kfree(devices_rdata);
224 if (r) { 250 if (r) {
225 kfree(lc); 251 kfree(lc);
226 kfree(ctr_str); 252 kfree(ctr_str);
@@ -241,6 +267,9 @@ static void userspace_dtr(struct dm_dirty_log *log)
241 NULL, 0, 267 NULL, 0,
242 NULL, NULL); 268 NULL, NULL);
243 269
270 if (lc->log_dev)
271 dm_put_device(lc->ti, lc->log_dev);
272
244 kfree(lc->usr_argv_str); 273 kfree(lc->usr_argv_str);
245 kfree(lc); 274 kfree(lc);
246 275