summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_conf.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-07-20 09:47:55 +0000
committerphk <phk@FreeBSD.org>1999-07-20 09:47:55 +0000
commitcacc73aa1890c8a258a383716e0c90da798acd4e (patch)
tree895deb1c3a5fdc3b63cee3173606b1811c3149f5 /sys/kern/kern_conf.c
parentcf4a7fab742bfd88596615a4e608783600af67b5 (diff)
downloadFreeBSD-src-cacc73aa1890c8a258a383716e0c90da798acd4e.zip
FreeBSD-src-cacc73aa1890c8a258a383716e0c90da798acd4e.tar.gz
Now a dev_t is a pointer to struct specinfo which is shared by all specdev
vnodes referencing this device. Details: cdevsw->d_parms has been removed, the specinfo is available now (== dev_t) and the driver should modify it directly when applicable, and the only driver doing so, does so: vn.c. I am not sure the logic in checking for "<" was right before, and it looks even less so now. An intial pool of 50 struct specinfo are depleted during early boot, after that malloc had better work. It is likely that fewer than 50 would do. Hashing is done from udev_t to dev_t with a prime number remainder hash, experiments show no better hash available for decent cost (MD5 is only marginally better) The prime number used should not be close to a power of two, we use 83 for now. Add new checkalias2() to get around the loss of info from dev2udev() in bdevvp(); The aliased vnodes are hung on a list straight of the dev_t, and speclisth[SPECSZ] is unused. The sharing of struct specinfo means that the v_specnext moves into the vnode which grows by 4 bytes. Don't use a VBLK dev_t which doesn't make sense in MFS, now we hang a dummy cdevsw on B/Cmaj 253 so that things look sane. Storage overhead from all of this is O(50k). Bump __FreeBSD_version to 400009 The next step will add the stuff needed so device-drivers can start to hang things from struct specinfo
Diffstat (limited to 'sys/kern/kern_conf.c')
-rw-r--r--sys/kern/kern_conf.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index caedd0f..f14f1e6 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -30,20 +30,34 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: kern_conf.c,v 1.49 1999/07/17 19:57:25 phk Exp $
+ * $Id: kern_conf.c,v 1.50 1999/07/19 09:37:59 phk Exp $
*/
#include <sys/param.h>
+#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/module.h>
+#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/vnode.h>
+#include <sys/queue.h>
+
+#include <miscfs/specfs/specdev.h>
#define cdevsw_ALLOCSTART (NUMCDEVSW/2)
struct cdevsw *cdevsw[NUMCDEVSW];
-int bmaj2cmaj[NUMCDEVSW];
+static int bmaj2cmaj[NUMCDEVSW];
+
+MALLOC_DEFINE(M_DEVT, "dev_t", "dev_t storage");
+
+#define DEVT_HASH 83
+#define DEVT_STASH 50
+
+static struct specinfo devt_stash[DEVT_STASH];
+
+static SLIST_HEAD(devt_hash_head, specinfo) dev_hash[DEVT_HASH];
/*
* Routine to convert from character to block device number.
@@ -87,7 +101,7 @@ cdevsw_add(struct cdevsw *newentry)
if (!setup) {
for (i = 0; i < NUMCDEVSW; i++)
if (!bmaj2cmaj[i])
- bmaj2cmaj[i] = 256;
+ bmaj2cmaj[i] = 254;
setup++;
}
@@ -104,7 +118,7 @@ cdevsw_add(struct cdevsw *newentry)
cdevsw[newentry->d_maj] = newentry;
if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) {
- if (bmaj2cmaj[newentry->d_bmaj] != 256) {
+ if (bmaj2cmaj[newentry->d_bmaj] != 254) {
printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n",
newentry->d_name,
cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name);
@@ -169,51 +183,63 @@ devsw_module_handler(module_t mod, int what, void* arg)
* dev_t and u_dev_t primitives
*/
-#define DEVT_FASCIST 1
-
int
major(dev_t x)
{
- uintptr_t i = (uintptr_t)x;
-
-#ifdef DEVT_FASCIST
- return(255 - ((i >> 8) & 0xff));
-#else
- return((i >> 8) & 0xff);
-#endif
+ if (x == NODEV)
+ return NOUDEV;
+ return((x->si_udev >> 8) & 0xff);
}
int
minor(dev_t x)
{
- uintptr_t i = (uintptr_t)x;
-
- return(i & 0xffff00ff);
+ if (x == NODEV)
+ return NOUDEV;
+ return(x->si_udev & 0xffff00ff);
}
dev_t
makebdev(int x, int y)
{
- if (bmaj2cmaj[x] == 256) {
- return NODEV;
- }
return (makedev(bmaj2cmaj[x], y));
}
dev_t
makedev(int x, int y)
{
-#ifdef DEVT_FASCIST
- return ((dev_t)(uintptr_t) (((255 - x) << 8) | y));
-#else
- return ((dev_t)(uintptr_t) ((x << 8) | y));
-#endif
+ struct specinfo *si;
+ udev_t udev;
+ int hash;
+ static int stashed;
+
+ udev = (x << 8) | y;
+ hash = udev % DEVT_HASH;
+ SLIST_FOREACH(si, &dev_hash[hash], si_hash) {
+ if (si->si_udev == udev)
+ return (si);
+ }
+ if (stashed >= DEVT_STASH) {
+ MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT,
+ M_USE_RESERVE);
+ } else {
+ si = devt_stash + stashed++;
+ }
+ bzero(si, sizeof(*si));
+ si->si_udev = udev;
+ si->si_bsize_phys = DEV_BSIZE;
+ si->si_bsize_best = BLKDEV_IOSIZE;
+ si->si_bsize_max = MAXBSIZE;
+ SLIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
+ return (si);
}
udev_t
dev2udev(dev_t x)
{
- return makeudev(major(x), minor(x));
+ if (x == NODEV)
+ return NOUDEV;
+ return (x->si_udev);
}
dev_t
OpenPOWER on IntegriCloud