Skip to content

Commit b49249d

Browse files
committed
Merge tag 'dm-3.8-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm
Pull dm update from Alasdair G Kergon: "Miscellaneous device-mapper fixes, cleanups and performance improvements. Of particular note: - Disable broken WRITE SAME support in all targets except linear and striped. Use it when kcopyd is zeroing blocks. - Remove several mempools from targets by moving the data into the bio's new front_pad area(which dm calls 'per_bio_data'). - Fix a race in thin provisioning if discards are misused. - Prevent userspace from interfering with the ioctl parameters and use kmalloc for the data buffer if it's small instead of vmalloc. - Throttle some annoying error messages when I/O fails." * tag 'dm-3.8-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm: (36 commits) dm stripe: add WRITE SAME support dm: remove map_info dm snapshot: do not use map_context dm thin: dont use map_context dm raid1: dont use map_context dm flakey: dont use map_context dm raid1: rename read_record to bio_record dm: move target request nr to dm_target_io dm snapshot: use per_bio_data dm verity: use per_bio_data dm raid1: use per_bio_data dm: introduce per_bio_data dm kcopyd: add WRITE SAME support to dm_kcopyd_zero dm linear: add WRITE SAME support dm: add WRITE SAME support dm: prepare to support WRITE SAME dm ioctl: use kmalloc if possible dm ioctl: remove PF_MEMALLOC dm persistent data: improve improve space map block alloc failure message dm thin: use DMERR_LIMIT for errors ...
2 parents 10532b5 + 45e621d commit b49249d

30 files changed

+522
-443
lines changed

drivers/md/dm-bio-prison.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -207,31 +207,6 @@ void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios)
207207
}
208208
EXPORT_SYMBOL_GPL(dm_cell_release);
209209

210-
/*
211-
* There are a couple of places where we put a bio into a cell briefly
212-
* before taking it out again. In these situations we know that no other
213-
* bio may be in the cell. This function releases the cell, and also does
214-
* a sanity check.
215-
*/
216-
static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
217-
{
218-
BUG_ON(cell->holder != bio);
219-
BUG_ON(!bio_list_empty(&cell->bios));
220-
221-
__cell_release(cell, NULL);
222-
}
223-
224-
void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
225-
{
226-
unsigned long flags;
227-
struct dm_bio_prison *prison = cell->prison;
228-
229-
spin_lock_irqsave(&prison->lock, flags);
230-
__cell_release_singleton(cell, bio);
231-
spin_unlock_irqrestore(&prison->lock, flags);
232-
}
233-
EXPORT_SYMBOL_GPL(dm_cell_release_singleton);
234-
235210
/*
236211
* Sometimes we don't want the holder, just the additional bios.
237212
*/

drivers/md/dm-bio-prison.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ int dm_bio_detain(struct dm_bio_prison *prison, struct dm_cell_key *key,
4444
struct bio *inmate, struct dm_bio_prison_cell **ref);
4545

4646
void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios);
47-
void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio); // FIXME: bio arg not needed
4847
void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates);
4948
void dm_cell_error(struct dm_bio_prison_cell *cell);
5049

drivers/md/dm-crypt.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,8 +1689,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
16891689
return ret;
16901690
}
16911691

