Skip to content

Commit 3876ac7

Browse files
Mikulas Patockasnitm
authored andcommitted
dm delay: refactor repetitive code
dm-delay has a lot of code that is repeated for delaying read and write bios. Repetitive code is generally bad; refactor out the repetitive code in preperation for adding another delay class for flush bios. Signed-off-by: Mikulas Patocka <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent af9313c commit 3876ac7

File tree

1 file changed

+103
-120
lines changed

1 file changed

+103
-120
lines changed

drivers/md/dm-delay.c

Lines changed: 103 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717

1818
#define DM_MSG_PREFIX "delay"
1919

20+
struct delay_class {
21+
struct dm_dev *dev;
22+
sector_t start;
23+
unsigned delay;
24+
unsigned ops;
25+
};
26+
2027
struct delay_c {
2128
struct timer_list delay_timer;
2229
struct mutex timer_lock;
@@ -25,19 +32,15 @@ struct delay_c {
2532
struct list_head delayed_bios;
2633
atomic_t may_delay;
2734

28-
struct dm_dev *dev_read;
29-
sector_t start_read;
30-
unsigned read_delay;
31-
unsigned reads;
35+
struct delay_class read;
36+
struct delay_class write;
3237

33-
struct dm_dev *dev_write;
34-
sector_t start_write;
35-
unsigned write_delay;
36-
unsigned writes;
38+
int argc;
3739
};
3840

3941
struct dm_delay_info {
4042
struct delay_c *context;
43+
struct delay_class *class;
4144
struct list_head list;
4245
unsigned long expires;
4346
};
@@ -77,7 +80,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
7780
{
7881
struct dm_delay_info *delayed, *next;
7982
unsigned long next_expires = 0;
80-
int start_timer = 0;
83+
unsigned long start_timer = 0;
8184
struct bio_list flush_bios = { };
8285

8386
mutex_lock(&delayed_bios_lock);
@@ -87,10 +90,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
8790
sizeof(struct dm_delay_info));
8891
list_del(&delayed->list);
8992
bio_list_add(&flush_bios, bio);
90-
if ((bio_data_dir(bio) == WRITE))
91-
delayed->context->writes--;
92-
else
93-
delayed->context->reads--;
93+
delayed->class->ops--;
9494
continue;
9595
}
9696

@@ -100,7 +100,6 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
100100
} else
101101
next_expires = min(next_expires, delayed->expires);
102102
}
103-
104103
mutex_unlock(&delayed_bios_lock);
105104

106105
if (start_timer)
@@ -117,6 +116,48 @@ static void flush_expired_bios(struct work_struct *work)
117116
flush_bios(flush_delayed_bios(dc, 0));
118117
}
119118

