summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2008-06-11 18:55:19 +0000
committered <ed@FreeBSD.org>2008-06-11 18:55:19 +0000
commit1bfc2929862ee5b2f075e0e679a8e903d61e0bce (patch)
tree08955a306d4e2b47f429af5b10f9ef048618b232
parentcaec8ca31895494e3aa869e4a120eb00f6fda2ea (diff)
downloadFreeBSD-src-1bfc2929862ee5b2f075e0e679a8e903d61e0bce.zip
FreeBSD-src-1bfc2929862ee5b2f075e0e679a8e903d61e0bce.tar.gz
Don't enforce unique device minor number policy anymore.
Except for the case where we use the cloner library (clone_create() and friends), there is no reason to enforce a unique device minor number policy. There are various drivers in the source tree that allocate unr pools and such to provide minor numbers, without using them themselves. Because we still need to support unique device minor numbers for the cloner library, introduce a new flag called D_NEEDMINOR. All cdevsw's that are used in combination with the cloner library should be marked with this flag to make the cloning work. This means drivers can now freely use si_drv0 to store their own flags and state, making it effectively the same as si_drv1 and si_drv2. We still keep the minor() and dev2unit() routines around to make drivers happy. The NTFS code also used the minor number in its hash table. We should not do this anymore. If the si_drv0 field would be changed, it would no longer end up in the same list. Approved by: philip (mentor)
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c1
-rw-r--r--sys/dev/nmdm/nmdm.c2
-rw-r--r--sys/dev/snp/snp.c2
-rw-r--r--sys/dev/vkbd/vkbd.c2
-rw-r--r--sys/fs/ntfs/ntfs_ihash.c6
-rw-r--r--sys/i386/acpica/acpi_machdep.c2
-rw-r--r--sys/kern/kern_conf.c13
-rw-r--r--sys/net/if_tap.c2
-rw-r--r--sys/net/if_tun.c2
-rw-r--r--sys/security/audit/audit_pipe.c2
-rw-r--r--sys/sys/conf.h3
11 files changed, 22 insertions, 15 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index e5b039c..7d58b01 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -16445,6 +16445,7 @@ void dtrace_invop_uninit(void);
static struct cdevsw dtrace_cdevsw = {
.d_version = D_VERSION,
+ .d_flags = D_NEEDMINOR,
.d_close = dtrace_close,
.d_ioctl = dtrace_ioctl,
.d_open = dtrace_open,
diff --git a/sys/dev/nmdm/nmdm.c b/sys/dev/nmdm/nmdm.c
index 110553a..8536c18 100644
--- a/sys/dev/nmdm/nmdm.c
+++ b/sys/dev/nmdm/nmdm.c
@@ -68,7 +68,7 @@ static struct cdevsw nmdm_cdevsw = {
.d_open = nmdmopen,
.d_close = nmdmclose,
.d_name = "nmdn",
- .d_flags = D_TTY | D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_TTY | D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
};
#define BUFSIZ 100 /* Chunk size iomoved to/from user */
diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c
index 845ef31..3b52e48 100644
--- a/sys/dev/snp/snp.c
+++ b/sys/dev/snp/snp.c
@@ -44,7 +44,7 @@ static d_poll_t snppoll;
static struct cdevsw snp_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
.d_open = snpopen,
.d_close = snpclose,
.d_read = snpread,
diff --git a/sys/dev/vkbd/vkbd.c b/sys/dev/vkbd/vkbd.c
index 9807036..10e3516 100644
--- a/sys/dev/vkbd/vkbd.c
+++ b/sys/dev/vkbd/vkbd.c
@@ -158,7 +158,7 @@ static int vkbd_data_read(vkbd_state_t *, int);
static struct cdevsw vkbd_dev_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
.d_open = vkbd_dev_open,
.d_close = vkbd_dev_close,
.d_read = vkbd_dev_read,
diff --git a/sys/fs/ntfs/ntfs_ihash.c b/sys/fs/ntfs/ntfs_ihash.c
index 1356560..bb40d5c 100644
--- a/sys/fs/ntfs/ntfs_ihash.c
+++ b/sys/fs/ntfs/ntfs_ihash.c
@@ -52,7 +52,7 @@ MALLOC_DEFINE(M_NTFSNTHASH, "ntfs_nthash", "NTFS ntnode hash tables");
*/
static LIST_HEAD(nthashhead, ntnode) *ntfs_nthashtbl;
static u_long ntfs_nthash; /* size of hash table - 1 */
-#define NTNOHASH(device, inum) (&ntfs_nthashtbl[(minor(device) + (inum)) & ntfs_nthash])
+#define NTNOHASH(inum) (&ntfs_nthashtbl[(inum) & ntfs_nthash])
static struct mtx ntfs_nthash_mtx;
struct lock ntfs_hashlock;
@@ -90,7 +90,7 @@ ntfs_nthashlookup(dev, inum)
struct ntnode *ip;
mtx_lock(&ntfs_nthash_mtx);
- LIST_FOREACH(ip, NTNOHASH(dev, inum), i_hash)
+ LIST_FOREACH(ip, NTNOHASH(inum), i_hash)
if (inum == ip->i_number && dev == ip->i_dev)
break;
mtx_unlock(&ntfs_nthash_mtx);
@@ -108,7 +108,7 @@ ntfs_nthashins(ip)
struct nthashhead *ipp;
mtx_lock(&ntfs_nthash_mtx);
- ipp = NTNOHASH(ip->i_dev, ip->i_number);
+ ipp = NTNOHASH(ip->i_number);
LIST_INSERT_HEAD(ipp, ip, i_hash);
ip->i_flag |= IN_HASHED;
mtx_unlock(&ntfs_nthash_mtx);
diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c
index db78988..9d24e62 100644
--- a/sys/i386/acpica/acpi_machdep.c
+++ b/sys/i386/acpica/acpi_machdep.c
@@ -84,7 +84,7 @@ static struct filterops apm_readfiltops =
static struct cdevsw apm_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_TRACKCLOSE,
+ .d_flags = D_TRACKCLOSE | D_NEEDMINOR,
.d_open = apmopen,
.d_close = apmclose,
.d_write = apmwrite,
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index 39cc8a7..0cff9ea 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -566,10 +566,13 @@ newdev(struct cdevsw *csw, int y, struct cdev *si)
mtx_assert(&devmtx, MA_OWNED);
udev = y;
- LIST_FOREACH(si2, &csw->d_devs, si_list) {
- if (si2->si_drv0 == udev) {
- dev_free_devlocked(si);
- return (si2);
+ if (csw->d_flags & D_NEEDMINOR) {
+ /* We may want to return an existing device */
+ LIST_FOREACH(si2, &csw->d_devs, si_list) {
+ if (si2->si_drv0 == udev) {
+ dev_free_devlocked(si);
+ return (si2);
+ }
}
}
si->si_drv0 = udev;
@@ -1016,6 +1019,8 @@ clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, struct cdev **
("Illegal extra bits (0x%x) in clone_create", extra));
KASSERT(*up <= CLONE_UNITMASK,
("Too high unit (0x%x) in clone_create", *up));
+ KASSERT(csw->d_flags & D_NEEDMINOR,
+ ("clone_create() on cdevsw without minor numbers"));
/*
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index b8136d1..84b8d70 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -132,7 +132,7 @@ static struct filterops tap_write_filterops = {
static struct cdevsw tap_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
.d_open = tapopen,
.d_close = tapclose,
.d_read = tapread,
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index cf4a3b9..6f6f05c 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -162,7 +162,7 @@ static struct filterops tun_write_filterops = {
static struct cdevsw tun_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
.d_open = tunopen,
.d_close = tunclose,
.d_read = tunread,
diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c
index b67c97b..ff950c9 100644
--- a/sys/security/audit/audit_pipe.c
+++ b/sys/security/audit/audit_pipe.c
@@ -177,7 +177,7 @@ static d_kqfilter_t audit_pipe_kqfilter;
static struct cdevsw audit_pipe_cdevsw = {
.d_version = D_VERSION,
- .d_flags = D_PSEUDO | D_NEEDGIANT,
+ .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
.d_open = audit_pipe_open,
.d_close = audit_pipe_close,
.d_read = audit_pipe_read,
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index b9ba8fd..e26b721 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -71,7 +71,7 @@ struct cdev {
gid_t si_gid;
mode_t si_mode;
struct ucred *si_cred; /* cached clone-time credential */
- u_int si_drv0;
+ int si_drv0;
int si_refcount;
LIST_ENTRY(cdev) si_list;
LIST_ENTRY(cdev) si_clone;
@@ -171,6 +171,7 @@ typedef int dumper_t(
#define D_MMAP_ANON 0x00100000 /* special treatment in vm_mmap.c */
#define D_PSEUDO 0x00200000 /* make_dev() can return NULL */
#define D_NEEDGIANT 0x00400000 /* driver want Giant */
+#define D_NEEDMINOR 0x00800000 /* driver uses clone_create() */
/*
* Version numbers.
OpenPOWER on IntegriCloud