1692-
static int crypt_map(struct dm_target *ti, struct bio *bio,
1693-
union map_info *map_context)
1692+
static int crypt_map(struct dm_target *ti, struct bio *bio)
16941693
{
16951694
struct dm_crypt_io *io;
16961695
struct crypt_config *cc = ti->private;
@@ -1846,7 +1845,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
18461845

18471846
static struct target_type crypt_target = {
18481847
.name = "crypt",
1849-
.version = {1, 11, 0},
1848+
.version = {1, 12, 0},
18501849
.module = THIS_MODULE,
18511850
.ctr = crypt_ctr,
18521851
.dtr = crypt_dtr,

drivers/md/dm-delay.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,7 @@ static void delay_resume(struct dm_target *ti)
274274
atomic_set(&dc->may_delay, 1);
275275
}
276276

277-
static int delay_map(struct dm_target *ti, struct bio *bio,
278-
union map_info *map_context)
277+
static int delay_map(struct dm_target *ti, struct bio *bio)
279278
{
280279
struct delay_c *dc = ti->private;
281280

@@ -338,7 +337,7 @@ static int delay_iterate_devices(struct dm_target *ti,
338337

339338
static struct target_type delay_target = {
340339
.name = "delay",
341-
.version = {1, 1, 0},
340+
.version = {1, 2, 0},
342341
.module = THIS_MODULE,
343342
.ctr = delay_ctr,
344343
.dtr = delay_dtr,

drivers/md/dm-flakey.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ enum feature_flag_bits {
3939
DROP_WRITES
4040
};
4141

42+
struct per_bio_data {
43+
bool bio_submitted;
44+
};
45+
4246
static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
4347
struct dm_target *ti)
4448
{
@@ -214,6 +218,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
214218

215219
ti->num_flush_requests = 1;
216220
ti->num_discard_requests = 1;
221+
ti->per_bio_data_size = sizeof(struct per_bio_data);
217222
ti->private = fc;
218223
return 0;
219224

@@ -265,19 +270,20 @@ static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
265270
}
266271
}
267272

268-
static int flakey_map(struct dm_target *ti, struct bio *bio,
269-
union map_info *map_context)
273+
static int flakey_map(struct dm_target *ti, struct bio *bio)
270274
{
271275
struct flakey_c *fc = ti->private;
272276
unsigned elapsed;
277+
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
278+
pb->bio_submitted = false;
273279

274280
/* Are we alive ? */
275281
elapsed = (jiffies - fc->start_time) / HZ;
276282
if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) {
277283
/*
278284
* Flag this bio as submitted while down.
279285
*/
280-
map_context->ll = 1;
286+
pb->bio_submitted = true;
281287

282288
/*
283289
* Map reads as normal.
@@ -314,17 +320,16 @@ static int flakey_map(struct dm_target *ti, struct bio *bio,
314320
return DM_MAPIO_REMAPPED;
315321
}
316322

317-
static int flakey_end_io(struct dm_target *ti, struct bio *bio,
318-
int error, union map_info *map_context)
323+
static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)
319324
{
320325
struct flakey_c *fc = ti->private;
321-
unsigned bio_submitted_while_down = map_context->ll;
326+
struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data));
322327

323328
/*
324329
* Corrupt successful READs while in down state.
325330
* If flags were specified, only corrupt those that match.
326331
*/
327-
if (fc->corrupt_bio_byte && !error && bio_submitted_while_down &&
332+
if (fc->corrupt_bio_byte && !error && pb->bio_submitted &&
328333
(bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) &&
329334
all_corrupt_bio_flags_match(bio, fc))
330335
corrupt_bio_data(bio, fc);
@@ -406,7 +411,7 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_
406411

407412
static struct target_type flakey_target = {
408413
.name = "flakey",
409-
.version = {1, 2, 0},
414+
.version = {1, 3, 0},
410415
.module = THIS_MODULE,
411416
.ctr = flakey_ctr,
412417
.dtr = flakey_dtr,

drivers/md/dm-io.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
287287
unsigned num_bvecs;
288288
sector_t remaining = where->count;
289289
struct request_queue *q = bdev_get_queue(where->bdev);
290-
sector_t discard_sectors;
290+
unsigned short logical_block_size = queue_logical_block_size(q);
291+
sector_t num_sectors;
291292

292293
/*
293294
* where->count may be zero if rw holds a flush and we need to
@@ -297,7 +298,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
297298
/*
298299
* Allocate a suitably sized-bio.
299300
*/
300-
if (rw & REQ_DISCARD)
301+
if ((rw & REQ_DISCARD) || (rw & REQ_WRITE_SAME))
301302
num_bvecs = 1;
302303
else
303304
num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev),
@@ -310,9 +311,21 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
310311
store_io_and_region_in_bio(bio, io, region);
311312

312313
if (rw & REQ_DISCARD) {
313-
discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
314-
bio->bi_size = discard_sectors << SECTOR_SHIFT;
315-
remaining -= discard_sectors;
314+
num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
315+
bio->bi_size = num_sectors << SECTOR_SHIFT;
316+
remaining -= num_sectors;
317+
} else if (rw & REQ_WRITE_SAME) {
318+
/*
319+
* WRITE SAME only uses a single page.
320+
*/
321+
dp->get_page(dp, &page, &len, &offset);
322+
bio_add_page(bio, page, logical_block_size, offset);
323+
num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining);
324+
bio->bi_size = num_sectors << SECTOR_SHIFT;
325+
326+
offset = 0;
327+
remaining -= num_sectors;
328+
dp->next_page(dp);
316329
} else while (remaining) {
317330
/*
318331
* Try and add as many pages as possible.

drivers/md/dm-ioctl.c

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,21 @@ static int check_version(unsigned int cmd, struct dm_ioctl __user *user)
15431543
return r;
15441544
}
15451545

1546-
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
1546+
#define DM_PARAMS_VMALLOC 0x0001 /* Params alloced with vmalloc not kmalloc */
1547+
#define DM_WIPE_BUFFER 0x0010 /* Wipe input buffer before returning from ioctl */
1548+
1549+
static void free_params(struct dm_ioctl *param, size_t param_size, int param_flags)
1550+
{
1551+
if (param_flags & DM_WIPE_BUFFER)
1552+
memset(param, 0, param_size);
1553+
1554+
if (param_flags & DM_PARAMS_VMALLOC)
1555+
vfree(param);
1556+
else
1557+
kfree(param);
1558+
}
1559+
1560+
static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param, int *param_flags)
15471561
{
15481562
struct dm_ioctl tmp, *dmi;
15491563
int secure_data;
@@ -1556,7 +1570,21 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
15561570

15571571
secure_data = tmp.flags & DM_SECURE_DATA_FLAG;
15581572

1559-
dmi = vmalloc(tmp.data_size);
1573+
*param_flags = secure_data ? DM_WIPE_BUFFER : 0;
1574+
1575+
/*
1576+
* Try to avoid low memory issues when a device is suspended.
1577+
* Use kmalloc() rather than vmalloc() when we can.
1578+
*/
1579+
dmi = NULL;
1580+
if (tmp.data_size <= KMALLOC_MAX_SIZE)
1581+
dmi = kmalloc(tmp.data_size, GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
1582+
1583+
if (!dmi) {
1584+
dmi = __vmalloc(tmp.data_size, GFP_NOIO | __GFP_REPEAT | __GFP_HIGH, PAGE_KERNEL);
1585+
*param_flags |= DM_PARAMS_VMALLOC;
1586+
}
1587+
15601588
if (!dmi) {
15611589
if (secure_data && clear_user(user, tmp.data_size))
15621590
return -EFAULT;
@@ -1566,6 +1594,14 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
15661594
if (copy_from_user(dmi, user, tmp.data_size))
15671595
goto bad;
15681596

1597+
/*
1598+
* Abort if something changed the ioctl data while it was being copied.
1599+
*/
1600+
if (dmi->data_size != tmp.data_size) {
1601+
DMERR("rejecting ioctl: data size modified while processing parameters");
1602+
goto bad;
1603+
}
1604+
15691605
/* Wipe the user buffer so we do not return it to userspace */
15701606
if (secure_data && clear_user(user, tmp.data_size))
15711607
goto bad;
@@ -1574,9 +1610,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
15741610
return 0;
15751611

15761612
bad:
1577-
if (secure_data)
1578-
memset(dmi, 0, tmp.data_size);
1579-
vfree(dmi);
1613+
free_params(dmi, tmp.data_size, *param_flags);
1614+
15801615
return -EFAULT;
15811616
}
15821617

@@ -1613,7 +1648,7 @@ static int validate_params(uint cmd, struct dm_ioctl *param)
16131648
static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
16141649
{
16151650
int r = 0;
1616-
int wipe_buffer;
1651+
int param_flags;
16171652
unsigned int cmd;
16181653
struct dm_ioctl *uninitialized_var(param);
16191654
ioctl_fn fn = NULL;
@@ -1648,25 +1683,15 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
16481683
return -ENOTTY;
16491684
}
16501685

1651-
/*
1652-
* Trying to avoid low memory issues when a device is
1653-
* suspended.
1654-
*/
1655-
current->flags |= PF_MEMALLOC;
1656-
16571686
/*
16581687
* Copy the parameters into kernel space.
16591688
*/
1660-
r = copy_params(user, &param);
1661-
1662-
current->flags &= ~PF_MEMALLOC;
1689+
r = copy_params(user, &param, &param_flags);
16631690

16641691
if (r)
16651692
return r;
16661693

16671694
input_param_size = param->data_size;
1668-
wipe_buffer = param->flags & DM_SECURE_DATA_FLAG;
1669-
16701695
r = validate_params(cmd, param);
16711696
if (r)
16721697
goto out;
@@ -1681,10 +1706,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user)
16811706
r = -EFAULT;
16821707

16831708
out:
1684-
if (wipe_buffer)
1685-
memset(param, 0, input_param_size);
1686-
1687-
vfree(param);
1709+
free_params(param, input_param_size, param_flags);
16881710
return r;
16891711
}
16901712

drivers/md/dm-kcopyd.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static void complete_io(unsigned long error, void *context)
349349
struct dm_kcopyd_client *kc = job->kc;
350350

351351
if (error) {
352-
if (job->rw == WRITE)
352+
if (job->rw & WRITE)
353353
job->write_err |= error;
354354
else
355355
job->read_err = 1;
@@ -361,7 +361,7 @@ static void complete_io(unsigned long error, void *context)
361361
}
362362
}
363363

364-
if (job->rw == WRITE)
364+
if (job->rw & WRITE)
365365
push(&kc->complete_jobs, job);
366366

367367
else {
@@ -432,7 +432,7 @@ static int process_jobs(struct list_head *jobs, struct dm_kcopyd_client *kc,
432432

433433
if (r < 0) {
434434
/* error this rogue job */
435-
if (job->rw == WRITE)
435+
if (job->rw & WRITE)
436436
job->write_err = (unsigned long) -1L;
437437
else
438438
job->read_err = 1;
@@ -585,6 +585,7 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
585585
unsigned int flags, dm_kcopyd_notify_fn fn, void *context)
586586
{
587587
struct kcopyd_job *job;
588+
int i;
588589

589590
/*
590591
* Allocate an array of jobs consisting of one master job
@@ -611,7 +612,16 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
611612
memset(&job->source, 0, sizeof job->source);
612613
job->source.count = job->dests[0].count;
613614
job->pages = &zero_page_list;
614-
job->rw = WRITE;
615+
616+
/*
617+
* Use WRITE SAME to optimize zeroing if all dests support it.
618+
*/
619+
job->rw = WRITE | REQ_WRITE_SAME;
620+
for (i = 0; i < job->num_dests; i++)
621+
if (!bdev_write_same(job->dests[i].bdev)) {
622+
job->rw = WRITE;
623+
break;
624+
}
615625
}
616626

617627
job->fn = fn;

drivers/md/dm-linear.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
5555

5656
ti->num_flush_requests = 1;
5757
ti->num_discard_requests = 1;
58+
ti->num_write_same_requests = 1;
5859
ti->private = lc;
5960
return 0;
6061

@@ -87,8 +88,7 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
8788
bio->bi_sector = linear_map_sector(ti, bio->bi_sector);
8889
}
8990

90-
static int linear_map(struct dm_target *ti, struct bio *bio,
91-
union map_info *map_context)
91+
static int linear_map(struct dm_target *ti, struct bio *bio)
9292
{
9393
linear_map_bio(ti, bio);
9494

@@ -155,7 +155,7 @@ static int linear_iterate_devices(struct dm_target *ti,
155155

156156
static struct target_type linear_target = {
157157
.name = "linear",
158-
.version = {1, 1, 0},
158+
.version = {1, 2, 0},
159159
.module = THIS_MODULE,
160160
.ctr = linear_ctr,
161161
.dtr = linear_dtr,

0 commit comments

Comments
 (0)