VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
author: Amos Waterland <apw@us.ibm.com> 2006-09-29 02:00:08 -0700 committer: Linus Torvalds <torvalds@g5.osdl.org> 2006-09-29 09:18:12 -0700 commit: 01d553d0fe9f90a132c5ff494872be8d4126be1e parent: f400e198b2ed26ce55b22a1412ded0896e7516ac
Commit Summary:
[PATCH] Chardev checking of overlapping ranges
Diffstat:
1 file changed, 20 insertions, 5 deletions
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 0009346d827f..33b95af89da4 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -128,13 +128,31 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
 
 	for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
 		if ((*cp)->major > major ||
-		    ((*cp)->major == major && (*cp)->baseminor >= baseminor))
+		    ((*cp)->major == major &&
+		     (((*cp)->baseminor >= baseminor) ||
+		      ((*cp)->baseminor + (*cp)->minorct > baseminor))))
 			break;
-	if (*cp && (*cp)->major == major &&
-	    (*cp)->baseminor < baseminor + minorct) {
-		ret = -EBUSY;
-		goto out;
+
+	/* Check for overlapping minor ranges.  */
+	if (*cp && (*cp)->major == major) {
+		int old_min = (*cp)->baseminor;
+		int old_max = (*cp)->baseminor + (*cp)->minorct - 1;
+		int new_min = baseminor;
+		int new_max = baseminor + minorct - 1;
+
+		/* New driver overlaps from the left.  */
+		if (new_max >= old_min && new_max <= old_max) {
+			ret = -EBUSY;
+			goto out;
+		}
+
+		/* New driver overlaps from the right.  */
+		if (new_min <= old_max && new_min >= old_min) {
+			ret = -EBUSY;
+			goto out;
+		}
 	}
+
 	cd->next = *cp;
 	*cp = cd;
 	mutex_unlock(&chrdevs_lock);