17
17
18
18
#define DM_MSG_PREFIX "delay"
19
19
20
+ struct delay_class {
21
+ struct dm_dev * dev ;
22
+ sector_t start ;
23
+ unsigned delay ;
24
+ unsigned ops ;
25
+ };
26
+
20
27
struct delay_c {
21
28
struct timer_list delay_timer ;
22
29
struct mutex timer_lock ;
@@ -25,19 +32,15 @@ struct delay_c {
25
32
struct list_head delayed_bios ;
26
33
atomic_t may_delay ;
27
34
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 ;
32
37
33
- struct dm_dev * dev_write ;
34
- sector_t start_write ;
35
- unsigned write_delay ;
36
- unsigned writes ;
38
+ int argc ;
37
39
};
38
40
39
41
struct dm_delay_info {
40
42
struct delay_c * context ;
43
+ struct delay_class * class ;
41
44
struct list_head list ;
42
45
unsigned long expires ;
43
46
};
@@ -77,7 +80,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
77
80
{
78
81
struct dm_delay_info * delayed , * next ;
79
82
unsigned long next_expires = 0 ;
80
- int start_timer = 0 ;
83
+ unsigned long start_timer = 0 ;
81
84
struct bio_list flush_bios = { };
82
85
83
86
mutex_lock (& delayed_bios_lock );
@@ -87,10 +90,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
87
90
sizeof (struct dm_delay_info ));
88
91
list_del (& delayed -> list );
89
92
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 -- ;
94
94
continue ;
95
95
}
96
96
@@ -100,7 +100,6 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
100
100
} else
101
101
next_expires = min (next_expires , delayed -> expires );
102
102
}
103
-
104
103
mutex_unlock (& delayed_bios_lock );
105
104
106
105
if (start_timer )
@@ -117,6 +116,48 @@ static void flush_expired_bios(struct work_struct *work)
117
116
flush_bios (flush_delayed_bios (dc , 0 ));
118
117
}
119
118
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
+
120
161
/*
121
162
* Mapping parameters:
122
163
* <device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
@@ -128,134 +169,76 @@ static void flush_expired_bios(struct work_struct *work)
128
169
static int delay_ctr (struct dm_target * ti , unsigned int argc , char * * argv )
129
170
{
130
171
struct delay_c * dc ;
131
- unsigned long long tmpll ;
132
- char dummy ;
133
172
int ret ;
134
173
135
174
if (argc != 3 && argc != 6 ) {
136
175
ti -> error = "Requires exactly 3 or 6 arguments" ;
137
176
return - EINVAL ;
138
177
}
139
178
140
- dc = kmalloc (sizeof (* dc ), GFP_KERNEL );
179
+ dc = kzalloc (sizeof (* dc ), GFP_KERNEL );
141
180
if (!dc ) {
142
181
ti -> error = "Cannot allocate context" ;
143
182
return - ENOMEM ;
144
183
}
145
184
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 ;
159
192
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 )
164
195
goto bad ;
165
- }
166
196
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 ;
170
201
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 ;
175
202
}
176
- dc -> start_write = tmpll ;
177
203
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 ;
189
207
190
208
out :
191
- ret = - EINVAL ;
192
209
dc -> kdelayd_wq = alloc_workqueue ("kdelayd" , WQ_MEM_RECLAIM , 0 );
193
210
if (!dc -> kdelayd_wq ) {
211
+ ret = - EINVAL ;
194
212
DMERR ("Couldn't start kdelayd" );
195
- goto bad_queue ;
213
+ goto bad ;
196
214
}
197
215
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
-
205
216
ti -> num_flush_bios = 1 ;
206
217
ti -> num_discard_bios = 1 ;
207
218
ti -> per_io_data_size = sizeof (struct dm_delay_info );
208
- ti -> private = dc ;
209
219
return 0 ;
210
220
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 );
216
221
bad :
217
- kfree ( dc );
222
+ delay_dtr ( ti );
218
223
return ret ;
219
224
}
220
225
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 )
238
227
{
239
228
struct dm_delay_info * delayed ;
240
229
unsigned long expires = 0 ;
241
230
242
- if (!delay || !atomic_read (& dc -> may_delay ))
231
+ if (!c -> delay || !atomic_read (& dc -> may_delay ))
243
232
return DM_MAPIO_REMAPPED ;
244
233
245
234
delayed = dm_per_bio_data (bio , sizeof (struct dm_delay_info ));
246
235
247
236
delayed -> context = dc ;
248
- delayed -> expires = expires = jiffies + msecs_to_jiffies (delay );
237
+ delayed -> expires = expires = jiffies + msecs_to_jiffies (c -> delay );
249
238
250
239
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 ++ ;
257
241
list_add_tail (& delayed -> list , & dc -> delayed_bios );
258
-
259
242
mutex_unlock (& delayed_bios_lock );
260
243
261
244
queue_timeout (dc , expires );
@@ -282,23 +265,25 @@ static void delay_resume(struct dm_target *ti)
282
265
static int delay_map (struct dm_target * ti , struct bio * bio )
283
266
{
284
267
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 ));
285
270
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 ;
293
275
}
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 );
294
280
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 );
300
282
}
301
283
284
+ #define DMEMIT_DELAY_CLASS (c ) \
285
+ DMEMIT("%s %llu %u", (c)->dev->name, (unsigned long long)(c)->start, (c)->delay)
286
+
302
287
static void delay_status (struct dm_target * ti , status_type_t type ,
303
288
unsigned status_flags , char * result , unsigned maxlen )
304
289
{
@@ -307,17 +292,15 @@ static void delay_status(struct dm_target *ti, status_type_t type,
307
292
308
293
switch (type ) {
309
294
case STATUSTYPE_INFO :
310
- DMEMIT ("%u %u" , dc -> reads , dc -> writes );
295
+ DMEMIT ("%u %u" , dc -> read . ops , dc -> write . ops );
311
296
break ;
312
297
313
298
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
+ }
321
304
break ;
322
305
}
323
306
}
@@ -328,12 +311,12 @@ static int delay_iterate_devices(struct dm_target *ti,
328
311
struct delay_c * dc = ti -> private ;
329
312
int ret = 0 ;
330
313
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 );
332
318
if (ret )
333
319
goto out ;
334
-
335
- if (dc -> dev_write )
336
- ret = fn (ti , dc -> dev_write , dc -> start_write , ti -> len , data );
337
320
338
321
out :
339
322
return ret ;
0 commit comments