aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c55
1 files changed, 15 insertions, 40 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 314a0e2faf79..e67a4be0080d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -318,7 +318,6 @@ static void __exit dm_exit(void)
318 /* 318 /*
319 * Should be empty by this point. 319 * Should be empty by this point.
320 */ 320 */
321 idr_remove_all(&_minor_idr);
322 idr_destroy(&_minor_idr); 321 idr_destroy(&_minor_idr);
323} 322}
324 323
@@ -1756,62 +1755,38 @@ static void free_minor(int minor)
1756 */ 1755 */
1757static int specific_minor(int minor) 1756static int specific_minor(int minor)
1758{ 1757{
1759 int r, m; 1758 int r;
1760 1759
1761 if (minor >= (1 << MINORBITS)) 1760 if (minor >= (1 << MINORBITS))
1762 return -EINVAL; 1761 return -EINVAL;
1763 1762
1764 r = idr_pre_get(&_minor_idr, GFP_KERNEL); 1763 idr_preload(GFP_KERNEL);
1765 if (!r)
1766 return -ENOMEM;
1767
1768 spin_lock(&_minor_lock); 1764 spin_lock(&_minor_lock);
1769 1765
1770 if (idr_find(&_minor_idr, minor)) { 1766 r = idr_alloc(&_minor_idr, MINOR_ALLOCED, minor, minor + 1, GFP_NOWAIT);
1771 r = -EBUSY;
1772 goto out;
1773 }
1774
1775 r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m);
1776 if (r)
1777 goto out;
1778 1767
1779 if (m != minor) {
1780 idr_remove(&_minor_idr, m);
1781 r = -EBUSY;
1782 goto out;
1783 }
1784
1785out:
1786 spin_unlock(&_minor_lock); 1768 spin_unlock(&_minor_lock);
1787 return r; 1769 idr_preload_end();
1770 if (r < 0)
1771 return r == -ENOSPC ? -EBUSY : r;
1772 return 0;
1788} 1773}
1789 1774
1790static int next_free_minor(int *minor) 1775static int next_free_minor(int *minor)
1791{ 1776{
1792 int r, m; 1777 int r;
1793
1794 r = idr_pre_get(&_minor_idr, GFP_KERNEL);
1795 if (!r)
1796 return -ENOMEM;
1797 1778
1779 idr_preload(GFP_KERNEL);
1798 spin_lock(&_minor_lock); 1780 spin_lock(&_minor_lock);
1799 1781
1800 r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m); 1782 r = idr_alloc(&_minor_idr, MINOR_ALLOCED, 0, 1 << MINORBITS, GFP_NOWAIT);
1801 if (r)
1802 goto out;
1803
1804 if (m >= (1 << MINORBITS)) {
1805 idr_remove(&_minor_idr, m);
1806 r = -ENOSPC;
1807 goto out;
1808 }
1809
1810 *minor = m;
1811 1783
1812out:
1813 spin_unlock(&_minor_lock); 1784 spin_unlock(&_minor_lock);
1814 return r; 1785 idr_preload_end();
1786 if (r < 0)
1787 return r;
1788 *minor = r;
1789 return 0;
1815} 1790}
1816 1791
1817static const struct block_device_operations dm_blk_dops; 1792static const struct block_device_operations dm_blk_dops;