Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107282457
D14704.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D14704.diff
View Options
Index: head/sys/dev/md/md.c
===================================================================
--- head/sys/dev/md/md.c
+++ head/sys/dev/md/md.c
@@ -114,6 +114,21 @@
#define MD_NSECT (10000 * 2)
#endif
+struct md_req {
+ unsigned md_unit; /* unit number */
+ enum md_types md_type; /* type of disk */
+ off_t md_mediasize; /* size of disk in bytes */
+ unsigned md_sectorsize; /* sectorsize */
+ unsigned md_options; /* options */
+ int md_fwheads; /* firmware heads */
+ int md_fwsectors; /* firmware sectors */
+ char *md_file; /* pathname of file to mount */
+ enum uio_seg md_file_seg; /* location of md_file */
+ char *md_label; /* label of the device (userspace) */
+ int *md_units; /* pointer to units array (kernel) */
+ size_t md_units_nitems; /* items in md_units array */
+};
+
static MALLOC_DEFINE(M_MD, "md_disk", "Memory Disk");
static MALLOC_DEFINE(M_MDSECT, "md_sectors", "Memory Disk Sectors");
@@ -1285,29 +1300,29 @@
}
static int
-mdcreate_malloc(struct md_s *sc, struct md_ioctl *mdio)
+mdcreate_malloc(struct md_s *sc, struct md_req *mdr)
{
uintptr_t sp;
int error;
off_t u;
error = 0;
- if (mdio->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE))
+ if (mdr->md_options & ~(MD_AUTOUNIT | MD_COMPRESS | MD_RESERVE))
return (EINVAL);
- if (mdio->md_sectorsize != 0 && !powerof2(mdio->md_sectorsize))
+ if (mdr->md_sectorsize != 0 && !powerof2(mdr->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_fwsectors != 0)
- sc->fwsectors = mdio->md_fwsectors;
- if (mdio->md_fwheads != 0)
- sc->fwheads = mdio->md_fwheads;
- sc->flags = mdio->md_options & (MD_COMPRESS | MD_FORCE);
+ if (mdr->md_options & MD_RESERVE)
+ mdr->md_options &= ~MD_COMPRESS;
+ if (mdr->md_fwsectors != 0)
+ sc->fwsectors = mdr->md_fwsectors;
+ if (mdr->md_fwheads != 0)
+ sc->fwheads = mdr->md_fwheads;
+ sc->flags = mdr->md_options & (MD_COMPRESS | MD_FORCE);
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) {
+ if (mdr->md_options & MD_RESERVE) {
off_t nsectors;
nsectors = sc->mediasize / sc->sectorsize;
@@ -1368,19 +1383,15 @@
}
static int
-mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
+mdcreate_vnode(struct md_s *sc, struct md_req *mdr, struct thread *td)
{
struct vattr vattr;
struct nameidata nd;
char *fname;
int error, flags;
- /*
- * Kernel-originated requests must have the filename appended
- * to the mdio structure to protect against malicious software.
- */
- fname = mdio->md_file;
- if ((void *)fname != (void *)(mdio + 1)) {
+ fname = mdr->md_file;
+ if (mdr->md_file_seg == UIO_USERSPACE) {
error = copyinstr(fname, sc->file, sizeof(sc->file), NULL);
if (error != 0)
return (error);
@@ -1391,8 +1402,8 @@
* If the user specified that this is a read only device, don't
* set the FWRITE mask before trying to open the backing store.
*/
- flags = FREAD | ((mdio->md_options & MD_READONLY) ? 0 : FWRITE) \
- | ((mdio->md_options & MD_VERIFY) ? O_VERIFY : 0);
+ flags = FREAD | ((mdr->md_options & MD_READONLY) ? 0 : FWRITE) \
+ | ((mdr->md_options & MD_VERIFY) ? O_VERIFY : 0);
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, sc->file, td);
error = vn_open(&nd, &flags, 0, NULL);
if (error != 0)
@@ -1416,13 +1427,13 @@
nd.ni_vp->v_vflag |= VV_MD;
VOP_UNLOCK(nd.ni_vp, 0);
- if (mdio->md_fwsectors != 0)
- sc->fwsectors = mdio->md_fwsectors;
- if (mdio->md_fwheads != 0)
- sc->fwheads = mdio->md_fwheads;
+ if (mdr->md_fwsectors != 0)
+ sc->fwsectors = mdr->md_fwsectors;
+ if (mdr->md_fwheads != 0)
+ sc->fwheads = mdr->md_fwheads;
snprintf(sc->ident, sizeof(sc->ident), "MD-DEV%ju-INO%ju",
(uintmax_t)vattr.va_fsid, (uintmax_t)vattr.va_fileid);
- sc->flags = mdio->md_options & (MD_FORCE | MD_ASYNC | MD_VERIFY);
+ sc->flags = mdr->md_options & (MD_FORCE | MD_ASYNC | MD_VERIFY);
if (!(flags & FWRITE))
sc->flags |= MD_READONLY;
sc->vnode = nd.ni_vp;
@@ -1488,7 +1499,7 @@
}
static int
-mdresize(struct md_s *sc, struct md_ioctl *mdio)
+mdresize(struct md_s *sc, struct md_req *mdr)
{
int error, res;
vm_pindex_t oldpages, newpages;
@@ -1498,11 +1509,11 @@
case MD_NULL:
break;
case MD_SWAP:
- if (mdio->md_mediasize <= 0 ||
- (mdio->md_mediasize % PAGE_SIZE) != 0)
+ if (mdr->md_mediasize <= 0 ||
+ (mdr->md_mediasize % PAGE_SIZE) != 0)
return (EDOM);
oldpages = OFF_TO_IDX(round_page(sc->mediasize));
- newpages = OFF_TO_IDX(round_page(mdio->md_mediasize));
+ newpages = OFF_TO_IDX(round_page(mdr->md_mediasize));
if (newpages < oldpages) {
VM_OBJECT_WLOCK(sc->object);
vm_object_page_remove(sc->object, newpages, 0, 0);
@@ -1518,7 +1529,7 @@
oldpages), sc->cred);
if (!res)
return (ENOMEM);
- if ((mdio->md_options & MD_RESERVE) ||
+ if ((mdr->md_options & MD_RESERVE) ||
(sc->flags & MD_RESERVE)) {
error = swap_pager_reserve(sc->object,
oldpages, newpages - oldpages);
@@ -1539,7 +1550,7 @@
return (EOPNOTSUPP);
}
- sc->mediasize = mdio->md_mediasize;
+ sc->mediasize = mdr->md_mediasize;
g_topology_lock();
g_resize_provider(sc->pp, sc->mediasize);
g_topology_unlock();
@@ -1547,7 +1558,7 @@
}
static int
-mdcreate_swap(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
+mdcreate_swap(struct md_s *sc, struct md_req *mdr, struct thread *td)
{
vm_ooffset_t npage;
int error;
@@ -1565,19 +1576,19 @@
* Note the truncation.
*/
- if ((mdio->md_options & MD_VERIFY) != 0)
+ if ((mdr->md_options & MD_VERIFY) != 0)
return (EINVAL);
- npage = mdio->md_mediasize / PAGE_SIZE;
- if (mdio->md_fwsectors != 0)
- sc->fwsectors = mdio->md_fwsectors;
- if (mdio->md_fwheads != 0)
- sc->fwheads = mdio->md_fwheads;
+ npage = mdr->md_mediasize / PAGE_SIZE;
+ if (mdr->md_fwsectors != 0)
+ sc->fwsectors = mdr->md_fwsectors;
+ if (mdr->md_fwheads != 0)
+ sc->fwheads = mdr->md_fwheads;
sc->object = vm_pager_allocate(OBJT_SWAP, NULL, PAGE_SIZE * npage,
VM_PROT_DEFAULT, 0, td->td_ucred);
if (sc->object == NULL)
return (ENOMEM);
- sc->flags = mdio->md_options & (MD_FORCE | MD_RESERVE);
- if (mdio->md_options & MD_RESERVE) {
+ sc->flags = mdr->md_options & (MD_FORCE | MD_RESERVE);
+ if (mdr->md_options & MD_RESERVE) {
if (swap_pager_reserve(sc->object, 0, npage) < 0) {
error = EDOM;
goto finish;
@@ -1593,7 +1604,7 @@
}
static int
-mdcreate_null(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
+mdcreate_null(struct md_s *sc, struct md_req *mdr, struct thread *td)
{
/*
@@ -1607,7 +1618,7 @@
}
static int
-kern_mdattach_locked(struct thread *td, struct md_ioctl *mdio)
+kern_mdattach_locked(struct thread *td, struct md_req *mdr)
{
struct md_s *sc;
unsigned sectsize;
@@ -1615,7 +1626,7 @@
sx_assert(&md_sx, SA_XLOCKED);
- switch (mdio->md_type) {
+ switch (mdr->md_type) {
case MD_MALLOC:
case MD_PRELOAD:
case MD_VNODE:
@@ -1625,35 +1636,35 @@
default:
return (EINVAL);
}
- if (mdio->md_sectorsize == 0)
+ if (mdr->md_sectorsize == 0)
sectsize = DEV_BSIZE;
else
- sectsize = mdio->md_sectorsize;
- if (sectsize > MAXPHYS || mdio->md_mediasize < sectsize)
+ sectsize = mdr->md_sectorsize;
+ if (sectsize > MAXPHYS || mdr->md_mediasize < sectsize)
return (EINVAL);
- if (mdio->md_options & MD_AUTOUNIT)
- sc = mdnew(-1, &error, mdio->md_type);
+ if (mdr->md_options & MD_AUTOUNIT)
+ sc = mdnew(-1, &error, mdr->md_type);
else {
- if (mdio->md_unit > INT_MAX)
+ if (mdr->md_unit > INT_MAX)
return (EINVAL);
- sc = mdnew(mdio->md_unit, &error, mdio->md_type);
+ sc = mdnew(mdr->md_unit, &error, mdr->md_type);
}
if (sc == NULL)
return (error);
- if (mdio->md_label != NULL)
- error = copyinstr(mdio->md_label, sc->label,
+ if (mdr->md_label != NULL)
+ error = copyinstr(mdr->md_label, sc->label,
sizeof(sc->label), NULL);
if (error != 0)
goto err_after_new;
- if (mdio->md_options & MD_AUTOUNIT)
- mdio->md_unit = sc->unit;
- sc->mediasize = mdio->md_mediasize;
+ if (mdr->md_options & MD_AUTOUNIT)
+ mdr->md_unit = sc->unit;
+ sc->mediasize = mdr->md_mediasize;
sc->sectorsize = sectsize;
error = EDOOFUS;
switch (sc->type) {
case MD_MALLOC:
sc->start = mdstart_malloc;
- error = mdcreate_malloc(sc, mdio);
+ error = mdcreate_malloc(sc, mdr);
break;
case MD_PRELOAD:
/*
@@ -1665,15 +1676,15 @@
break;
case MD_VNODE:
sc->start = mdstart_vnode;
- error = mdcreate_vnode(sc, mdio, td);
+ error = mdcreate_vnode(sc, mdr, td);
break;
case MD_SWAP:
sc->start = mdstart_swap;
- error = mdcreate_swap(sc, mdio, td);
+ error = mdcreate_swap(sc, mdr, td);
break;
case MD_NULL:
sc->start = mdstart_null;
- error = mdcreate_null(sc, mdio, td);
+ error = mdcreate_null(sc, mdr, td);
break;
}
err_after_new:
@@ -1691,122 +1702,122 @@
}
static int
-kern_mdattach(struct thread *td, struct md_ioctl *mdio)
+kern_mdattach(struct thread *td, struct md_req *mdr)
{
int error;
sx_xlock(&md_sx);
- error = kern_mdattach_locked(td, mdio);
+ error = kern_mdattach_locked(td, mdr);
sx_xunlock(&md_sx);
return (error);
}
static int
-kern_mddetach_locked(struct thread *td, struct md_ioctl *mdio)
+kern_mddetach_locked(struct thread *td, struct md_req *mdr)
{
struct md_s *sc;
sx_assert(&md_sx, SA_XLOCKED);
- if (mdio->md_mediasize != 0 ||
- (mdio->md_options & ~MD_FORCE) != 0)
+ if (mdr->md_mediasize != 0 ||
+ (mdr->md_options & ~MD_FORCE) != 0)
return (EINVAL);
- sc = mdfind(mdio->md_unit);
+ sc = mdfind(mdr->md_unit);
if (sc == NULL)
return (ENOENT);
if (sc->opencount != 0 && !(sc->flags & MD_FORCE) &&
- !(mdio->md_options & MD_FORCE))
+ !(mdr->md_options & MD_FORCE))
return (EBUSY);
return (mddestroy(sc, td));
}
static int
-kern_mddetach(struct thread *td, struct md_ioctl *mdio)
+kern_mddetach(struct thread *td, struct md_req *mdr)
{
int error;
sx_xlock(&md_sx);
- error = kern_mddetach_locked(td, mdio);
+ error = kern_mddetach_locked(td, mdr);
sx_xunlock(&md_sx);
return (error);
}
static int
-kern_mdresize_locked(struct md_ioctl *mdio)
+kern_mdresize_locked(struct md_req *mdr)
{
struct md_s *sc;
sx_assert(&md_sx, SA_XLOCKED);
- if ((mdio->md_options & ~(MD_FORCE | MD_RESERVE)) != 0)
+ if ((mdr->md_options & ~(MD_FORCE | MD_RESERVE)) != 0)
return (EINVAL);
- sc = mdfind(mdio->md_unit);
+ sc = mdfind(mdr->md_unit);
if (sc == NULL)
return (ENOENT);
- if (mdio->md_mediasize < sc->sectorsize)
+ if (mdr->md_mediasize < sc->sectorsize)
return (EINVAL);
- if (mdio->md_mediasize < sc->mediasize &&
+ if (mdr->md_mediasize < sc->mediasize &&
!(sc->flags & MD_FORCE) &&
- !(mdio->md_options & MD_FORCE))
+ !(mdr->md_options & MD_FORCE))
return (EBUSY);
- return (mdresize(sc, mdio));
+ return (mdresize(sc, mdr));
}
static int
-kern_mdresize(struct md_ioctl *mdio)
+kern_mdresize(struct md_req *mdr)
{
int error;
sx_xlock(&md_sx);
- error = kern_mdresize_locked(mdio);
+ error = kern_mdresize_locked(mdr);
sx_xunlock(&md_sx);
return (error);
}
static int
-kern_mdquery_locked(struct md_ioctl *mdio)
+kern_mdquery_locked(struct md_req *mdr)
{
struct md_s *sc;
int error;
sx_assert(&md_sx, SA_XLOCKED);
- sc = mdfind(mdio->md_unit);
+ sc = mdfind(mdr->md_unit);
if (sc == NULL)
return (ENOENT);
- mdio->md_type = sc->type;
- mdio->md_options = sc->flags;
- mdio->md_mediasize = sc->mediasize;
- mdio->md_sectorsize = sc->sectorsize;
+ mdr->md_type = sc->type;
+ mdr->md_options = sc->flags;
+ mdr->md_mediasize = sc->mediasize;
+ mdr->md_sectorsize = sc->sectorsize;
error = 0;
- if (mdio->md_label != NULL) {
- error = copyout(sc->label, mdio->md_label,
+ if (mdr->md_label != NULL) {
+ error = copyout(sc->label, mdr->md_label,
strlen(sc->label) + 1);
if (error != 0)
return (error);
}
if (sc->type == MD_VNODE ||
- (sc->type == MD_PRELOAD && mdio->md_file != NULL))
- error = copyout(sc->file, mdio->md_file,
+ (sc->type == MD_PRELOAD && mdr->md_file != NULL))
+ error = copyout(sc->file, mdr->md_file,
strlen(sc->file) + 1);
return (error);
}
static int
-kern_mdquery(struct md_ioctl *mdio)
+kern_mdquery(struct md_req *mdr)
{
int error;
sx_xlock(&md_sx);
- error = kern_mdquery_locked(mdio);
+ error = kern_mdquery_locked(mdr);
sx_xunlock(&md_sx);
return (error);
}
static int
-kern_mdlist_locked(struct md_ioctl *mdio)
+kern_mdlist_locked(struct md_req *mdr)
{
struct md_s *sc;
int i;
@@ -1814,9 +1825,9 @@
sx_assert(&md_sx, SA_XLOCKED);
/*
- * Write the number of md devices to mdio->md_pad[0].
- * Write the unit number of the first (MDNPAD - 2) units
- * to mdio->md_pad[1::(MDNPAD - 2)] and terminate the
+ * Write the number of md devices to mdr->md_units[0].
+ * Write the unit number of the first (mdr->md_units_nitems - 2)
+ * units to mdr->md_units[1::(mdr->md_units - 2)] and terminate the
* list with -1.
*
* XXX: There is currently no mechanism to retrieve unit
@@ -1827,22 +1838,22 @@
*/
i = 1;
LIST_FOREACH(sc, &md_softc_list, list) {
- if (i < MDNPAD - 1)
- mdio->md_pad[i] = sc->unit;
+ if (i < mdr->md_units_nitems - 1)
+ mdr->md_units[i] = sc->unit;
i++;
}
- mdio->md_pad[MIN(i, MDNPAD - 1)] = -1;
- mdio->md_pad[0] = i - 1;
+ mdr->md_units[MIN(i, mdr->md_units_nitems - 1)] = -1;
+ mdr->md_units[0] = i - 1;
return (0);
}
static int
-kern_mdlist(struct md_ioctl *mdio)
+kern_mdlist(struct md_req *mdr)
{
int error;
sx_xlock(&md_sx);
- error = kern_mdlist_locked(mdio);
+ error = kern_mdlist_locked(mdr);
sx_xunlock(&md_sx);
return (error);
}
@@ -1851,6 +1862,7 @@
mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
struct thread *td)
{
+ struct md_req mdr;
struct md_ioctl *mdio;
int error;
@@ -1858,37 +1870,67 @@
printf("mdctlioctl(%s %lx %p %x %p)\n",
devtoname(dev), cmd, addr, flags, td);
- mdio = (struct md_ioctl *)addr;
- if (mdio->md_version != MDIOVERSION)
- return (EINVAL);
+ switch (cmd) {
+ case MDIOCATTACH:
+ case MDIOCDETACH:
+ case MDIOCRESIZE:
+ case MDIOCQUERY:
+ case MDIOCLIST:
+ mdio = (struct md_ioctl *)addr;
+ if (mdio->md_version != MDIOVERSION)
+ return (EINVAL);
+ mdr.md_unit = mdio->md_unit;
+ mdr.md_type = mdio->md_type;
+ mdr.md_mediasize = mdio->md_mediasize;
+ mdr.md_sectorsize = mdio->md_sectorsize;
+ mdr.md_options = mdio->md_options;
+ mdr.md_fwheads = mdio->md_fwheads;
+ mdr.md_fwsectors = mdio->md_fwsectors;
+ mdr.md_file = mdio->md_file;
+ /* If the file is adjacent to the md_ioctl it's in kernel. */
+ if ((void *)mdio->md_file == (void *)(mdio + 1))
+ mdr.md_file_seg = UIO_SYSSPACE;
+ else
+ mdr.md_file_seg = UIO_USERSPACE;
+ mdr.md_label = mdio->md_label;
+ mdr.md_units = &mdio->md_pad[0];
+ mdr.md_units_nitems = nitems(mdio->md_pad);
+ break;
+ }
- /*
- * We assert the version number in the individual ioctl
- * handlers instead of out here because (a) it is possible we
- * may add another ioctl in the future which doesn't read an
- * mdio, and (b) the correct return value for an unknown ioctl
- * is ENOIOCTL, not EINVAL.
- */
error = 0;
switch (cmd) {
case MDIOCATTACH:
- error = kern_mdattach(td, mdio);
+ error = kern_mdattach(td, &mdr);
break;
case MDIOCDETACH:
- error = kern_mddetach(td, mdio);
+ error = kern_mddetach(td, &mdr);
break;
case MDIOCRESIZE:
- error = kern_mdresize(mdio);
+ error = kern_mdresize(&mdr);
break;
case MDIOCQUERY:
- error = kern_mdquery(mdio);
+ error = kern_mdquery(&mdr);
break;
case MDIOCLIST:
- error = kern_mdlist(mdio);
+ error = kern_mdlist(&mdr);
break;
default:
error = ENOIOCTL;
- };
+ }
+
+ switch (cmd) {
+ case MDIOCATTACH:
+ case MDIOCQUERY:
+ mdio->md_unit = mdr.md_unit;
+ mdio->md_type = mdr.md_type;
+ mdio->md_mediasize = mdr.md_mediasize;
+ mdio->md_sectorsize = mdr.md_sectorsize;
+ mdio->md_options = mdr.md_options;
+ mdio->md_fwheads = mdr.md_fwheads;
+ mdio->md_fwsectors = mdr.md_fwsectors;
+ break;
+ }
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 11:00 PM (21 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15773594
Default Alt Text
D14704.diff (15 KB)
Attached To
Mode
D14704: Add a request structure and make the implementation use it.
Attached
Detach File
Event Timeline
Log In to Comment