dm-table.c (f68ec0c24755e5cdb779be6240925f2175311d84) | dm-table.c (82b1519b345d61dcfae526e3fcb08128f39f9bcc) |
---|---|
1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. 3 * Copyright (C) 2004 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" --- 236 unchanged lines hidden (view full) --- 245 return 0; 246} 247 248static void free_devices(struct list_head *devices) 249{ 250 struct list_head *tmp, *next; 251 252 list_for_each_safe(tmp, next, devices) { | 1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. 3 * Copyright (C) 2004 Red Hat, Inc. All rights reserved. 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" --- 236 unchanged lines hidden (view full) --- 245 return 0; 246} 247 248static void free_devices(struct list_head *devices) 249{ 250 struct list_head *tmp, *next; 251 252 list_for_each_safe(tmp, next, devices) { |
253 struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); | 253 struct dm_dev_internal *dd = 254 list_entry(tmp, struct dm_dev_internal, list); |
254 kfree(dd); 255 } 256} 257 258static void table_destroy(struct dm_table *t) 259{ 260 unsigned int i; 261 --- 60 unchanged lines hidden (view full) --- 322 *dev = bdev->bd_dev; 323 bdput(bdev); 324 return 0; 325} 326 327/* 328 * See if we've already got a device in the list. 329 */ | 255 kfree(dd); 256 } 257} 258 259static void table_destroy(struct dm_table *t) 260{ 261 unsigned int i; 262 --- 60 unchanged lines hidden (view full) --- 323 *dev = bdev->bd_dev; 324 bdput(bdev); 325 return 0; 326} 327 328/* 329 * See if we've already got a device in the list. 330 */ |
330static struct dm_dev *find_device(struct list_head *l, dev_t dev) | 331static struct dm_dev_internal *find_device(struct list_head *l, dev_t dev) |
331{ | 332{ |
332 struct dm_dev *dd; | 333 struct dm_dev_internal *dd; |
333 334 list_for_each_entry (dd, l, list) | 334 335 list_for_each_entry (dd, l, list) |
335 if (dd->bdev->bd_dev == dev) | 336 if (dd->dm_dev.bdev->bd_dev == dev) |
336 return dd; 337 338 return NULL; 339} 340 341/* 342 * Open a device so we can use it as a map destination. 343 */ | 337 return dd; 338 339 return NULL; 340} 341 342/* 343 * Open a device so we can use it as a map destination. 344 */ |
344static int open_dev(struct dm_dev *d, dev_t dev, struct mapped_device *md) | 345static int open_dev(struct dm_dev_internal *d, dev_t dev, 346 struct mapped_device *md) |
345{ 346 static char *_claim_ptr = "I belong to device-mapper"; 347 struct block_device *bdev; 348 349 int r; 350 | 347{ 348 static char *_claim_ptr = "I belong to device-mapper"; 349 struct block_device *bdev; 350 351 int r; 352 |
351 BUG_ON(d->bdev); | 353 BUG_ON(d->dm_dev.bdev); |
352 | 354 |
353 bdev = open_by_devnum(dev, d->mode); | 355 bdev = open_by_devnum(dev, d->dm_dev.mode); |
354 if (IS_ERR(bdev)) 355 return PTR_ERR(bdev); 356 r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); 357 if (r) 358 blkdev_put(bdev); 359 else | 356 if (IS_ERR(bdev)) 357 return PTR_ERR(bdev); 358 r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); 359 if (r) 360 blkdev_put(bdev); 361 else |
360 d->bdev = bdev; | 362 d->dm_dev.bdev = bdev; |
361 return r; 362} 363 364/* 365 * Close a device that we've been using. 366 */ | 363 return r; 364} 365 366/* 367 * Close a device that we've been using. 368 */ |
367static void close_dev(struct dm_dev *d, struct mapped_device *md) | 369static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) |
368{ | 370{ |
369 if (!d->bdev) | 371 if (!d->dm_dev.bdev) |
370 return; 371 | 372 return; 373 |
372 bd_release_from_disk(d->bdev, dm_disk(md)); 373 blkdev_put(d->bdev); 374 d->bdev = NULL; | 374 bd_release_from_disk(d->dm_dev.bdev, dm_disk(md)); 375 blkdev_put(d->dm_dev.bdev); 376 d->dm_dev.bdev = NULL; |
375} 376 377/* 378 * If possible, this checks an area of a destination device is valid. 379 */ | 377} 378 379/* 380 * If possible, this checks an area of a destination device is valid. 381 */ |
380static int check_device_area(struct dm_dev *dd, sector_t start, sector_t len) | 382static int check_device_area(struct dm_dev_internal *dd, sector_t start, 383 sector_t len) |
381{ | 384{ |
382 sector_t dev_size = dd->bdev->bd_inode->i_size >> SECTOR_SHIFT; | 385 sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT; |
383 384 if (!dev_size) 385 return 1; 386 387 return ((start < dev_size) && (len <= (dev_size - start))); 388} 389 390/* 391 * This upgrades the mode on an already open dm_dev. Being 392 * careful to leave things as they were if we fail to reopen the 393 * device. 394 */ | 386 387 if (!dev_size) 388 return 1; 389 390 return ((start < dev_size) && (len <= (dev_size - start))); 391} 392 393/* 394 * This upgrades the mode on an already open dm_dev. Being 395 * careful to leave things as they were if we fail to reopen the 396 * device. 397 */ |
395static int upgrade_mode(struct dm_dev *dd, int new_mode, struct mapped_device *md) | 398static int upgrade_mode(struct dm_dev_internal *dd, int new_mode, 399 struct mapped_device *md) |
396{ 397 int r; | 400{ 401 int r; |
398 struct dm_dev dd_copy; 399 dev_t dev = dd->bdev->bd_dev; | 402 struct dm_dev_internal dd_copy; 403 dev_t dev = dd->dm_dev.bdev->bd_dev; |
400 401 dd_copy = *dd; 402 | 404 405 dd_copy = *dd; 406 |
403 dd->mode |= new_mode; 404 dd->bdev = NULL; | 407 dd->dm_dev.mode |= new_mode; 408 dd->dm_dev.bdev = NULL; |
405 r = open_dev(dd, dev, md); 406 if (!r) 407 close_dev(&dd_copy, md); 408 else 409 *dd = dd_copy; 410 411 return r; 412} 413 414/* 415 * Add a device to the list, or just increment the usage count if 416 * it's already present. 417 */ 418static int __table_get_device(struct dm_table *t, struct dm_target *ti, 419 const char *path, sector_t start, sector_t len, 420 int mode, struct dm_dev **result) 421{ 422 int r; 423 dev_t uninitialized_var(dev); | 409 r = open_dev(dd, dev, md); 410 if (!r) 411 close_dev(&dd_copy, md); 412 else 413 *dd = dd_copy; 414 415 return r; 416} 417 418/* 419 * Add a device to the list, or just increment the usage count if 420 * it's already present. 421 */ 422static int __table_get_device(struct dm_table *t, struct dm_target *ti, 423 const char *path, sector_t start, sector_t len, 424 int mode, struct dm_dev **result) 425{ 426 int r; 427 dev_t uninitialized_var(dev); |
424 struct dm_dev *dd; | 428 struct dm_dev_internal *dd; |
425 unsigned int major, minor; 426 427 BUG_ON(!t); 428 429 if (sscanf(path, "%u:%u", &major, &minor) == 2) { 430 /* Extract the major/minor numbers */ 431 dev = MKDEV(major, minor); 432 if (MAJOR(dev) != major || MINOR(dev) != minor) --- 5 unchanged lines hidden (view full) --- 438 } 439 440 dd = find_device(&t->devices, dev); 441 if (!dd) { 442 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 443 if (!dd) 444 return -ENOMEM; 445 | 429 unsigned int major, minor; 430 431 BUG_ON(!t); 432 433 if (sscanf(path, "%u:%u", &major, &minor) == 2) { 434 /* Extract the major/minor numbers */ 435 dev = MKDEV(major, minor); 436 if (MAJOR(dev) != major || MINOR(dev) != minor) --- 5 unchanged lines hidden (view full) --- 442 } 443 444 dd = find_device(&t->devices, dev); 445 if (!dd) { 446 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 447 if (!dd) 448 return -ENOMEM; 449 |
446 dd->mode = mode; 447 dd->bdev = NULL; | 450 dd->dm_dev.mode = mode; 451 dd->dm_dev.bdev = NULL; |
448 449 if ((r = open_dev(dd, dev, t->md))) { 450 kfree(dd); 451 return r; 452 } 453 | 452 453 if ((r = open_dev(dd, dev, t->md))) { 454 kfree(dd); 455 return r; 456 } 457 |
454 format_dev_t(dd->name, dev); | 458 format_dev_t(dd->dm_dev.name, dev); |
455 456 atomic_set(&dd->count, 0); 457 list_add(&dd->list, &t->devices); 458 | 459 460 atomic_set(&dd->count, 0); 461 list_add(&dd->list, &t->devices); 462 |
459 } else if (dd->mode != (mode | dd->mode)) { | 463 } else if (dd->dm_dev.mode != (mode | dd->dm_dev.mode)) { |
460 r = upgrade_mode(dd, mode, t->md); 461 if (r) 462 return r; 463 } 464 atomic_inc(&dd->count); 465 466 if (!check_device_area(dd, start, len)) { 467 DMWARN("device %s too small for target", path); | 464 r = upgrade_mode(dd, mode, t->md); 465 if (r) 466 return r; 467 } 468 atomic_inc(&dd->count); 469 470 if (!check_device_area(dd, start, len)) { 471 DMWARN("device %s too small for target", path); |
468 dm_put_device(ti, dd); | 472 dm_put_device(ti, &dd->dm_dev); |
469 return -EINVAL; 470 } 471 | 473 return -EINVAL; 474 } 475 |
472 *result = dd; | 476 *result = &dd->dm_dev; |
473 474 return 0; 475} 476 477void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) 478{ 479 struct request_queue *q = bdev_get_queue(bdev); 480 struct io_restrictions *rs = &ti->limits; --- 54 unchanged lines hidden (view full) --- 535 dm_set_device_limits(ti, (*result)->bdev); 536 537 return r; 538} 539 540/* 541 * Decrement a devices use count and remove it if necessary. 542 */ | 477 478 return 0; 479} 480 481void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev) 482{ 483 struct request_queue *q = bdev_get_queue(bdev); 484 struct io_restrictions *rs = &ti->limits; --- 54 unchanged lines hidden (view full) --- 539 dm_set_device_limits(ti, (*result)->bdev); 540 541 return r; 542} 543 544/* 545 * Decrement a devices use count and remove it if necessary. 546 */ |
543void dm_put_device(struct dm_target *ti, struct dm_dev *dd) | 547void dm_put_device(struct dm_target *ti, struct dm_dev *d) |
544{ | 548{ |
549 struct dm_dev_internal *dd = container_of(d, struct dm_dev_internal, 550 dm_dev); 551 |
|
545 if (atomic_dec_and_test(&dd->count)) { 546 close_dev(dd, ti->table->md); 547 list_del(&dd->list); 548 kfree(dd); 549 } 550} 551 552/* --- 379 unchanged lines hidden (view full) --- 932 ti->type->resume(ti); 933 } 934 935 return 0; 936} 937 938int dm_table_any_congested(struct dm_table *t, int bdi_bits) 939{ | 552 if (atomic_dec_and_test(&dd->count)) { 553 close_dev(dd, ti->table->md); 554 list_del(&dd->list); 555 kfree(dd); 556 } 557} 558 559/* --- 379 unchanged lines hidden (view full) --- 939 ti->type->resume(ti); 940 } 941 942 return 0; 943} 944 945int dm_table_any_congested(struct dm_table *t, int bdi_bits) 946{ |
940 struct dm_dev *dd; | 947 struct dm_dev_internal *dd; |
941 struct list_head *devices = dm_table_get_devices(t); 942 int r = 0; 943 944 list_for_each_entry(dd, devices, list) { | 948 struct list_head *devices = dm_table_get_devices(t); 949 int r = 0; 950 951 list_for_each_entry(dd, devices, list) { |
945 struct request_queue *q = bdev_get_queue(dd->bdev); | 952 struct request_queue *q = bdev_get_queue(dd->dm_dev.bdev); |
946 r |= bdi_congested(&q->backing_dev_info, bdi_bits); 947 } 948 949 return r; 950} 951 952void dm_table_unplug_all(struct dm_table *t) 953{ | 953 r |= bdi_congested(&q->backing_dev_info, bdi_bits); 954 } 955 956 return r; 957} 958 959void dm_table_unplug_all(struct dm_table *t) 960{ |
954 struct dm_dev *dd; | 961 struct dm_dev_internal *dd; |
955 struct list_head *devices = dm_table_get_devices(t); 956 957 list_for_each_entry(dd, devices, list) { | 962 struct list_head *devices = dm_table_get_devices(t); 963 964 list_for_each_entry(dd, devices, list) { |
958 struct request_queue *q = bdev_get_queue(dd->bdev); | 965 struct request_queue *q = bdev_get_queue(dd->dm_dev.bdev); |
959 960 blk_unplug(q); 961 } 962} 963 964struct mapped_device *dm_table_get_md(struct dm_table *t) 965{ 966 dm_get(t->md); --- 14 unchanged lines hidden --- | 966 967 blk_unplug(q); 968 } 969} 970 971struct mapped_device *dm_table_get_md(struct dm_table *t) 972{ 973 dm_get(t->md); --- 14 unchanged lines hidden --- |