119+
static void delay_dtr(struct dm_target *ti)
120+
{
121+
struct delay_c *dc = ti->private;
122+
123+
destroy_workqueue(dc->kdelayd_wq);
124+
125+
if (dc->read.dev)
126+
dm_put_device(ti, dc->read.dev);
127+
if (dc->write.dev)
128+
dm_put_device(ti, dc->write.dev);
129+
130+
mutex_destroy(&dc->timer_lock);
131+
132+
kfree(dc);
133+
}
134+
135+
static int delay_class_ctr(struct dm_target *ti, struct delay_class *c, char **argv)
136+
{
137+
int ret;
138+
unsigned long long tmpll;
139+
char dummy;
140+
141+
if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
142+
ti->error = "Invalid device sector";
143+
return -EINVAL;
144+
}
145+
c->start = tmpll;
146+
147+
if (sscanf(argv[2], "%u%c", &c->delay, &dummy) != 1) {
148+
ti->error = "Invalid delay";
149+
return -EINVAL;
150+
}
151+
152+
ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &c->dev);
153+
if (ret) {
154+
ti->error = "Device lookup failed";
155+
return ret;
156+
}
157+
158+
return 0;
159+
}
160+
120161
/*
121162
* Mapping parameters:
122163
* <device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
@@ -128,134 +169,76 @@ static void flush_expired_bios(struct work_struct *work)
128169
static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
129170
{
130171
struct delay_c *dc;
131-
unsigned long long tmpll;
132-
char dummy;
133172
int ret;
134173

135174
if (argc != 3 && argc != 6) {
136175
ti->error = "Requires exactly 3 or 6 arguments";
137176
return -EINVAL;
138177
}
139178

140-
dc = kmalloc(sizeof(*dc), GFP_KERNEL);
179+
dc = kzalloc(sizeof(*dc), GFP_KERNEL);
141180
if (!dc) {
142181
ti->error = "Cannot allocate context";
143182
return -ENOMEM;
144183
}
145184

146-
dc->reads = dc->writes = 0;
147-
148-
ret = -EINVAL;
149-
if (sscanf(argv[1], "%llu%c", &tmpll, &dummy) != 1) {
150-
ti->error = "Invalid device sector";
151-
goto bad;
152-
}
153-
dc->start_read = tmpll;
154-
155-
if (sscanf(argv[2], "%u%c", &dc->read_delay, &dummy) != 1) {
156-
ti->error = "Invalid delay";
157-
goto bad;
158-
}
185+
ti->private = dc;
186+
timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
187+
INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
188+
INIT_LIST_HEAD(&dc->delayed_bios);
189+
mutex_init(&dc->timer_lock);
190+
atomic_set(&dc->may_delay, 1);
191+
dc->argc = argc;
159192

160-
ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
161-
&dc->dev_read);
162-
if (ret) {
163-
ti->error = "Device lookup failed";
193+
ret = delay_class_ctr(ti, &dc->read, argv);
194+
if (ret)
164195
goto bad;
165-
}
166196

167-
ret = -EINVAL;
168-
dc->dev_write = NULL;
169-
if (argc == 3)
197+
if (argc == 3) {
198+
ret = delay_class_ctr(ti, &dc->write, argv);
199+
if (ret)
200+
goto bad;
170201
goto out;
171-
172-
if (sscanf(argv[4], "%llu%c", &tmpll, &dummy) != 1) {
173-
ti->error = "Invalid write device sector";
174-
goto bad_dev_read;
175202
}
176-
dc->start_write = tmpll;
177203

178-
if (sscanf(argv[5], "%u%c", &dc->write_delay, &dummy) != 1) {
179-
ti->error = "Invalid write delay";
180-
goto bad_dev_read;
181-
}
182-
183-
ret = dm_get_device(ti, argv[3], dm_table_get_mode(ti->table),
184-
&dc->dev_write);
185-
if (ret) {
186-
ti->error = "Write device lookup failed";
187-
goto bad_dev_read;
188-
}
204+
ret = delay_class_ctr(ti, &dc->write, argv + 3);
205+
if (ret)
206+
goto bad;
189207

190208
out:
191-
ret = -EINVAL;
192209
dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0);
193210
if (!dc->kdelayd_wq) {
211+
ret = -EINVAL;
194212
DMERR("Couldn't start kdelayd");
195-
goto bad_queue;
213+
goto bad;
196214
}
197215

198-
timer_setup(&dc->delay_timer, handle_delayed_timer, 0);
199-
200-
INIT_WORK(&dc->flush_expired_bios, flush_expired_bios);
201-
INIT_LIST_HEAD(&dc->delayed_bios);
202-
mutex_init(&dc->timer_lock);
203-
atomic_set(&dc->may_delay, 1);
204-
205216
ti->num_flush_bios = 1;
206217
ti->num_discard_bios = 1;
207218
ti->per_io_data_size = sizeof(struct dm_delay_info);
208-
ti->private = dc;
209219
return 0;
210220

211-
bad_queue:
212-
if (dc->dev_write)
213-
dm_put_device(ti, dc->dev_write);
214-
bad_dev_read:
215-
dm_put_device(ti, dc->dev_read);
216221
bad:
217-
kfree(dc);
222+
delay_dtr(ti);
218223
return ret;
219224
}
220225

221-
static void delay_dtr(struct dm_target *ti)
222-
{
223-
struct delay_c *dc = ti->private;
224-
225-
destroy_workqueue(dc->kdelayd_wq);
226-
227-
dm_put_device(ti, dc->dev_read);
228-
229-
if (dc->dev_write)
230-
dm_put_device(ti, dc->dev_write);
231-
232-
mutex_destroy(&dc->timer_lock);
233-
234-
kfree(dc);
235-
}
236-
237-
static int delay_bio(struct delay_c *dc, int delay, struct bio *bio)
226+
static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio)
238227
{
239228
struct dm_delay_info *delayed;
240229
unsigned long expires = 0;
241230

242-
if (!delay || !atomic_read(&dc->may_delay))
231+
if (!c->delay || !atomic_read(&dc->may_delay))
243232
return DM_MAPIO_REMAPPED;
244233

245234
delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info));
246235

247236
delayed->context = dc;
248-
delayed->expires = expires = jiffies + msecs_to_jiffies(delay);
237+
delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay);
249238

250239
mutex_lock(&delayed_bios_lock);
251-
252-
if (bio_data_dir(bio) == WRITE)
253-
dc->writes++;
254-
else
255-
dc->reads++;
256-
240+
c->ops++;
257241
list_add_tail(&delayed->list, &dc->delayed_bios);
258-
259242
mutex_unlock(&delayed_bios_lock);
260243

261244
queue_timeout(dc, expires);
@@ -282,23 +265,25 @@ static void delay_resume(struct dm_target *ti)
282265
static int delay_map(struct dm_target *ti, struct bio *bio)
283266
{
284267
struct delay_c *dc = ti->private;
268+
struct delay_class *c;
269+
struct dm_delay_info *delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info));
285270

286-
if ((bio_data_dir(bio) == WRITE) && (dc->dev_write)) {
287-
bio_set_dev(bio, dc->dev_write->bdev);
288-
if (bio_sectors(bio))
289-
bio->bi_iter.bi_sector = dc->start_write +
290-
dm_target_offset(ti, bio->bi_iter.bi_sector);
291-
292-
return delay_bio(dc, dc->write_delay, bio);
271+
if (bio_data_dir(bio) == WRITE) {
272+
c = &dc->write;
273+
} else {
274+
c = &dc->read;
293275
}
276+
delayed->class = c;
277+
bio_set_dev(bio, c->dev->bdev);
278+
if (bio_sectors(bio))
279+
bio->bi_iter.bi_sector = c->start + dm_target_offset(ti, bio->bi_iter.bi_sector);
294280

295-
bio_set_dev(bio, dc->dev_read->bdev);
296-
bio->bi_iter.bi_sector = dc->start_read +
297-
dm_target_offset(ti, bio->bi_iter.bi_sector);
298-
299-
return delay_bio(dc, dc->read_delay, bio);
281+
return delay_bio(dc, c, bio);
300282
}
301283

284+
#define DMEMIT_DELAY_CLASS(c) \
285+
DMEMIT("%s %llu %u", (c)->dev->name, (unsigned long long)(c)->start, (c)->delay)
286+
302287
static void delay_status(struct dm_target *ti, status_type_t type,
303288
unsigned status_flags, char *result, unsigned maxlen)
304289
{
@@ -307,17 +292,15 @@ static void delay_status(struct dm_target *ti, status_type_t type,
307292

308293
switch (type) {
309294
case STATUSTYPE_INFO:
310-
DMEMIT("%u %u", dc->reads, dc->writes);
295+
DMEMIT("%u %u", dc->read.ops, dc->write.ops);
311296
break;
312297

313298
case STATUSTYPE_TABLE:
314-
DMEMIT("%s %llu %u", dc->dev_read->name,
315-
(unsigned long long) dc->start_read,
316-
dc->read_delay);
317-
if (dc->dev_write)
318-
DMEMIT(" %s %llu %u", dc->dev_write->name,
319-
(unsigned long long) dc->start_write,
320-
dc->write_delay);
299+
DMEMIT_DELAY_CLASS(&dc->read);
300+
if (dc->argc >= 6) {
301+
DMEMIT(" ");
302+
DMEMIT_DELAY_CLASS(&dc->write);
303+
}
321304
break;
322305
}
323306
}
@@ -328,12 +311,12 @@ static int delay_iterate_devices(struct dm_target *ti,
328311
struct delay_c *dc = ti->private;
329312
int ret = 0;
330313

331-
ret = fn(ti, dc->dev_read, dc->start_read, ti->len, data);
314+
ret = fn(ti, dc->read.dev, dc->read.start, ti->len, data);
315+
if (ret)
316+
goto out;
317+
ret = fn(ti, dc->write.dev, dc->write.start, ti->len, data);
332318
if (ret)
333319
goto out;
334-
335-
if (dc->dev_write)
336-
ret = fn(ti, dc->dev_write, dc->start_write, ti->len, data);
337320

338321
out:
339322
return ret;

0 commit comments

Comments
 (0)