Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151503311
D51127.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
D51127.diff
View Options
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -264,25 +264,40 @@
struct g_provider *pp;
int (*start)(struct md_s *sc, struct bio *bp);
struct devstat *devstat;
- bool candelete;
-
- /* MD_MALLOC related fields */
- struct indir *indir;
- uma_zone_t uma;
-
- /* MD_PRELOAD related fields */
- u_char *pl_ptr;
- size_t pl_len;
-
- /* MD_VNODE related fields */
- struct vnode *vnode;
- char file[PATH_MAX];
- char label[PATH_MAX];
struct ucred *cred;
- vm_offset_t kva;
+ char label[PATH_MAX];
+ bool candelete;
- /* MD_SWAP related fields */
- vm_object_t object;
+ union {
+ /* MD_MALLOC related fields */
+ struct {
+ struct indir *indir;
+ uma_zone_t uma;
+ } s_malloc;
+
+ /* MD_PRELOAD related fields */
+ struct {
+ u_char *pl_ptr;
+ size_t pl_len;
+ char name[PATH_MAX];
+ } s_preload;
+
+ /* MD_VNODE related fields */
+ struct {
+ struct vnode *vnode;
+ char file[PATH_MAX];
+ vm_offset_t kva;
+ } s_vnode;
+
+ /* MD_SWAP related fields */
+ struct {
+ vm_object_t object;
+ } s_swap;
+
+ /* MD_NULL */
+ struct {
+ } s_null;
+ };
};
static struct indir *
@@ -324,7 +339,7 @@
if (ip->shift)
destroy_indir(sc, (struct indir*)(ip->array[i]));
else if (ip->array[i] > 255)
- uma_zfree(sc->uma, (void *)(ip->array[i]));
+ uma_zfree(sc->s_malloc.uma, (void *)(ip->array[i]));
}
del_indir(ip);
}
@@ -675,10 +690,10 @@
secno = bp->bio_offset / sc->sectorsize;
error = 0;
while (nsec--) {
- osp = s_read(sc->indir, secno);
+ osp = s_read(sc->s_malloc.indir, secno);
if (bp->bio_cmd == BIO_DELETE) {
if (osp != 0)
- error = s_write(sc->indir, secno, 0);
+ error = s_write(sc->s_malloc.indir, secno, 0);
} else if (bp->bio_cmd == BIO_READ) {
if (osp == 0) {
if (notmapped) {
@@ -743,10 +758,12 @@
}
if (i == sc->sectorsize) {
if (osp != uc)
- error = s_write(sc->indir, secno, uc);
+ error = s_write(sc->s_malloc.indir,
+ secno, uc);
} else {
if (osp <= 255) {
- sp = (uintptr_t)uma_zalloc(sc->uma,
+ sp = (uintptr_t)uma_zalloc(
+ sc->s_malloc.uma,
md_malloc_wait ? M_WAITOK :
M_NOWAIT);
if (sp == 0) {
@@ -767,7 +784,8 @@
bcopy(dst, (void *)sp,
sc->sectorsize);
}
- error = s_write(sc->indir, secno, sp);
+ error = s_write(sc->s_malloc.indir,
+ secno, sp);
} else {
if (notmapped) {
error = md_malloc_move_ma(&m,
@@ -790,7 +808,7 @@
error = EOPNOTSUPP;
}
if (osp > 255)
- uma_zfree(sc->uma, (void*)osp);
+ uma_zfree(sc->s_malloc.uma, (void*)osp);
if (error != 0)
break;
secno++;
@@ -848,7 +866,7 @@
{
uint8_t *p;
- p = sc->pl_ptr + bp->bio_offset;
+ p = sc->s_preload.pl_ptr + bp->bio_offset;
switch (bp->bio_cmd) {
case BIO_READ:
if ((bp->bio_flags & BIO_VLIST) != 0) {
@@ -888,7 +906,7 @@
bool mapped;
td = curthread;
- vp = sc->vnode;
+ vp = sc->s_vnode.vnode;
piov = NULL;
ma_offs = bp->bio_ma_offset;
off = bp->bio_offset;
@@ -922,8 +940,8 @@
case BIO_DELETE:
if (sc->candelete) {
error = vn_deallocate(vp, &off, &len, 0,
- sc->flags & MD_ASYNC ? 0 : IO_SYNC, sc->cred,
- NOCRED);
+ sc->flags & MD_ASYNC ? 0 : IO_SYNC,
+ sc->cred, NOCRED);
bp->bio_resid = len;
return (error);
}
@@ -963,8 +981,10 @@
KASSERT(iolen > 0, ("zero iolen"));
KASSERT(npages <= atop(maxphys + PAGE_SIZE),
("npages %d too large", npages));
- pmap_qenter(sc->kva, &bp->bio_ma[atop(ma_offs)], npages);
- aiov.iov_base = (void *)(sc->kva + (ma_offs & PAGE_MASK));
+ pmap_qenter(sc->s_vnode.kva, &bp->bio_ma[atop(ma_offs)],
+ npages);
+ aiov.iov_base = (void *)(sc->s_vnode.kva + (ma_offs &
+ PAGE_MASK));
aiov.iov_len = iolen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
@@ -998,7 +1018,7 @@
POSIX_FADV_DONTNEED);
if (mapped) {
- pmap_qremove(sc->kva, npages);
+ pmap_qremove(sc->s_vnode.kva, npages);
if (error == 0) {
len -= iolen;
bp->bio_resid -= iolen;
@@ -1052,20 +1072,21 @@
lastend = (bp->bio_offset + bp->bio_length - 1) % PAGE_SIZE + 1;
rv = VM_PAGER_OK;
- vm_object_pip_add(sc->object, 1);
+ vm_object_pip_add(sc->s_swap.object, 1);
for (i = bp->bio_offset / PAGE_SIZE; i <= lastp; i++) {
len = ((i == lastp) ? lastend : PAGE_SIZE) - offs;
- m = vm_page_grab_unlocked(sc->object, i, VM_ALLOC_SYSTEM);
+ m = vm_page_grab_unlocked(sc->s_swap.object, i,
+ VM_ALLOC_SYSTEM);
if (bp->bio_cmd == BIO_READ) {
if (vm_page_all_valid(m))
rv = VM_PAGER_OK;
else
- rv = vm_pager_get_pages(sc->object, &m, 1,
- NULL, NULL);
+ rv = vm_pager_get_pages(sc->s_swap.object,
+ &m, 1, NULL, NULL);
if (rv == VM_PAGER_ERROR) {
- VM_OBJECT_WLOCK(sc->object);
+ VM_OBJECT_WLOCK(sc->s_swap.object);
vm_page_free(m);
- VM_OBJECT_WUNLOCK(sc->object);
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
break;
} else if (rv == VM_PAGER_FAIL) {
/*
@@ -1092,12 +1113,12 @@
if (len == PAGE_SIZE || vm_page_all_valid(m))
rv = VM_PAGER_OK;
else
- rv = vm_pager_get_pages(sc->object, &m, 1,
- NULL, NULL);
+ rv = vm_pager_get_pages(sc->s_swap.object,
+ &m, 1, NULL, NULL);
if (rv == VM_PAGER_ERROR) {
- VM_OBJECT_WLOCK(sc->object);
+ VM_OBJECT_WLOCK(sc->s_swap.object);
vm_page_free(m);
- VM_OBJECT_WUNLOCK(sc->object);
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
break;
} else if (rv == VM_PAGER_FAIL)
pmap_zero_page(m);
@@ -1118,12 +1139,12 @@
if (len == PAGE_SIZE || vm_page_all_valid(m))
rv = VM_PAGER_OK;
else
- rv = vm_pager_get_pages(sc->object, &m, 1,
- NULL, NULL);
- VM_OBJECT_WLOCK(sc->object);
+ rv = vm_pager_get_pages(sc->s_swap.object,
+ &m, 1, NULL, NULL);
+ VM_OBJECT_WLOCK(sc->s_swap.object);
if (rv == VM_PAGER_ERROR) {
vm_page_free(m);
- VM_OBJECT_WUNLOCK(sc->object);
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
break;
} else if (rv == VM_PAGER_FAIL) {
vm_page_free(m);
@@ -1139,7 +1160,7 @@
m = NULL;
}
}
- VM_OBJECT_WUNLOCK(sc->object);
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
}
if (m != NULL) {
/*
@@ -1159,7 +1180,7 @@
offs = 0;
ma_offs += len;
}
- vm_object_pip_wakeup(sc->object);
+ vm_object_pip_wakeup(sc->s_swap.object);
return (rv != VM_PAGER_ERROR ? 0 : ENOSPC);
}
@@ -1354,18 +1375,18 @@
if (mdr->md_fwheads != 0)
sc->fwheads = mdr->md_fwheads;
sc->flags = mdr->md_options & (MD_COMPRESS | MD_FORCE | MD_RESERVE);
- sc->indir = dimension(sc->mediasize / sc->sectorsize);
- sc->uma = uma_zcreate(sc->name, sc->sectorsize, NULL, NULL, NULL, NULL,
- 0x1ff, 0);
+ sc->s_malloc.indir = dimension(sc->mediasize / sc->sectorsize);
+ sc->s_malloc.uma = uma_zcreate(sc->name, sc->sectorsize, NULL, NULL,
+ NULL, NULL, 0x1ff, 0);
if (mdr->md_options & MD_RESERVE) {
off_t nsectors;
nsectors = sc->mediasize / sc->sectorsize;
for (u = 0; u < nsectors; u++) {
- sp = (uintptr_t)uma_zalloc(sc->uma, (md_malloc_wait ?
- M_WAITOK : M_NOWAIT) | M_ZERO);
+ sp = (uintptr_t)uma_zalloc(sc->s_malloc.uma,
+ (md_malloc_wait ? M_WAITOK : M_NOWAIT) | M_ZERO);
if (sp != 0)
- error = s_write(sc->indir, u, sp);
+ error = s_write(sc->s_malloc.indir, u, sp);
else
error = ENOMEM;
if (error != 0)
@@ -1393,7 +1414,7 @@
* Horrible kludge to establish credentials for NFS XXX.
*/
- if (sc->vnode) {
+ if (sc->type == MD_VNODE && sc->s_vnode.vnode != NULL) {
struct uio auio;
struct iovec aiov;
@@ -1408,9 +1429,9 @@
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_resid = aiov.iov_len;
- vn_lock(sc->vnode, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_READ(sc->vnode, &auio, 0, sc->cred);
- VOP_UNLOCK(sc->vnode);
+ vn_lock(sc->s_vnode.vnode, LK_EXCLUSIVE | LK_RETRY);
+ error = VOP_READ(sc->s_vnode.vnode, &auio, 0, sc->cred);
+ VOP_UNLOCK(sc->s_vnode.vnode);
free(tmpbuf, M_TEMP);
}
return (error);
@@ -1427,11 +1448,12 @@
fname = mdr->md_file;
if (mdr->md_file_seg == UIO_USERSPACE) {
- error = copyinstr(fname, sc->file, sizeof(sc->file), NULL);
+ error = copyinstr(fname, sc->s_vnode.file,
+ sizeof(sc->s_vnode.file), NULL);
if (error != 0)
return (error);
} else if (mdr->md_file_seg == UIO_SYSSPACE)
- strlcpy(sc->file, fname, sizeof(sc->file));
+ strlcpy(sc->s_vnode.file, fname, sizeof(sc->s_vnode.file));
else
return (EDOOFUS);
@@ -1441,7 +1463,7 @@
*/
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);
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, sc->s_vnode.file);
error = vn_open(&nd, &flags, 0, NULL);
if (error != 0)
return (error);
@@ -1481,17 +1503,17 @@
MD_VERIFY | MD_MUSTDEALLOC);
if (!(flags & FWRITE))
sc->flags |= MD_READONLY;
- sc->vnode = nd.ni_vp;
+ sc->s_vnode.vnode = nd.ni_vp;
error = mdsetcred(sc, td->td_ucred);
if (error != 0) {
- sc->vnode = NULL;
+ sc->s_vnode.vnode = NULL;
vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
nd.ni_vp->v_vflag &= ~VV_MD;
goto bad;
}
- sc->kva = kva_alloc(maxphys + PAGE_SIZE);
+ sc->s_vnode.kva = kva_alloc(maxphys + PAGE_SIZE);
return (0);
bad:
VOP_UNLOCK(nd.ni_vp);
@@ -1535,23 +1557,30 @@
msleep(sc->procp, &sc->queue_mtx, PRIBIO, "mddestroy", hz / 10);
mtx_unlock(&sc->queue_mtx);
mtx_destroy(&sc->queue_mtx);
- if (sc->vnode != NULL) {
- vn_lock(sc->vnode, LK_EXCLUSIVE | LK_RETRY);
- sc->vnode->v_vflag &= ~VV_MD;
- VOP_UNLOCK(sc->vnode);
- (void)vn_close(sc->vnode, sc->flags & MD_READONLY ?
+ switch (sc->type) {
+ case MD_VNODE:
+ vn_lock(sc->s_vnode.vnode, LK_EXCLUSIVE | LK_RETRY);
+ sc->s_vnode.vnode->v_vflag &= ~VV_MD;
+ VOP_UNLOCK(sc->s_vnode.vnode);
+ (void)vn_close(sc->s_vnode.vnode, sc->flags & MD_READONLY ?
FREAD : (FREAD|FWRITE), sc->cred, td);
+ kva_free(sc->s_vnode.kva, maxphys + PAGE_SIZE);
+ break;
+ case MD_SWAP:
+ vm_object_deallocate(sc->s_swap.object);
+ break;
+ case MD_MALLOC:
+ destroy_indir(sc, sc->s_malloc.indir);
+ uma_zdestroy(sc->s_malloc.uma);
+ break;
+ case MD_PRELOAD:
+ case MD_NULL:
+ break;
+ default:
+ __assert_unreachable();
}
if (sc->cred != NULL)
crfree(sc->cred);
- if (sc->object != NULL)
- vm_object_deallocate(sc->object);
- if (sc->indir)
- destroy_indir(sc, sc->indir);
- if (sc->uma)
- uma_zdestroy(sc->uma);
- if (sc->kva)
- kva_free(sc->kva, maxphys + PAGE_SIZE);
LIST_REMOVE(sc, list);
free_unr(md_uh, sc->unit);
@@ -1576,13 +1605,14 @@
oldpages = OFF_TO_IDX(sc->mediasize);
newpages = OFF_TO_IDX(mdr->md_mediasize);
if (newpages < oldpages) {
- VM_OBJECT_WLOCK(sc->object);
- vm_object_page_remove(sc->object, newpages, 0, 0);
+ VM_OBJECT_WLOCK(sc->s_swap.object);
+ vm_object_page_remove(sc->s_swap.object, newpages,
+ 0, 0);
swap_release_by_cred(IDX_TO_OFF(oldpages -
newpages), sc->cred);
- sc->object->charge = IDX_TO_OFF(newpages);
- sc->object->size = newpages;
- VM_OBJECT_WUNLOCK(sc->object);
+ sc->s_swap.object->charge = IDX_TO_OFF(newpages);
+ sc->s_swap.object->size = newpages;
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
} else if (newpages > oldpages) {
res = swap_reserve_by_cred(IDX_TO_OFF(newpages -
oldpages), sc->cred);
@@ -1590,7 +1620,7 @@
return (ENOMEM);
if ((mdr->md_options & MD_RESERVE) ||
(sc->flags & MD_RESERVE)) {
- error = swap_pager_reserve(sc->object,
+ error = swap_pager_reserve(sc->s_swap.object,
oldpages, newpages - oldpages);
if (error < 0) {
swap_release_by_cred(
@@ -1599,10 +1629,10 @@
return (EDOM);
}
}
- VM_OBJECT_WLOCK(sc->object);
- sc->object->charge = IDX_TO_OFF(newpages);
- sc->object->size = newpages;
- VM_OBJECT_WUNLOCK(sc->object);
+ VM_OBJECT_WLOCK(sc->s_swap.object);
+ sc->s_swap.object->charge = IDX_TO_OFF(newpages);
+ sc->s_swap.object->size = newpages;
+ VM_OBJECT_WUNLOCK(sc->s_swap.object);
}
break;
default:
@@ -1643,13 +1673,13 @@
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)
+ sc->s_swap.object = vm_pager_allocate(OBJT_SWAP, NULL,
+ PAGE_SIZE * npage, VM_PROT_DEFAULT, 0, td->td_ucred);
+ if (sc->s_swap.object == NULL)
return (ENOMEM);
sc->flags = mdr->md_options & (MD_FORCE | MD_RESERVE);
if (mdr->md_options & MD_RESERVE) {
- if (swap_pager_reserve(sc->object, 0, npage) < 0) {
+ if (swap_pager_reserve(sc->s_swap.object, 0, npage) < 0) {
error = EDOM;
goto finish;
}
@@ -1657,8 +1687,8 @@
error = mdsetcred(sc, td->td_ucred);
finish:
if (error != 0) {
- vm_object_deallocate(sc->object);
- sc->object = NULL;
+ vm_object_deallocate(sc->s_swap.object);
+ sc->s_swap.object = NULL;
}
return (error);
}
@@ -1856,10 +1886,13 @@
if (error != 0)
return (error);
}
- if (sc->type == MD_VNODE ||
- (sc->type == MD_PRELOAD && mdr->md_file != NULL))
- error = copyout(sc->file, mdr->md_file,
- strlen(sc->file) + 1);
+ if (sc->type == MD_VNODE) {
+ error = copyout(sc->s_vnode.file, mdr->md_file,
+ strlen(sc->s_vnode.file) + 1);
+ } else if (sc->type == MD_PRELOAD && mdr->md_file != NULL) {
+ error = copyout(sc->s_preload.name, mdr->md_file,
+ strlen(sc->s_preload.name) + 1);
+ }
return (error);
}
@@ -2011,11 +2044,12 @@
return;
sc->mediasize = length;
sc->sectorsize = DEV_BSIZE;
- sc->pl_ptr = image;
- sc->pl_len = length;
+ sc->s_preload.pl_ptr = image;
+ sc->s_preload.pl_len = length;
sc->start = mdstart_preload;
if (name != NULL)
- strlcpy(sc->file, name, sizeof(sc->file));
+ strlcpy(sc->s_preload.name, name,
+ sizeof(sc->s_preload.name));
#ifdef MD_ROOT
if (sc->unit == 0) {
#ifndef ROOTDEVNAME
@@ -2127,9 +2161,14 @@
sbuf_printf(sb, " fs %ju", (uintmax_t) mp->fwsectors);
sbuf_printf(sb, " l %ju", (uintmax_t) mp->mediasize);
sbuf_printf(sb, " t %s", type);
- if ((mp->type == MD_VNODE && mp->vnode != NULL) ||
- (mp->type == MD_PRELOAD && mp->file[0] != '\0'))
- sbuf_printf(sb, " file %s", mp->file);
+ if (mp->type == MD_VNODE &&
+ mp->s_vnode.vnode != NULL)
+ sbuf_printf(sb, " file %s", mp->s_vnode.file);
+ if (mp->type == MD_PRELOAD &&
+ mp->s_preload.name[0] != '\0') {
+ sbuf_printf(sb, " file %s",
+ mp->s_preload.name);
+ }
sbuf_printf(sb, " label %s", mp->label);
} else {
sbuf_printf(sb, "%s<unit>%d</unit>\n", indent,
@@ -2154,15 +2193,23 @@
"read-only");
sbuf_printf(sb, "%s<type>%s</type>\n", indent,
type);
- if ((mp->type == MD_VNODE && mp->vnode != NULL) ||
- (mp->type == MD_PRELOAD && mp->file[0] != '\0')) {
+ if (mp->type == MD_VNODE) {
+ if (mp->s_vnode.vnode != NULL) {
+ sbuf_printf(sb, "%s<file>", indent);
+ g_conf_printf_escaped(sb, "%s",
+ mp->s_vnode.file);
+ sbuf_printf(sb, "</file>\n");
+ }
+ sbuf_printf(sb, "%s<cache>%s</cache>\n", indent,
+ (mp->flags & MD_CACHE) == 0 ? "off": "on");
+ }
+ if (mp->type == MD_PRELOAD &&
+ mp->s_preload.name[0] != '\0') {
sbuf_printf(sb, "%s<file>", indent);
- g_conf_printf_escaped(sb, "%s", mp->file);
+ g_conf_printf_escaped(sb, "%s",
+ mp->s_preload.name);
sbuf_printf(sb, "</file>\n");
}
- if (mp->type == MD_VNODE)
- sbuf_printf(sb, "%s<cache>%s</cache>\n", indent,
- (mp->flags & MD_CACHE) == 0 ? "off": "on");
sbuf_printf(sb, "%s<label>", indent);
g_conf_printf_escaped(sb, "%s", mp->label);
sbuf_printf(sb, "</label>\n");
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 9, 9:12 PM (11 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31171795
Default Alt Text
D51127.diff (15 KB)
Attached To
Mode
D51127: md(4): move type-specific data under union
Attached
Detach File
Event Timeline
Log In to Comment