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 ---