dm.c (62f75c2f3244553b1290447abd1f1e6b1144d3e9) | dm.c (f32c10b09940cffc3620ce111315ec44343fd3ca) |
---|---|
1/* 2 * Copyright (C) 2001, 2002 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" --- 12 unchanged lines hidden (view full) --- 21#include <linux/hdreg.h> 22#include <linux/blktrace_api.h> 23 24static const char *_name = DM_NAME; 25 26static unsigned int major = 0; 27static unsigned int _major = 0; 28 | 1/* 2 * Copyright (C) 2001, 2002 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" --- 12 unchanged lines hidden (view full) --- 21#include <linux/hdreg.h> 22#include <linux/blktrace_api.h> 23 24static const char *_name = DM_NAME; 25 26static unsigned int major = 0; 27static unsigned int _major = 0; 28 |
29static DEFINE_SPINLOCK(_minor_lock); |
|
29/* 30 * One of these is allocated per bio. 31 */ 32struct dm_io { 33 struct mapped_device *md; 34 int error; 35 struct bio *bio; 36 atomic_t io_count; --- 704 unchanged lines hidden (view full) --- 741 742 dm_table_put(map); 743 return r; 744} 745 746/*----------------------------------------------------------------- 747 * An IDR is used to keep track of allocated minor numbers. 748 *---------------------------------------------------------------*/ | 30/* 31 * One of these is allocated per bio. 32 */ 33struct dm_io { 34 struct mapped_device *md; 35 int error; 36 struct bio *bio; 37 atomic_t io_count; --- 704 unchanged lines hidden (view full) --- 742 743 dm_table_put(map); 744 return r; 745} 746 747/*----------------------------------------------------------------- 748 * An IDR is used to keep track of allocated minor numbers. 749 *---------------------------------------------------------------*/ |
749static DEFINE_MUTEX(_minor_lock); | |
750static DEFINE_IDR(_minor_idr); 751 752static void free_minor(unsigned int minor) 753{ | 750static DEFINE_IDR(_minor_idr); 751 752static void free_minor(unsigned int minor) 753{ |
754 mutex_lock(&_minor_lock); | 754 spin_lock(&_minor_lock); |
755 idr_remove(&_minor_idr, minor); | 755 idr_remove(&_minor_idr, minor); |
756 mutex_unlock(&_minor_lock); | 756 spin_unlock(&_minor_lock); |
757} 758 759/* 760 * See if the device with a specific minor # is free. 761 */ 762static int specific_minor(struct mapped_device *md, unsigned int minor) 763{ 764 int r, m; 765 766 if (minor >= (1 << MINORBITS)) 767 return -EINVAL; 768 769 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 770 if (!r) 771 return -ENOMEM; 772 | 757} 758 759/* 760 * See if the device with a specific minor # is free. 761 */ 762static int specific_minor(struct mapped_device *md, unsigned int minor) 763{ 764 int r, m; 765 766 if (minor >= (1 << MINORBITS)) 767 return -EINVAL; 768 769 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 770 if (!r) 771 return -ENOMEM; 772 |
773 mutex_lock(&_minor_lock); | 773 spin_lock(&_minor_lock); |
774 775 if (idr_find(&_minor_idr, minor)) { 776 r = -EBUSY; 777 goto out; 778 } 779 780 r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m); 781 if (r) 782 goto out; 783 784 if (m != minor) { 785 idr_remove(&_minor_idr, m); 786 r = -EBUSY; 787 goto out; 788 } 789 790out: | 774 775 if (idr_find(&_minor_idr, minor)) { 776 r = -EBUSY; 777 goto out; 778 } 779 780 r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m); 781 if (r) 782 goto out; 783 784 if (m != minor) { 785 idr_remove(&_minor_idr, m); 786 r = -EBUSY; 787 goto out; 788 } 789 790out: |
791 mutex_unlock(&_minor_lock); | 791 spin_unlock(&_minor_lock); |
792 return r; 793} 794 795static int next_free_minor(struct mapped_device *md, unsigned int *minor) 796{ 797 int r; 798 unsigned int m; 799 800 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 801 if (!r) 802 return -ENOMEM; 803 | 792 return r; 793} 794 795static int next_free_minor(struct mapped_device *md, unsigned int *minor) 796{ 797 int r; 798 unsigned int m; 799 800 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 801 if (!r) 802 return -ENOMEM; 803 |
804 mutex_lock(&_minor_lock); | 804 spin_lock(&_minor_lock); |
805 806 r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); 807 if (r) { 808 goto out; 809 } 810 811 if (m >= (1 << MINORBITS)) { 812 idr_remove(&_minor_idr, m); 813 r = -ENOSPC; 814 goto out; 815 } 816 817 *minor = m; 818 819out: | 805 806 r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); 807 if (r) { 808 goto out; 809 } 810 811 if (m >= (1 << MINORBITS)) { 812 idr_remove(&_minor_idr, m); 813 r = -ENOSPC; 814 goto out; 815 } 816 817 *minor = m; 818 819out: |
820 mutex_unlock(&_minor_lock); | 820 spin_unlock(&_minor_lock); |
821 return r; 822} 823 824static struct block_device_operations dm_blk_dops; 825 826/* 827 * Allocate and initialise a blank device with a given minor. 828 */ --- 53 unchanged lines hidden (view full) --- 882 add_disk(md->disk); 883 format_dev_t(md->name, MKDEV(_major, minor)); 884 885 atomic_set(&md->pending, 0); 886 init_waitqueue_head(&md->wait); 887 init_waitqueue_head(&md->eventq); 888 889 /* Populate the mapping, nobody knows we exist yet */ | 821 return r; 822} 823 824static struct block_device_operations dm_blk_dops; 825 826/* 827 * Allocate and initialise a blank device with a given minor. 828 */ --- 53 unchanged lines hidden (view full) --- 882 add_disk(md->disk); 883 format_dev_t(md->name, MKDEV(_major, minor)); 884 885 atomic_set(&md->pending, 0); 886 init_waitqueue_head(&md->wait); 887 init_waitqueue_head(&md->eventq); 888 889 /* Populate the mapping, nobody knows we exist yet */ |
890 mutex_lock(&_minor_lock); | 890 spin_lock(&_minor_lock); |
891 old_md = idr_replace(&_minor_idr, md, minor); | 891 old_md = idr_replace(&_minor_idr, md, minor); |
892 mutex_unlock(&_minor_lock); | 892 spin_unlock(&_minor_lock); |
893 894 BUG_ON(old_md != MINOR_ALLOCED); 895 896 return md; 897 898 bad4: 899 mempool_destroy(md->tio_pool); 900 bad3: --- 114 unchanged lines hidden (view full) --- 1015static struct mapped_device *dm_find_md(dev_t dev) 1016{ 1017 struct mapped_device *md; 1018 unsigned minor = MINOR(dev); 1019 1020 if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) 1021 return NULL; 1022 | 893 894 BUG_ON(old_md != MINOR_ALLOCED); 895 896 return md; 897 898 bad4: 899 mempool_destroy(md->tio_pool); 900 bad3: --- 114 unchanged lines hidden (view full) --- 1015static struct mapped_device *dm_find_md(dev_t dev) 1016{ 1017 struct mapped_device *md; 1018 unsigned minor = MINOR(dev); 1019 1020 if (MAJOR(dev) != _major || minor >= (1 << MINORBITS)) 1021 return NULL; 1022 |
1023 mutex_lock(&_minor_lock); | 1023 spin_lock(&_minor_lock); |
1024 1025 md = idr_find(&_minor_idr, minor); 1026 if (md && (md == MINOR_ALLOCED || (dm_disk(md)->first_minor != minor))) 1027 md = NULL; 1028 | 1024 1025 md = idr_find(&_minor_idr, minor); 1026 if (md && (md == MINOR_ALLOCED || (dm_disk(md)->first_minor != minor))) 1027 md = NULL; 1028 |
1029 mutex_unlock(&_minor_lock); | 1029 spin_unlock(&_minor_lock); |
1030 1031 return md; 1032} 1033 1034struct mapped_device *dm_get_md(dev_t dev) 1035{ 1036 struct mapped_device *md = dm_find_md(dev); 1037 --- 17 unchanged lines hidden (view full) --- 1055{ 1056 atomic_inc(&md->holders); 1057} 1058 1059void dm_put(struct mapped_device *md) 1060{ 1061 struct dm_table *map; 1062 | 1030 1031 return md; 1032} 1033 1034struct mapped_device *dm_get_md(dev_t dev) 1035{ 1036 struct mapped_device *md = dm_find_md(dev); 1037 --- 17 unchanged lines hidden (view full) --- 1055{ 1056 atomic_inc(&md->holders); 1057} 1058 1059void dm_put(struct mapped_device *md) 1060{ 1061 struct dm_table *map; 1062 |
1063 if (atomic_dec_and_test(&md->holders)) { | 1063 if (atomic_dec_and_lock(&md->holders, &_minor_lock)) { |
1064 map = dm_get_table(md); | 1064 map = dm_get_table(md); |
1065 mutex_lock(&_minor_lock); | |
1066 idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); | 1065 idr_replace(&_minor_idr, MINOR_ALLOCED, dm_disk(md)->first_minor); |
1067 mutex_unlock(&_minor_lock); | 1066 spin_unlock(&_minor_lock); |
1068 if (!dm_suspended(md)) { 1069 dm_table_presuspend_targets(map); 1070 dm_table_postsuspend_targets(map); 1071 } 1072 __unbind(md); 1073 dm_table_put(map); 1074 free_dev(md); 1075 } --- 259 unchanged lines hidden --- | 1067 if (!dm_suspended(md)) { 1068 dm_table_presuspend_targets(map); 1069 dm_table_postsuspend_targets(map); 1070 } 1071 __unbind(md); 1072 dm_table_put(map); 1073 free_dev(md); 1074 } --- 259 unchanged lines hidden --- |