diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-09-16 21:32:13 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2004-09-16 21:32:13 +0000 |
commit | b830359bc58e3733d84002a4e2c438c378ff5b30 (patch) | |
tree | c8eed432da84045183ce12e190d7155be6324b88 /sys | |
parent | fdbe44b0cda0f2b6909099d898a99aa84079d569 (diff) | |
download | src-b830359bc58e3733d84002a4e2c438c378ff5b30.tar.gz src-b830359bc58e3733d84002a4e2c438c378ff5b30.zip |
- Make md(4) 64-bit clean.
After this change it should be possible to use very big md(4) devices.
- Clean up and simplify the code a bit.
- Use humanize_number(3) to print size of md(4) devices.
- Add 't' suffix which stands for terabyte.
- Make '-S' to really work with all types of devices.
- Other minor changes.
Notes
Notes:
svn path=/head/; revision=135340
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/md/md.c | 250 | ||||
-rw-r--r-- | sys/sys/mdioctl.h | 4 |
2 files changed, 91 insertions, 163 deletions
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 6d5cfa93f1a6..caee7cfaa232 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -153,9 +153,9 @@ struct md_s { struct mtx queue_mtx; struct cdev *dev; enum md_types type; - unsigned nsect; + off_t mediasize; + unsigned sectorsize; unsigned opencount; - unsigned secsize; unsigned fwheads; unsigned fwsectors; unsigned flags; @@ -170,7 +170,7 @@ struct md_s { /* MD_PRELOAD related fields */ u_char *pl_ptr; - unsigned pl_len; + size_t pl_len; /* MD_VNODE related fields */ struct vnode *vnode; @@ -386,11 +386,11 @@ mdstart_malloc(struct md_s *sc, struct bio *bp) { int i, error; u_char *dst; - unsigned secno, nsec, uc; + off_t secno, nsec, uc; uintptr_t sp, osp; - nsec = bp->bio_length / sc->secsize; - secno = bp->bio_offset / sc->secsize; + nsec = bp->bio_length / sc->sectorsize; + secno = bp->bio_offset / sc->sectorsize; dst = bp->bio_data; error = 0; while (nsec--) { @@ -400,38 +400,38 @@ mdstart_malloc(struct md_s *sc, struct bio *bp) error = s_write(sc->indir, secno, 0); } else if (bp->bio_cmd == BIO_READ) { if (osp == 0) - bzero(dst, sc->secsize); + bzero(dst, sc->sectorsize); else if (osp <= 255) - for (i = 0; i < sc->secsize; i++) + for (i = 0; i < sc->sectorsize; i++) dst[i] = osp; else - bcopy((void *)osp, dst, sc->secsize); + bcopy((void *)osp, dst, sc->sectorsize); osp = 0; } else if (bp->bio_cmd == BIO_WRITE) { if (sc->flags & MD_COMPRESS) { uc = dst[0]; - for (i = 1; i < sc->secsize; i++) + for (i = 1; i < sc->sectorsize; i++) if (dst[i] != uc) break; } else { i = 0; uc = 0; } - if (i == sc->secsize) { + if (i == sc->sectorsize) { if (osp != uc) error = s_write(sc->indir, secno, uc); } else { if (osp <= 255) { - sp = (uintptr_t) uma_zalloc( - sc->uma, M_NOWAIT); + sp = (uintptr_t)uma_zalloc(sc->uma, + M_NOWAIT); if (sp == 0) { error = ENOSPC; break; } - bcopy(dst, (void *)sp, sc->secsize); + bcopy(dst, (void *)sp, sc->sectorsize); error = s_write(sc->indir, secno, sp); } else { - bcopy(dst, (void *)osp, sc->secsize); + bcopy(dst, (void *)osp, sc->sectorsize); osp = 0; } } @@ -443,7 +443,7 @@ mdstart_malloc(struct md_s *sc, struct bio *bp) if (error) break; secno++; - dst += sc->secsize; + dst += sc->sectorsize; } bp->bio_resid = 0; return (error); @@ -726,8 +726,8 @@ mdinit(struct md_s *sc) gp = g_new_geomf(&g_md_class, "md%d", sc->unit); gp->softc = sc; pp = g_new_providerf(gp, "md%d", sc->unit); - pp->mediasize = (off_t)sc->nsect * sc->secsize; - pp->sectorsize = sc->secsize; + pp->mediasize = sc->mediasize; + pp->sectorsize = sc->sectorsize; sc->gp = gp; sc->pp = pp; g_error_provider(pp, 0); @@ -743,98 +743,59 @@ mdinit(struct md_s *sc) */ static int -mdcreate_preload(struct md_ioctl *mdio) +mdcreate_preload(struct md_s *sc, struct md_ioctl *mdio) { - struct md_s *sc; - if (mdio->md_size == 0) - return (EINVAL); - if (mdio->md_options & ~(MD_AUTOUNIT)) + if (mdio->md_options & ~(MD_AUTOUNIT | MD_FORCE)) return (EINVAL); - if (mdio->md_options & MD_AUTOUNIT) { - sc = mdnew(-1); - if (sc == NULL) - return (ENOMEM); - mdio->md_unit = sc->unit; - } else { - sc = mdnew(mdio->md_unit); - if (sc == NULL) - return (EBUSY); - } - sc->type = MD_PRELOAD; - sc->secsize = DEV_BSIZE; - sc->nsect = mdio->md_size; sc->flags = mdio->md_options & MD_FORCE; /* Cast to pointer size, then to pointer to avoid warning */ sc->pl_ptr = (u_char *)(uintptr_t)mdio->md_base; - sc->pl_len = (mdio->md_size << DEV_BSHIFT); - mdinit(sc); + sc->pl_len = (size_t)sc->mediasize; return (0); } static int -mdcreate_malloc(struct md_ioctl *mdio) +mdcreate_malloc(struct md_s *sc, struct md_ioctl *mdio) { - struct md_s *sc; - off_t u; uintptr_t sp; int error; + off_t u; error = 0; - if (mdio->md_size == 0) - return (EINVAL); if (mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE)) return (EINVAL); - if (mdio->md_secsize != 0 && !powerof2(mdio->md_secsize)) + if (mdio->md_sectorsize != 0 && !powerof2(mdio->md_sectorsize)) return (EINVAL); /* Compression doesn't make sense if we have reserved space */ if (mdio->md_options & MD_RESERVE) mdio->md_options &= ~MD_COMPRESS; - if (mdio->md_options & MD_AUTOUNIT) { - sc = mdnew(-1); - if (sc == NULL) - return (ENOMEM); - mdio->md_unit = sc->unit; - } else { - sc = mdnew(mdio->md_unit); - if (sc == NULL) - return (EBUSY); - } - sc->type = MD_MALLOC; - if (mdio->md_secsize != 0) - sc->secsize = mdio->md_secsize; - else - sc->secsize = DEV_BSIZE; if (mdio->md_fwsectors != 0) sc->fwsectors = mdio->md_fwsectors; if (mdio->md_fwheads != 0) sc->fwheads = mdio->md_fwheads; - sc->nsect = (mdio->md_size * DEV_BSIZE) / sc->secsize; sc->flags = mdio->md_options & (MD_COMPRESS | MD_FORCE); - sc->indir = dimension(sc->nsect); - sc->uma = uma_zcreate(sc->name, sc->secsize, - NULL, NULL, NULL, NULL, 0x1ff, 0); + sc->indir = dimension(sc->mediasize / sc->sectorsize); + sc->uma = uma_zcreate(sc->name, sc->sectorsize, NULL, NULL, NULL, NULL, + 0x1ff, 0); if (mdio->md_options & MD_RESERVE) { - for (u = 0; u < sc->nsect; u++) { - sp = (uintptr_t) uma_zalloc(sc->uma, M_NOWAIT | M_ZERO); + off_t nsectors; + + nsectors = sc->mediasize / sc->sectorsize; + for (u = 0; u < nsectors; u++) { + sp = (uintptr_t)uma_zalloc(sc->uma, M_NOWAIT | M_ZERO); if (sp != 0) error = s_write(sc->indir, u, sp); else error = ENOMEM; - if (error) + if (error != 0) break; } } - if (error) { + if (error != 0) uma_zdestroy(sc->uma); - mddestroy(sc, NULL); - return (error); - } - mdinit(sc); - if (!(mdio->md_options & MD_RESERVE)) - sc->pp->flags |= G_PF_CANDELETE; - return (0); + return (error); } @@ -860,11 +821,11 @@ mdsetcred(struct md_s *sc, struct ucred *cred) struct uio auio; struct iovec aiov; - tmpbuf = malloc(sc->secsize, M_TEMP, M_WAITOK); + tmpbuf = malloc(sc->sectorsize, M_TEMP, M_WAITOK); bzero(&auio, sizeof(auio)); aiov.iov_base = tmpbuf; - aiov.iov_len = sc->secsize; + aiov.iov_len = sc->sectorsize; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = 0; @@ -880,9 +841,8 @@ mdsetcred(struct md_s *sc, struct ucred *cred) } static int -mdcreate_vnode(struct md_ioctl *mdio, struct thread *td) +mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td) { - struct md_s *sc; struct vattr vattr; struct nameidata nd; int error, flags; @@ -904,52 +864,25 @@ mdcreate_vnode(struct md_ioctl *mdio, struct thread *td) if (nd.ni_vp->v_type != VREG || (error = VOP_GETATTR(nd.ni_vp, &vattr, td->td_ucred, td))) { VOP_UNLOCK(nd.ni_vp, 0, td); - (void) vn_close(nd.ni_vp, flags, td->td_ucred, td); + (void)vn_close(nd.ni_vp, flags, td->td_ucred, td); return (error ? error : EINVAL); } VOP_UNLOCK(nd.ni_vp, 0, td); - if (mdio->md_options & MD_AUTOUNIT) { - sc = mdnew(-1); - mdio->md_unit = sc->unit; - } else { - sc = mdnew(mdio->md_unit); - } - if (sc == NULL) { - (void) vn_close(nd.ni_vp, flags, td->td_ucred, td); - return (EBUSY); - } - if (mdio->md_fwsectors != 0) sc->fwsectors = mdio->md_fwsectors; if (mdio->md_fwheads != 0) sc->fwheads = mdio->md_fwheads; - sc->type = MD_VNODE; sc->flags = mdio->md_options & (MD_FORCE | MD_ASYNC); if (!(flags & FWRITE)) sc->flags |= MD_READONLY; - sc->secsize = DEV_BSIZE; sc->vnode = nd.ni_vp; - /* - * If the size is specified, override the file attributes. - */ - if (mdio->md_size) - sc->nsect = mdio->md_size; - else - sc->nsect = vattr.va_size / sc->secsize; /* XXX: round up ? */ - if (sc->nsect == 0) { - (void) vn_close(nd.ni_vp, flags, td->td_ucred, td); - mddestroy(sc, td); - return (EINVAL); - } error = mdsetcred(sc, td->td_ucred); - if (error) { - (void) vn_close(nd.ni_vp, flags, td->td_ucred, td); - mddestroy(sc, td); + if (error != 0) { + (void)vn_close(nd.ni_vp, flags, td->td_ucred, td); return (error); } - mdinit(sc); return (0); } @@ -999,47 +932,27 @@ mddestroy(struct md_s *sc, struct thread *td) } static int -mdcreate_swap(struct md_ioctl *mdio, struct thread *td) +mdcreate_swap(struct md_s *sc, struct md_ioctl *mdio, struct thread *td) { - struct md_s *sc; vm_ooffset_t npage; int error; GIANT_REQUIRED; - if (mdio->md_options & MD_AUTOUNIT) { - sc = mdnew(-1); - mdio->md_unit = sc->unit; - } else { - sc = mdnew(mdio->md_unit); - } - if (sc == NULL) - return (EBUSY); - - sc->type = MD_SWAP; - /* * Range check. Disallow negative sizes or any size less then the * size of a page. Then round to a page. */ - - if (mdio->md_size == 0) { - mddestroy(sc, td); + if (sc->mediasize == 0 || (sc->mediasize % PAGE_SIZE) != 0) return (EDOM); - } /* * Allocate an OBJT_SWAP object. * - * sc_nsect is in units of DEV_BSIZE. - * npage is in units of PAGE_SIZE. - * * Note the truncation. */ - sc->secsize = DEV_BSIZE; - npage = mdio->md_size / (PAGE_SIZE / DEV_BSIZE); - sc->nsect = npage * (PAGE_SIZE / DEV_BSIZE); + npage = mdio->md_mediasize / PAGE_SIZE; if (mdio->md_fwsectors != 0) sc->fwsectors = mdio->md_fwsectors; if (mdio->md_fwheads != 0) @@ -1051,7 +964,6 @@ mdcreate_swap(struct md_ioctl *mdio, struct thread *td) if (swap_pager_reserve(sc->object, 0, npage) < 0) { vm_object_deallocate(sc->object); sc->object = NULL; - mddestroy(sc, td); return (EDOM); } } @@ -1059,13 +971,8 @@ mdcreate_swap(struct md_ioctl *mdio, struct thread *td) if (error) { vm_object_deallocate(sc->object); sc->object = NULL; - mddestroy(sc, td); - return (error); } - mdinit(sc); - if (!(mdio->md_options & MD_RESERVE)) - sc->pp->flags |= G_PF_CANDELETE; - return (0); + return (error); } static int @@ -1094,7 +1001,7 @@ mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread { struct md_ioctl *mdio; struct md_s *sc; - int i; + int error, i; if (md_debug) printf("mdctlioctl(%s %lx %p %x %p)\n", @@ -1114,20 +1021,52 @@ mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread return (EINVAL); switch (mdio->md_type) { case MD_MALLOC: - return (mdcreate_malloc(mdio)); case MD_PRELOAD: - return (mdcreate_preload(mdio)); case MD_VNODE: - return (mdcreate_vnode(mdio, td)); case MD_SWAP: - return (mdcreate_swap(mdio, td)); + break; default: return (EINVAL); } + if (mdio->md_options & MD_AUTOUNIT) { + sc = mdnew(-1); + mdio->md_unit = sc->unit; + } else { + sc = mdnew(mdio->md_unit); + if (sc == NULL) + return (EBUSY); + } + sc->type = mdio->md_type; + sc->mediasize = mdio->md_mediasize; + if (mdio->md_sectorsize == 0) + sc->sectorsize = DEV_BSIZE; + else + sc->sectorsize = mdio->md_sectorsize; + error = EDOOFUS; + switch (sc->type) { + case MD_MALLOC: + error = mdcreate_malloc(sc, mdio); + break; + case MD_PRELOAD: + error = mdcreate_preload(sc, mdio); + break; + case MD_VNODE: + error = mdcreate_vnode(sc, mdio, td); + break; + case MD_SWAP: + error = mdcreate_swap(sc, mdio, td); + break; + } + if (error != 0) { + mddestroy(sc, td); + return (error); + } + mdinit(sc); + return (0); case MDIOCDETACH: if (mdio->md_version != MDIOVERSION) return (EINVAL); - if (mdio->md_file != NULL || mdio->md_size != 0 || + if (mdio->md_file != NULL || mdio->md_mediasize != 0 || mdio->md_options != 0) return (EINVAL); return (mddetach(mdio->md_unit, td)); @@ -1139,22 +1078,11 @@ mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread return (ENOENT); mdio->md_type = sc->type; mdio->md_options = sc->flags; - switch (sc->type) { - case MD_MALLOC: - mdio->md_size = sc->nsect; - break; - case MD_PRELOAD: - mdio->md_size = sc->nsect; - mdio->md_base = (uint64_t)(intptr_t)sc->pl_ptr; - break; - case MD_SWAP: - mdio->md_size = sc->nsect; - break; - case MD_VNODE: - mdio->md_size = sc->nsect; + mdio->md_mediasize = sc->mediasize; + mdio->md_sectorsize = sc->sectorsize; + if (sc->type == MD_VNODE) { /* XXX fill this in */ mdio->md_file = NULL; - break; } return (0); case MDIOCLIST: @@ -1174,7 +1102,7 @@ mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread } static void -md_preloaded(u_char *image, unsigned length) +md_preloaded(u_char *image, size_t length) { struct md_s *sc; @@ -1182,8 +1110,8 @@ md_preloaded(u_char *image, unsigned length) if (sc == NULL) return; sc->type = MD_PRELOAD; - sc->secsize = DEV_BSIZE; - sc->nsect = length / DEV_BSIZE; + sc->mediasize = length; + sc->sectorsize = DEV_BSIZE; sc->pl_ptr = image; sc->pl_len = length; #ifdef MD_ROOT diff --git a/sys/sys/mdioctl.h b/sys/sys/mdioctl.h index 4243f49e18ea..e45c096085ea 100644 --- a/sys/sys/mdioctl.h +++ b/sys/sys/mdioctl.h @@ -55,10 +55,10 @@ struct md_ioctl { unsigned md_unit; /* unit number */ enum md_types md_type ; /* type of disk */ char *md_file; /* pathname of file to mount */ - unsigned md_size; /* size of disk in DEV_BSIZE units */ + off_t md_mediasize; /* size of disk in bytes */ + unsigned md_sectorsize; /* sectorsize */ unsigned md_options; /* options */ u_int64_t md_base; /* base address */ - int md_secsize; /* sectorsize */ int md_fwheads; /* firmware heads */ int md_fwsectors; /* firmware sectors */ int md_pad[MDNPAD]; /* padding for future ideas */ |