diff options
| author | Poul-Henning Kamp <phk@FreeBSD.org> | 1999-11-26 20:08:44 +0000 |
|---|---|---|
| committer | Poul-Henning Kamp <phk@FreeBSD.org> | 1999-11-26 20:08:44 +0000 |
| commit | 71e4fff823e1f5d08467df93c62f445b7d88d142 (patch) | |
| tree | 5ea3588f6376879ee2608c319d803b1f1b241cc5 /sys/dev/md | |
| parent | 7dfec6b427846273a0cb04fdbd87c8d5e121bcea (diff) | |
Notes
Diffstat (limited to 'sys/dev/md')
| -rw-r--r-- | sys/dev/md/md.c | 286 |
1 files changed, 192 insertions, 94 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 66d4a013e164..1b9ba0f82473 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -10,6 +10,9 @@ * */ +#include "opt_mfs.h" /* We have adopted some tasks from MFS */ +#include "opt_md.h" /* We have adopted some tasks from MFS */ + #include <sys/param.h> #include <sys/systm.h> #include <sys/buf.h> @@ -28,13 +31,33 @@ MALLOC_DEFINE(M_MD, "MD disk", "Memory Disk"); MALLOC_DEFINE(M_MDSECT, "MD sectors", "Memory Disk Sectors"); -static int md_debug = 0; +static int md_debug; SYSCTL_INT(_debug, OID_AUTO, mddebug, CTLFLAG_RW, &md_debug, 0, ""); +#if defined(MFS_ROOT) && !defined(MD_ROOT) +#define MD_ROOT MFS_ROOT +#warning "option MFS_ROOT has been superceeded by MD_ROOT" +#endif + +#if defined(MFS_ROOT_SIZE) && !defined(MD_ROOT_SIZE) +#define MD_ROOT_SIZE MFS_ROOT_SIZE +#warning "option MFS_ROOT_SIZE has been superceeded by MD_ROOT_SIZE" +#endif + +#if defined(MD_ROOT) && defined(MD_ROOT_SIZE) +/* Image gets put here: */ +static u_char mfs_root[MD_ROOT_SIZE*1024] = "MFS Filesystem goes here"; +static u_char end_mfs_root[] __unused = "MFS Filesystem had better STOP here"; +#endif + +static int mdrootready; + #define CDEV_MAJOR 95 #define BDEV_MAJOR 22 static d_strategy_t mdstrategy; +static d_strategy_t mdstrategy_preload; +static d_strategy_t mdstrategy_malloc; static d_open_t mdopen; static d_ioctl_t mdioctl; @@ -51,10 +74,9 @@ static struct cdevsw md_cdevsw = { /* maj */ CDEV_MAJOR, /* dump */ nodump, /* psize */ nopsize, - /* flags */ D_DISK | D_CANFREE, + /* flags */ D_DISK | D_CANFREE | D_MEMDISK, /* bmaj */ BDEV_MAJOR }; -static struct cdevsw mddisk_cdevsw; struct md_s { int unit; @@ -65,6 +87,7 @@ struct md_s { int busy; enum {MD_MALLOC, MD_PRELOAD} type; unsigned nsect; + struct cdevsw devsw; /* MD_MALLOC related fields */ unsigned nsecp; @@ -114,6 +137,26 @@ mdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) static void mdstrategy(struct buf *bp) { + struct md_s *sc; + + if (md_debug > 1) + printf("mdstrategy(%p) %s %lx, %d, %ld, %p)\n", + bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp->b_bcount / DEV_BSIZE, bp->b_data); + + sc = bp->b_dev->si_drv1; + if (sc->type == MD_MALLOC) { + mdstrategy_malloc(bp); + } else { + mdstrategy_preload(bp); + } + return; +} + + +static void +mdstrategy_malloc(struct buf *bp) +{ int s, i; struct md_s *sc; devstat_trans_flags dop; @@ -121,7 +164,7 @@ mdstrategy(struct buf *bp) unsigned secno, nsec, secval, uc; if (md_debug > 1) - printf("mdstrategy(%p) %s %lx, %d, %ld, %p)\n", + printf("mdstrategy_malloc(%p) %s %lx, %d, %ld, %p)\n", bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, bp->b_bcount / DEV_BSIZE, bp->b_data); @@ -155,90 +198,79 @@ mdstrategy(struct buf *bp) else dop = DEVSTAT_WRITE; - if (sc->type == MD_MALLOC) { - nsec = bp->b_bcount / DEV_BSIZE; - secno = bp->b_pblkno; - dst = bp->b_data; - while (nsec--) { + nsec = bp->b_bcount / DEV_BSIZE; + secno = bp->b_pblkno; + dst = bp->b_data; + while (nsec--) { - if (secno < sc->nsecp) { - secpp = &sc->secp[secno]; - if ((u_int)*secpp > 255) { - secp = *secpp; - secval = 0; - } else { - secp = 0; - secval = (u_int) *secpp; - } + if (secno < sc->nsecp) { + secpp = &sc->secp[secno]; + if ((u_int)*secpp > 255) { + secp = *secpp; + secval = 0; } else { - secpp = 0; secp = 0; - secval = 0; + secval = (u_int) *secpp; } - if (md_debug > 2) - printf("%lx %p %p %d\n", bp->b_flags, secpp, secp, secval); + } else { + secpp = 0; + secp = 0; + secval = 0; + } + if (md_debug > 2) + printf("%lx %p %p %d\n", bp->b_flags, secpp, secp, secval); - if (bp->b_flags & B_FREEBUF) { - if (secpp) { - if (secp) - FREE(secp, M_MDSECT); - *secpp = 0; - } - } else if (bp->b_flags & B_READ) { - if (secp) { - bcopy(secp, dst, DEV_BSIZE); - } else if (secval) { - for (i = 0; i < DEV_BSIZE; i++) - dst[i] = secval; - } else { - bzero(dst, DEV_BSIZE); - } + if (bp->b_flags & B_FREEBUF) { + if (secpp) { + if (secp) + FREE(secp, M_MDSECT); + *secpp = 0; + } + } else if (bp->b_flags & B_READ) { + if (secp) { + bcopy(secp, dst, DEV_BSIZE); + } else if (secval) { + for (i = 0; i < DEV_BSIZE; i++) + dst[i] = secval; } else { - uc = dst[0]; - for (i = 1; i < DEV_BSIZE; i++) - if (dst[i] != uc) - break; - if (i == DEV_BSIZE && !uc) { + bzero(dst, DEV_BSIZE); + } + } else { + uc = dst[0]; + for (i = 1; i < DEV_BSIZE; i++) + if (dst[i] != uc) + break; + if (i == DEV_BSIZE && !uc) { + if (secp) + FREE(secp, M_MDSECT); + if (secpp) + *secpp = (u_char *)uc; + } else { + if (!secpp) { + MALLOC(secpp, u_char **, (secno + nsec + 1) * sizeof(u_char *), M_MD, M_WAITOK); + bzero(secpp, (secno + nsec + 1) * sizeof(u_char *)); + bcopy(sc->secp, secpp, sc->nsecp * sizeof(u_char *)); + FREE(sc->secp, M_MD); + sc->secp = secpp; + sc->nsecp = secno + nsec + 1; + secpp = &sc->secp[secno]; + } + if (i == DEV_BSIZE) { if (secp) FREE(secp, M_MDSECT); - if (secpp) - *secpp = (u_char *)uc; + *secpp = (u_char *)uc; } else { - if (!secpp) { - MALLOC(secpp, u_char **, (secno + nsec + 1) * sizeof(u_char *), M_MD, M_WAITOK); - bzero(secpp, (secno + nsec + 1) * sizeof(u_char *)); - bcopy(sc->secp, secpp, sc->nsecp * sizeof(u_char *)); - FREE(sc->secp, M_MD); - sc->secp = secpp; - sc->nsecp = secno + nsec + 1; - secpp = &sc->secp[secno]; - } - if (i == DEV_BSIZE) { - if (secp) - FREE(secp, M_MDSECT); - *secpp = (u_char *)uc; - } else { - if (!secp) - MALLOC(secp, u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK); - bcopy(dst, secp, DEV_BSIZE); + if (!secp) + MALLOC(secp, u_char *, DEV_BSIZE, M_MDSECT, M_WAITOK); + bcopy(dst, secp, DEV_BSIZE); - *secpp = secp; - } + *secpp = secp; } } - secno++; - dst += DEV_BSIZE; - } - } else { - if (bp->b_flags & B_FREEBUF) { - /* nothing */ - } else if (bp->b_flags & B_READ) { - bcopy(sc->pl_ptr + (secno << DEV_BSHIFT), bp->b_data, bp->b_bcount); - } else { - bcopy(bp->b_data, sc->pl_ptr + (secno << DEV_BSHIFT), bp->b_bcount); } + secno++; + dst += DEV_BSIZE; } - bp->b_resid = 0; devstat_end_transaction_buf(&sc->stats, bp); biodone(bp); @@ -248,8 +280,62 @@ mdstrategy(struct buf *bp) return; } + static void -mdcreate_preload(u_char *image, unsigned length) +mdstrategy_preload(struct buf *bp) +{ + int s; + struct md_s *sc; + devstat_trans_flags dop; + + if (md_debug > 1) + printf("mdstrategy_preload(%p) %s %lx, %d, %ld, %p)\n", + bp, devtoname(bp->b_dev), bp->b_flags, bp->b_blkno, + bp->b_bcount / DEV_BSIZE, bp->b_data); + + sc = bp->b_dev->si_drv1; + + s = splbio(); + + bufqdisksort(&sc->buf_queue, bp); + + if (sc->busy) { + splx(s); + return; + } + + sc->busy++; + + while (1) { + bp = bufq_first(&sc->buf_queue); + if (bp) + bufq_remove(&sc->buf_queue, bp); + splx(s); + if (!bp) + break; + + devstat_start_transaction(&sc->stats); + + if (bp->b_flags & B_FREEBUF) { + dop = DEVSTAT_NO_DATA; + } else if (bp->b_flags & B_READ) { + dop = DEVSTAT_READ; + bcopy(sc->pl_ptr + (bp->b_pblkno << DEV_BSHIFT), bp->b_data, bp->b_bcount); + } else { + dop = DEVSTAT_WRITE; + bcopy(bp->b_data, sc->pl_ptr + (bp->b_pblkno << DEV_BSHIFT), bp->b_bcount); + } + bp->b_resid = 0; + devstat_end_transaction_buf(&sc->stats, bp); + biodone(bp); + s = splbio(); + } + sc->busy = 0; + return; +} + +static struct md_s * +mdcreate(struct cdevsw *devsw) { struct md_s *sc; @@ -260,13 +346,25 @@ mdcreate_preload(u_char *image, unsigned length) bufq_init(&sc->buf_queue); devstat_add_entry(&sc->stats, "md", sc->unit, DEV_BSIZE, DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, 0x190); - sc->dev = disk_create(sc->unit, &sc->disk, 0, - &md_cdevsw, &mddisk_cdevsw); + DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, + DEVSTAT_PRIORITY_OTHER); + sc->dev = disk_create(sc->unit, &sc->disk, 0, devsw, &sc->devsw); sc->dev->si_drv1 = sc; + return (sc); +} + +static void +mdcreate_preload(u_char *image, unsigned length) +{ + struct md_s *sc; + + sc = mdcreate(&md_cdevsw); sc->nsect = length / DEV_BSIZE; sc->pl_ptr = image; sc->pl_len = length; + + if (sc->unit == 0) + mdrootready = 1; } static void @@ -274,21 +372,8 @@ mdcreate_malloc(void) { struct md_s *sc; - MALLOC(sc, struct md_s *,sizeof(*sc), M_MD, M_WAITOK); - bzero(sc, sizeof(*sc)); - sc->unit = mdunits++; - sc->type = MD_MALLOC; - - bufq_init(&sc->buf_queue); - - devstat_add_entry(&sc->stats, "md", sc->unit, DEV_BSIZE, - DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_OTHER, 0x190); - - sc->dev = disk_create(sc->unit, &sc->disk, 0, - &md_cdevsw, &mddisk_cdevsw); + sc = mdcreate(&md_cdevsw); - sc->dev->si_drv1 = sc; sc->nsect = MDNSECT; /* for now */ MALLOC(sc->secp, u_char **, sizeof(u_char *), M_MD, M_WAITOK); bzero(sc->secp, sizeof(u_char *)); @@ -304,6 +389,9 @@ md_drvinit(void *unused) u_char *ptr, *name, *type; unsigned len; +#ifdef MD_ROOT_SIZE + mdcreate_preload(mfs_root, MD_ROOT_SIZE*1024); +#endif mod = NULL; while ((mod = preload_search_next_name(mod)) != NULL) { name = (char *)preload_search_info(mod, MODINFO_NAME); @@ -312,7 +400,7 @@ md_drvinit(void *unused) continue; if (type == NULL) continue; - if (strcmp(type, "md_image")) + if (strcmp(type, "md_image") && strcmp(type, "mfs_root")) continue; c = preload_search_info(mod, MODINFO_ADDR); ptr = *(u_char **)c; @@ -325,5 +413,15 @@ md_drvinit(void *unused) mdcreate_malloc(); } -SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, md_drvinit,NULL) +SYSINIT(mddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, md_drvinit,NULL) +#ifdef MD_ROOT +static void +md_takeroot(void *junk) +{ + if (mdrootready) + rootdevnames[0] = "ufs:/dev/md0c"; +} + +SYSINIT(md_root, SI_SUB_MOUNT_ROOT, SI_ORDER_FIRST, md_takeroot, NULL); +#endif |
