diff options
Diffstat (limited to 'drivers/md/dm-table.c')
| -rw-r--r-- | drivers/md/dm-table.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index d952b3441913..1a6cb3c7822e 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
| @@ -343,10 +343,10 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) | |||
| 343 | } | 343 | } |
| 344 | 344 | ||
| 345 | /* | 345 | /* |
| 346 | * If possible, this checks an area of a destination device is valid. | 346 | * If possible, this checks an area of a destination device is invalid. |
| 347 | */ | 347 | */ |
| 348 | static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | 348 | static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev, |
| 349 | sector_t start, sector_t len, void *data) | 349 | sector_t start, sector_t len, void *data) |
| 350 | { | 350 | { |
| 351 | struct queue_limits *limits = data; | 351 | struct queue_limits *limits = data; |
| 352 | struct block_device *bdev = dev->bdev; | 352 | struct block_device *bdev = dev->bdev; |
| @@ -357,36 +357,40 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, | |||
| 357 | char b[BDEVNAME_SIZE]; | 357 | char b[BDEVNAME_SIZE]; |
| 358 | 358 | ||
| 359 | if (!dev_size) | 359 | if (!dev_size) |
| 360 | return 1; | 360 | return 0; |
| 361 | 361 | ||
| 362 | if ((start >= dev_size) || (start + len > dev_size)) { | 362 | if ((start >= dev_size) || (start + len > dev_size)) { |
| 363 | DMWARN("%s: %s too small for target", | 363 | DMWARN("%s: %s too small for target: " |
| 364 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 364 | "start=%llu, len=%llu, dev_size=%llu", |
| 365 | return 0; | 365 | dm_device_name(ti->table->md), bdevname(bdev, b), |
| 366 | (unsigned long long)start, | ||
| 367 | (unsigned long long)len, | ||
| 368 | (unsigned long long)dev_size); | ||
| 369 | return 1; | ||
| 366 | } | 370 | } |
| 367 | 371 | ||
| 368 | if (logical_block_size_sectors <= 1) | 372 | if (logical_block_size_sectors <= 1) |
| 369 | return 1; | 373 | return 0; |
| 370 | 374 | ||
| 371 | if (start & (logical_block_size_sectors - 1)) { | 375 | if (start & (logical_block_size_sectors - 1)) { |
| 372 | DMWARN("%s: start=%llu not aligned to h/w " | 376 | DMWARN("%s: start=%llu not aligned to h/w " |
| 373 | "logical block size %hu of %s", | 377 | "logical block size %u of %s", |
| 374 | dm_device_name(ti->table->md), | 378 | dm_device_name(ti->table->md), |
| 375 | (unsigned long long)start, | 379 | (unsigned long long)start, |
| 376 | limits->logical_block_size, bdevname(bdev, b)); | 380 | limits->logical_block_size, bdevname(bdev, b)); |
| 377 | return 0; | 381 | return 1; |
| 378 | } | 382 | } |
| 379 | 383 | ||
| 380 | if (len & (logical_block_size_sectors - 1)) { | 384 | if (len & (logical_block_size_sectors - 1)) { |
| 381 | DMWARN("%s: len=%llu not aligned to h/w " | 385 | DMWARN("%s: len=%llu not aligned to h/w " |
| 382 | "logical block size %hu of %s", | 386 | "logical block size %u of %s", |
| 383 | dm_device_name(ti->table->md), | 387 | dm_device_name(ti->table->md), |
| 384 | (unsigned long long)len, | 388 | (unsigned long long)len, |
| 385 | limits->logical_block_size, bdevname(bdev, b)); | 389 | limits->logical_block_size, bdevname(bdev, b)); |
| 386 | return 0; | 390 | return 1; |
| 387 | } | 391 | } |
| 388 | 392 | ||
| 389 | return 1; | 393 | return 0; |
| 390 | } | 394 | } |
| 391 | 395 | ||
| 392 | /* | 396 | /* |
| @@ -496,8 +500,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
| 496 | } | 500 | } |
| 497 | 501 | ||
| 498 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) | 502 | if (blk_stack_limits(limits, &q->limits, start << 9) < 0) |
| 499 | DMWARN("%s: target device %s is misaligned", | 503 | DMWARN("%s: target device %s is misaligned: " |
| 500 | dm_device_name(ti->table->md), bdevname(bdev, b)); | 504 | "physical_block_size=%u, logical_block_size=%u, " |
| 505 | "alignment_offset=%u, start=%llu", | ||
| 506 | dm_device_name(ti->table->md), bdevname(bdev, b), | ||
| 507 | q->limits.physical_block_size, | ||
| 508 | q->limits.logical_block_size, | ||
| 509 | q->limits.alignment_offset, | ||
| 510 | (unsigned long long) start << 9); | ||
| 511 | |||
| 501 | 512 | ||
| 502 | /* | 513 | /* |
| 503 | * Check if merge fn is supported. | 514 | * Check if merge fn is supported. |
| @@ -698,7 +709,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table, | |||
| 698 | 709 | ||
| 699 | if (remaining) { | 710 | if (remaining) { |
| 700 | DMWARN("%s: table line %u (start sect %llu len %llu) " | 711 | DMWARN("%s: table line %u (start sect %llu len %llu) " |
| 701 | "not aligned to h/w logical block size %hu", | 712 | "not aligned to h/w logical block size %u", |
| 702 | dm_device_name(table->md), i, | 713 | dm_device_name(table->md), i, |
| 703 | (unsigned long long) ti->begin, | 714 | (unsigned long long) ti->begin, |
| 704 | (unsigned long long) ti->len, | 715 | (unsigned long long) ti->len, |
| @@ -996,12 +1007,16 @@ int dm_calculate_queue_limits(struct dm_table *table, | |||
| 996 | ti->type->iterate_devices(ti, dm_set_device_limits, | 1007 | ti->type->iterate_devices(ti, dm_set_device_limits, |
| 997 | &ti_limits); | 1008 | &ti_limits); |
| 998 | 1009 | ||
| 1010 | /* Set I/O hints portion of queue limits */ | ||
| 1011 | if (ti->type->io_hints) | ||
| 1012 | ti->type->io_hints(ti, &ti_limits); | ||
| 1013 | |||
| 999 | /* | 1014 | /* |
| 1000 | * Check each device area is consistent with the target's | 1015 | * Check each device area is consistent with the target's |
| 1001 | * overall queue limits. | 1016 | * overall queue limits. |
| 1002 | */ | 1017 | */ |
| 1003 | if (!ti->type->iterate_devices(ti, device_area_is_valid, | 1018 | if (ti->type->iterate_devices(ti, device_area_is_invalid, |
| 1004 | &ti_limits)) | 1019 | &ti_limits)) |
| 1005 | return -EINVAL; | 1020 | return -EINVAL; |
| 1006 | 1021 | ||
| 1007 | combine_limits: | 1022 | combine_limits: |
