All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Corry <kevcorry@us.ibm.com>
To: Andrew Morton <akpm@osdl.org>, Linus Torvalds <torvalds@osdl.org>
Cc: LKML <linux-kernel@vger.kernel.org>
Subject: [PATCH] 1/1: Device-Mapper: Remove 1024 devices limitation
Date: Thu, 1 Jul 2004 10:35:13 -0500	[thread overview]
Message-ID: <200407011035.13283.kevcorry@us.ibm.com> (raw)

Remove the limitation of 1024 DM devices.

Signed-off-by: Kevin Corry <kevcorry@us.ibm.com>

--- diff/drivers/md/dm.c	2004-06-30 08:45:34.512303600 -0500
+++ source/drivers/md/dm.c	2004-06-30 08:48:42.085788096 -0500
@@ -17,11 +17,13 @@
 #include <linux/slab.h>
 
 static const char *_name = DM_NAME;
-#define MAX_DEVICES 1024
 
 static unsigned int major = 0;
 static unsigned int _major = 0;
 
+static int realloc_minor_bits(unsigned long requested_minor);
+static void free_minor_bits(void);
+
 /*
  * One of these is allocated per bio.
  */
@@ -111,11 +113,19 @@
 		return -ENOMEM;
 	}
 
+	r = realloc_minor_bits(1024);
+	if (r < 0) {
+		kmem_cache_destroy(_tio_cache);
+		kmem_cache_destroy(_io_cache);
+		return r;
+	}
+
 	_major = major;
 	r = register_blkdev(_major, _name);
 	if (r < 0) {
 		kmem_cache_destroy(_tio_cache);
 		kmem_cache_destroy(_io_cache);
+		free_minor_bits();
 		return r;
 	}
 
@@ -129,6 +139,7 @@
 {
 	kmem_cache_destroy(_tio_cache);
 	kmem_cache_destroy(_io_cache);
+	free_minor_bits();
 
 	if (unregister_blkdev(_major, _name) < 0)
 		DMERR("devfs_unregister_blkdev failed");
@@ -615,14 +626,58 @@
 /*-----------------------------------------------------------------
  * A bitset is used to keep track of allocated minor numbers.
  *---------------------------------------------------------------*/
-static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED;
-static unsigned long _minor_bits[MAX_DEVICES / BITS_PER_LONG];
+static DECLARE_MUTEX(_minor_lock);
+static unsigned long *_minor_bits = NULL;
+static unsigned long _max_minors = 0;
+
+#define MINORS_SIZE(minors) ((minors / BITS_PER_LONG) * sizeof(unsigned long))
+
+static int realloc_minor_bits(unsigned long requested_minor)
+{
+	unsigned long max_minors;
+	unsigned long *minor_bits, *tmp;
+
+	if (requested_minor < _max_minors)
+		return -EINVAL;
+
+	/* Round up the requested minor to the next power-of-2. */
+	max_minors = 1 << fls(requested_minor - 1);
+	if (max_minors > (1 << MINORBITS))
+		return -EINVAL;
+
+	minor_bits = kmalloc(MINORS_SIZE(max_minors), GFP_KERNEL);
+	if (!minor_bits)
+		return -ENOMEM;
+	memset(minor_bits, 0, MINORS_SIZE(max_minors));
+
+	/* Copy the existing bit-set to the new one. */
+	if (_minor_bits)
+		memcpy(minor_bits, _minor_bits, MINORS_SIZE(_max_minors));
+
+	tmp = _minor_bits;
+	_minor_bits = minor_bits;
+	_max_minors = max_minors;
+	if (tmp)
+		kfree(tmp);
+
+	return 0;
+}
+
+static void free_minor_bits(void)
+{
+	down(&_minor_lock);
+	kfree(_minor_bits);
+	_minor_bits = NULL;
+	_max_minors = 0;
+	up(&_minor_lock);
+}
 
 static void free_minor(unsigned int minor)
 {
-	spin_lock(&_minor_lock);
-	clear_bit(minor, _minor_bits);
-	spin_unlock(&_minor_lock);
+	down(&_minor_lock);
+	if (minor < _max_minors)
+		clear_bit(minor, _minor_bits);
+	up(&_minor_lock);
 }
 
 /*
@@ -630,37 +685,48 @@
  */
 static int specific_minor(unsigned int minor)
 {
-	int r = -EBUSY;
+	int r = 0;
 
-	if (minor >= MAX_DEVICES) {
-		DMWARN("request for a mapped_device beyond MAX_DEVICES (%d)",
-		       MAX_DEVICES);
+	if (minor > (1 << MINORBITS))
 		return -EINVAL;
+
+	down(&_minor_lock);
+	if (minor >= _max_minors) {
+		r = realloc_minor_bits(minor);
+		if (r) {
+			up(&_minor_lock);
+			return r;
+		}
 	}
 
-	spin_lock(&_minor_lock);
-	if (!test_and_set_bit(minor, _minor_bits))
-		r = 0;
-	spin_unlock(&_minor_lock);
+	if (test_and_set_bit(minor, _minor_bits))
+		r = -EBUSY;
+	up(&_minor_lock);
 
 	return r;
 }
 
 static int next_free_minor(unsigned int *minor)
 {
-	int r = -EBUSY;
+	int r;
 	unsigned int m;
 
-	spin_lock(&_minor_lock);
-	m = find_first_zero_bit(_minor_bits, MAX_DEVICES);
-	if (m != MAX_DEVICES) {
-		set_bit(m, _minor_bits);
-		*minor = m;
-		r = 0;
+	down(&_minor_lock);
+	m = find_first_zero_bit(_minor_bits, _max_minors);
+	if (m >= _max_minors) {
+		r = realloc_minor_bits(_max_minors * 2);
+		if (r) {
+			up(&_minor_lock);
+			return r;
+		}
+		m = find_first_zero_bit(_minor_bits, _max_minors);
 	}
-	spin_unlock(&_minor_lock);
 
-	return r;
+	set_bit(m, _minor_bits);
+	*minor = m;
+	up(&_minor_lock);
+
+	return 0;
 }
 
 static struct block_device_operations dm_blk_dops;

             reply	other threads:[~2004-07-01 15:35 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-07-01 15:35 Kevin Corry [this message]
2004-07-01 21:38 ` [PATCH] 1/1: Device-Mapper: Remove 1024 devices limitation Andrew Morton
2004-07-02  2:54   ` Kevin Corry
2004-07-02  3:30     ` Andrew Morton
2004-07-02 17:33       ` Kevin Corry
2004-07-02 19:42         ` Andrew Morton
2004-07-06 18:23           ` Kevin Corry
2004-07-06 21:23             ` Andrew Morton
2004-07-06 21:35               ` Alasdair G Kergon
2004-07-06 22:04                 ` Alasdair G Kergon
2004-07-06 22:20                 ` Andrew Morton
2004-07-06 22:07               ` Jim Houston
2004-07-06 22:28                 ` Andrew Morton
2004-07-06 23:00                   ` Jim Houston
2004-07-06 23:16                     ` Andrew Morton
2004-07-07 10:58                       ` Jim Houston
2004-07-07 11:10                         ` Andrew Morton
2004-07-12 14:49                           ` Kevin Corry
2004-07-12 18:14                             ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200407011035.13283.kevcorry@us.ibm.com \
    --to=kevcorry@us.ibm.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.