ml_iterator_switch Switch from direct mountlist traversal to mountlist iterator. diff -r ff3f89481f2e -r 28fea04e7b15 sys/coda/coda_vfsops.c --- a/sys/coda/coda_vfsops.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/coda/coda_vfsops.c Thu Mar 30 11:17:57 2017 +0200 @@ -624,23 +624,20 @@ NULL, NULL); } -#include -#include -/* get the mount structure corresponding to a given device. Assume - * device corresponds to a UFS. Return NULL if no device is found. +/* Get the mount structure corresponding to a given device. + * Return NULL if no device is found or the device is not mounted. */ struct mount *devtomp(dev_t dev) { struct mount *mp; + struct vnode *vp; - mutex_enter(&mountlist_lock); - TAILQ_FOREACH(mp, &mountlist, mnt_list) { - if ((!strcmp(mp->mnt_op->vfs_name, MOUNT_UFS)) && - ((VFSTOUFS(mp))->um_dev == (dev_t) dev)) { - /* mount corresponds to UFS and the device matches one we want */ - break; - } + if (spec_node_lookup_by_dev(VBLK, dev, &vp) == 0) { + mp = spec_node_getmountedfs(vp); + vrele(vp); + } else { + mp = NULL; } - mutex_exit(&mountlist_lock); + return mp; } diff -r ff3f89481f2e -r 28fea04e7b15 sys/compat/common/vfs_syscalls_20.c --- a/sys/compat/common/vfs_syscalls_20.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/compat/common/vfs_syscalls_20.c Thu Mar 30 11:17:57 2017 +0200 @@ -203,7 +203,8 @@ syscallarg(int) flags; } */ int root = 0; - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; struct statvfs *sbuf; struct statfs12 *sfsp; size_t count, maxcount; @@ -212,16 +213,13 @@ sbuf = malloc(sizeof(*sbuf), M_TEMP, M_WAITOK); maxcount = (size_t)SCARG(uap, bufsize) / sizeof(struct statfs12); sfsp = SCARG(uap, buf); - mutex_enter(&mountlist_lock); count = 0; - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 0); if (error) { - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); continue; } error = vfs2fs(sfsp, sbuf); @@ -233,9 +231,8 @@ root |= strcmp(sbuf->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); if (root == 0 && l->l_proc->p_cwdi->cwdi_rdir) { /* * fake a root entry @@ -252,6 +249,7 @@ else *retval = count; out: + mountlist_iterator_destroy(iter); free(sbuf, M_TEMP); return error; } diff -r ff3f89481f2e -r 28fea04e7b15 sys/compat/ndis/subr_ndis.c --- a/sys/compat/ndis/subr_ndis.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/compat/ndis/subr_ndis.c Thu Mar 30 11:17:57 2017 +0200 @@ -3042,6 +3042,8 @@ char *path; linker_file_t head, lf; void *kldstart, *kldend; + mount_iterator_t *iter; + struct mount *mp; ndis_unicode_to_ascii(filename->us_buf, filename->us_len, &afilename); @@ -3094,7 +3096,11 @@ return; } - if (TAILQ_EMPTY(&mountlist)) { + mountlist_iterator_init(&iter); + if ((mp = mountlist_iterator_next(iter, 0)) != NULL) + vfs_unbusy(mp, false); + mountlist_iterator_destroy(iter); + if (mp == NULL) { ExFreePool(fh); *status = NDIS_STATUS_FILE_NOT_FOUND; printf("NDIS: could not find file %s in linker list\n", diff -r ff3f89481f2e -r 28fea04e7b15 sys/compat/netbsd32/netbsd32_compat_20.c --- a/sys/compat/netbsd32/netbsd32_compat_20.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/compat/netbsd32/netbsd32_compat_20.c Thu Mar 30 11:17:57 2017 +0200 @@ -85,7 +85,8 @@ } */ int root = 0; struct proc *p = l->l_proc; - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; struct statvfs *sb; struct netbsd32_statfs sb32; void *sfsp; @@ -95,16 +96,13 @@ sb = STATVFSBUF_GET(); maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd32_statfs); sfsp = SCARG_P32(uap, buf); - mutex_enter(&mountlist_lock); + mountlist_iterator_init(&iter); count = 0; - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0); if (error) { - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); error = 0; continue; } @@ -118,9 +116,8 @@ root |= strcmp(sb->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); if (root == 0 && p->p_cwdi->cwdi_rdir) { /* @@ -144,6 +141,7 @@ else *retval = count; out: + mountlist_iterator_destroy(iter); STATVFSBUF_PUT(sb); return error; } diff -r ff3f89481f2e -r 28fea04e7b15 sys/compat/osf1/osf1_mount.c --- a/sys/compat/osf1/osf1_mount.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/compat/osf1/osf1_mount.c Thu Mar 30 11:17:57 2017 +0200 @@ -132,7 +132,8 @@ int osf1_sys_getfsstat(struct lwp *l, const struct osf1_sys_getfsstat_args *uap, register_t *retval) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; struct statvfs *sp; struct osf1_statfs osfs; char *osf_sfsp; @@ -143,13 +144,9 @@ maxcount = SCARG(uap, bufsize) / sizeof(struct osf1_statfs); osf_sfsp = (void *)SCARG(uap, buf); - mutex_enter(&mountlist_lock); - for (count = 0, mp = TAILQ_FIRST(&mountlist); - mp != NULL; - mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + count = 0; + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (osf_sfsp && count < maxcount) { sp = &mp->mnt_stat; /* @@ -171,9 +168,9 @@ } } count++; - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); if (osf_sfsp && count > maxcount) *retval = maxcount; else diff -r ff3f89481f2e -r 28fea04e7b15 sys/compat/ultrix/ultrix_fs.c --- a/sys/compat/ultrix/ultrix_fs.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/compat/ultrix/ultrix_fs.c Thu Mar 30 11:17:57 2017 +0200 @@ -206,9 +206,10 @@ int ultrix_sys_getmnt(struct lwp *l, const struct ultrix_sys_getmnt_args *uap, register_t *retval) { - struct mount *mp, *nmp; + struct mount *mp; struct statvfs *sp; struct ultrix_fs_data *sfsp; + mount_iterator_t *iter; char *path; int mntflags; int skip; @@ -216,7 +217,6 @@ long count, maxcount; int error; - nmp = NULL; /* XXX keep gcc quiet */ path = NULL; error = 0; maxcount = SCARG(uap, bufsize) / sizeof(struct ultrix_fs_data); @@ -247,20 +247,19 @@ if ((error = copyin((void *)SCARG(uap, start), &start, sizeof(*SCARG(uap, start)))) != 0) goto bad; - mutex_enter(&mountlist_lock); - for (skip = start, mp = TAILQ_FIRST(&mountlist); + mountlist_iterator_init(&iter); + for (skip = start, mp = mountlist_iterator_next(iter, 0); mp != NULL && skip-- > 0; - mp = TAILQ_NEXT(mp, mnt_list)) - continue; - mutex_exit(&mountlist_lock); + mp = mountlist_iterator_next(iter, 0)) { + vfs_unbusy(mp, false); + } + mountlist_iterator_destroy(iter); } - mutex_enter(&mountlist_lock); - for (count = 0, mp = TAILQ_FIRST(&mountlist); - mp != NULL && count < maxcount; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + count = 0; + while (count < maxcount && + (mp = mountlist_iterator_next(iter, 0)) != NULL) { if (sfsp != NULL) { struct ultrix_fs_data tem; sp = &mp->mnt_stat; @@ -288,9 +287,9 @@ count++; } } - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); if (sfsp != NULL && count > maxcount) *retval = maxcount; diff -r ff3f89481f2e -r 28fea04e7b15 sys/gdbscripts/vchain --- a/sys/gdbscripts/vchain Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/gdbscripts/vchain Thu Mar 30 11:17:57 2017 +0200 @@ -53,14 +53,18 @@ end define mountdump - set $mp=mountlist.tqh_first - while ($mp) - printf "%s on %s type %s, (mp 0x%x, privdata 0x%x)\n", \ - $mp->mnt_stat->f_mntfromname, $mp->mnt_stat->f_mntonname, \ - $mp->mnt_op->vfs_name, $mp, $mp->mnt_data - set $mp=$mp->mnt_list.tqe_next - if ((const void *)$mp == (const void *)&mountlist) - set $mp = 0 + set $me=mount_list.tqh_first + while ($me) + if ($me->me_type == ME_MOUNT) + set $mp = $me->me_mount + printf "%s on %s type %s, (mp 0x%x, privdata 0x%x)\n", \ + $mp->mnt_stat->f_mntfromname, \ + $mp->mnt_stat->f_mntonname, \ + $mp->mnt_op->vfs_name, $mp, $mp->mnt_data + end + set $me=$me->me_list.tqe_next + if ((const void *)$me == (const void *)&mount_list) + set $me = 0 end end end diff -r ff3f89481f2e -r 28fea04e7b15 sys/kern/kern_veriexec.c --- a/sys/kern/kern_veriexec.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/kern/kern_veriexec.c Thu Mar 30 11:17:57 2017 +0200 @@ -1363,20 +1363,17 @@ int veriexec_dump(struct lwp *l, prop_array_t rarray) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - /* If it fails, the file-system is [being] unmounted. */ - if (vfs_busy(mp, &nmp) != 0) - continue; - + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { fileassoc_table_run(mp, veriexec_hook, (fileassoc_cb_t)veriexec_file_dump, rarray); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return (0); } @@ -1384,24 +1381,21 @@ int veriexec_flush(struct lwp *l) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; int error = 0; - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { int lerror; - /* If it fails, the file-system is [being] unmounted. */ - if (vfs_busy(mp, &nmp) != 0) - continue; - lerror = veriexec_table_delete(l, mp); if (lerror && lerror != ENOENT) error = lerror; - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return (error); } diff -r ff3f89481f2e -r 28fea04e7b15 sys/kern/vfs_mount.c --- a/sys/kern/vfs_mount.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/kern/vfs_mount.c Thu Mar 30 11:17:57 2017 +0200 @@ -236,11 +236,9 @@ ++xxxfs_mntid; tfsid.__fsid_val[0] = makedev(mtype & 0xff, xxxfs_mntid); tfsid.__fsid_val[1] = mtype; - if (!TAILQ_EMPTY(&mountlist)) { - while (vfs_getvfs(&tfsid)) { - tfsid.__fsid_val[0]++; - xxxfs_mntid++; - } + while (vfs_getvfs(&tfsid)) { + tfsid.__fsid_val[0]++; + xxxfs_mntid++; } mp->mnt_stat.f_fsidx.__fsid_val[0] = tfsid.__fsid_val[0]; mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0]; @@ -255,17 +253,20 @@ struct mount * vfs_getvfs(fsid_t *fsid) { + mount_iterator_t *iter; struct mount *mp; - mutex_enter(&mountlist_lock); - TAILQ_FOREACH(mp, &mountlist, mnt_list) { + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (mp->mnt_stat.f_fsidx.__fsid_val[0] == fsid->__fsid_val[0] && mp->mnt_stat.f_fsidx.__fsid_val[1] == fsid->__fsid_val[1]) { - mutex_exit(&mountlist_lock); - return (mp); + vfs_unbusy(mp, false); + mountlist_iterator_destroy(iter); + return mp; } + vfs_unbusy(mp, false); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return NULL; } @@ -834,6 +835,7 @@ int dounmount(struct mount *mp, int flags, struct lwp *l) { + mount_iterator_t *iter; struct mount *cmp; vnode_t *coveredvp; int error, async, used_syncer, used_extattr; @@ -847,14 +849,16 @@ /* * No unmount below layered mounts. */ - mutex_enter(&mountlist_lock); - TAILQ_FOREACH(cmp, &mountlist, mnt_list) { + mountlist_iterator_init(&iter); + while ((cmp = mountlist_iterator_next(iter, 0)) != NULL) { if (cmp->mnt_lower == mp) { - mutex_exit(&mountlist_lock); + vfs_unbusy(cmp, false); + mountlist_iterator_destroy(iter); return EBUSY; } + vfs_unbusy(cmp, false); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); /* * XXX Freeze syncer. Must do this before locking the @@ -988,16 +992,23 @@ bool vfs_unmount_forceone(struct lwp *l) { + mount_iterator_t *iter; struct mount *mp, *nmp; int error; nmp = NULL; - TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) { + mountlist_iterator_init_reverse(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (nmp == NULL || mp->mnt_gen > nmp->mnt_gen) { + vfs_unbusy(mp, true, NULL); + if (nmp) + vfs_destroy(nmp); nmp = mp; - } + } else + vfs_unbusy(mp, false, NULL); } + mountlist_iterator_destroy(iter); if (nmp == NULL) { return false; } @@ -1006,7 +1017,6 @@ printf("forcefully unmounting %s (%s)...\n", nmp->mnt_stat.f_mntonname, nmp->mnt_stat.f_mntfromname); #endif - atomic_inc_uint(&nmp->mnt_refcnt); if ((error = dounmount(nmp, MNT_FORCE, l)) == 0) { vfs_unmount_print(nmp, "forcefully "); return true; @@ -1025,17 +1035,19 @@ bool vfs_unmountall1(struct lwp *l, bool force, bool verbose) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; bool any_error = false, progress = false; int error; - TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) { + mountlist_iterator_init_reverse(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { #ifdef DEBUG printf("unmounting %p %s (%s)...\n", (void *)mp, mp->mnt_stat.f_mntonname, mp->mnt_stat.f_mntfromname); #endif - atomic_inc_uint(&mp->mnt_refcnt); + vfs_unbusy(mp, true, NULL); if ((error = dounmount(mp, force ? MNT_FORCE : 0, l)) == 0) { vfs_unmount_print(mp, ""); progress = true; @@ -1048,6 +1060,7 @@ any_error = true; } } + mountlist_iterator_destroy(iter); if (verbose) { printf("unmounting done\n"); } @@ -1231,10 +1244,16 @@ vrele(rootvp); } if (error == 0) { + mount_iterator_t *iter; struct mount *mp; extern struct cwdinfo cwdi0; - mp = TAILQ_FIRST(&mountlist); + mountlist_iterator_init(&iter); + mp = mountlist_iterator_next(iter, 0); + KASSERT(mp != NULL); + vfs_unbusy(mp, false, NULL); + mountlist_iterator_destroy(iter); + mp->mnt_flag |= MNT_ROOTFS; mp->mnt_op->vfs_refcount++; error = fstrans_mount(mp); diff -r ff3f89481f2e -r 28fea04e7b15 sys/kern/vfs_subr.c --- a/sys/kern/vfs_subr.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/kern/vfs_subr.c Thu Mar 30 11:17:57 2017 +0200 @@ -759,9 +759,10 @@ void sched_sync(void *arg) { + mount_iterator_t *iter; synclist_t *slp; struct vnode *vp; - struct mount *mp, *nmp; + struct mount *mp; time_t starttime; bool synced; @@ -773,23 +774,21 @@ /* * Sync mounts whose dirty time has expired. */ - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, MNT_NOWAIT)) != NULL) { if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0 || mp->mnt_synclist_slot != syncer_delayno) { - nmp = TAILQ_NEXT(mp, mnt_list); + vfs_unbusy(mp, false, NULL); continue; } mp->mnt_synclist_slot = sync_delay_slot(sync_delay(mp)); - if (vfs_busy(mp, &nmp)) - continue; if (fstrans_start_nowait(mp, FSTRANS_SHARED) == 0) { VFS_SYNC(mp, MNT_LAZY, curlwp->l_cred); fstrans_done(mp); } - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); mutex_enter(&syncer_data_lock); @@ -967,8 +966,9 @@ { char *where = oldp; size_t *sizep = oldlenp; - struct mount *mp, *nmp; + struct mount *mp; vnode_t *vp, vbuf; + mount_iterator_t *iter; struct vnode_iterator *marker; char *bp = where; char *ewhere; @@ -988,17 +988,15 @@ ewhere = where + *sizep; sysctl_unlock(); - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { vfs_vnode_iterator_init(mp, &marker); while ((vp = vfs_vnode_iterator_next(marker, NULL, NULL))) { if (bp + VPTRSZ + VNODESZ > ewhere) { vrele(vp); vfs_vnode_iterator_destroy(marker); vfs_unbusy(mp, false, NULL); + mountlist_iterator_destroy(iter); sysctl_relock(); *sizep = bp - where; return (ENOMEM); @@ -1009,6 +1007,7 @@ vrele(vp); vfs_vnode_iterator_destroy(marker); vfs_unbusy(mp, false, NULL); + mountlist_iterator_destroy(iter); sysctl_relock(); return (error); } @@ -1016,9 +1015,9 @@ bp += VPTRSZ + VNODESZ; } vfs_vnode_iterator_destroy(marker); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); sysctl_relock(); *sizep = bp - where; @@ -1549,7 +1548,7 @@ struct mount *mp; vnode_impl_t *vip; - TAILQ_FOREACH(mp, &mountlist, mnt_list) { + for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { if (&vip->vi_lock != vlock) continue; @@ -1656,25 +1655,19 @@ void printlockedvnodes(void) { - struct mount *mp, *nmp; + struct mount *mp; vnode_t *vp; vnode_impl_t *vip; printf("Locked vnodes\n"); - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { vp = VIMPL_TO_VNODE(vip); if (VOP_ISLOCKED(vp)) vprint(NULL, vp); } - mutex_enter(&mountlist_lock); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); } #endif /* DDB || DEBUGPRINT */ diff -r ff3f89481f2e -r 28fea04e7b15 sys/kern/vfs_syscalls.c --- a/sys/kern/vfs_syscalls.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/kern/vfs_syscalls.c Thu Mar 30 11:17:57 2017 +0200 @@ -641,14 +641,12 @@ void do_sys_sync(struct lwp *l) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; int asyncflag; - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { fstrans_start(mp, FSTRANS_SHARED); mutex_enter(&mp->mnt_updating); if ((mp->mnt_flag & MNT_RDONLY) == 0) { @@ -660,9 +658,9 @@ } mutex_exit(&mp->mnt_updating); fstrans_done(mp); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); #ifdef DEBUG if (syncprt) vfs_bufstats(); @@ -1251,24 +1249,22 @@ register_t *retval) { int root = 0; + mount_iterator_t *iter; struct proc *p = l->l_proc; - struct mount *mp, *nmp; + struct mount *mp; struct statvfs *sb; size_t count, maxcount; int error = 0; sb = STATVFSBUF_GET(); maxcount = bufsize / entry_sz; - mutex_enter(&mountlist_lock); count = 0; - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - continue; - } + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sb, l, flags, 0); if (error) { - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); error = 0; continue; } @@ -1281,9 +1277,8 @@ root |= strcmp(sb->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); if (root == 0 && p->p_cwdi->cwdi_rdir) { /* @@ -1305,6 +1300,7 @@ else *retval = count; out: + mountlist_iterator_destroy(iter); STATVFSBUF_PUT(sb); return error; } diff -r ff3f89481f2e -r 28fea04e7b15 sys/kern/vfs_trans.c --- a/sys/kern/vfs_trans.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/kern/vfs_trans.c Thu Mar 30 11:17:57 2017 +0200 @@ -871,7 +871,7 @@ fstrans_print_lwp(p, l, full == 1); printf("Fstrans state by mount:\n"); - TAILQ_FOREACH(mp, &mountlist, mnt_list) + for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) fstrans_print_mount(mp, full == 1); } #endif /* defined(DDB) */ diff -r ff3f89481f2e -r 28fea04e7b15 sys/miscfs/procfs/procfs_linux.c --- a/sys/miscfs/procfs/procfs_linux.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/miscfs/procfs/procfs_linux.c Thu Mar 30 11:17:57 2017 +0200 @@ -603,26 +603,24 @@ { char *bf, *mtab = NULL; size_t mtabsz = 0; - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; int error = 0, root = 0; struct cwdinfo *cwdi = curl->l_proc->p_cwdi; bf = malloc(LBFSZ, M_TEMP, M_WAITOK); - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { struct statvfs sfs; - if (vfs_busy(mp, &nmp)) - continue; - if ((error = dostatvfs(mp, &sfs, curl, MNT_WAIT, 0)) == 0) root |= procfs_format_sfs(&mtab, &mtabsz, bf, LBFSZ, &sfs, curl, 0); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); /* * If we are inside a chroot that is not itself a mount point, diff -r ff3f89481f2e -r 28fea04e7b15 sys/ufs/lfs/lfs_bio.c --- a/sys/ufs/lfs/lfs_bio.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/ufs/lfs/lfs_bio.c Thu Mar 30 11:17:57 2017 +0200 @@ -514,7 +514,8 @@ lfs_flush(struct lfs *fs, int flags, int only_onefs) { extern u_int64_t locked_fakequeue_count; - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; struct lfs *tfs; KASSERT(mutex_owned(&lfs_lock)); @@ -543,12 +544,8 @@ vfs_unbusy(fs->lfs_ivnode->v_mount, false, NULL); } else { locked_fakequeue_count = 0; - mutex_enter(&mountlist_lock); - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - DLOG((DLOG_FLUSH, "lfs_flush: fs vfs_busy\n")); - continue; - } + mountlist_iterator_init(&iter); + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { if (strncmp(&mp->mnt_stat.f_fstypename[0], MOUNT_LFS, sizeof(mp->mnt_stat.f_fstypename)) == 0) { tfs = VFSTOULFS(mp)->um_lfs; @@ -556,9 +553,9 @@ lfs_flush_fs(tfs, flags); mutex_exit(&lfs_lock); } - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); } LFS_DEBUG_COUNTLOCKED("flush"); wakeup(&lfs_subsys_pages); diff -r ff3f89481f2e -r 28fea04e7b15 sys/ufs/lfs/lfs_vfsops.c --- a/sys/ufs/lfs/lfs_vfsops.c Thu Mar 30 11:17:56 2017 +0200 +++ b/sys/ufs/lfs/lfs_vfsops.c Thu Mar 30 11:17:57 2017 +0200 @@ -386,11 +386,11 @@ static void lfs_writerd(void *arg) { - struct mount *mp, *nmp; + mount_iterator_t *iter; + struct mount *mp; struct lfs *fs; struct vfsops *vfs = NULL; int fsflags; - int skipc; int lfsc; int wrote_something = 0; @@ -447,14 +447,9 @@ * Look through the list of LFSs to see if any of them * have requested pageouts. */ - mutex_enter(&mountlist_lock); + mountlist_iterator_init(&iter); lfsc = 0; - skipc = 0; - for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { - if (vfs_busy(mp, &nmp)) { - ++skipc; - continue; - } + while ((mp = mountlist_iterator_next(iter, 0)) != NULL) { KASSERT(!mutex_owned(&lfs_lock)); if (strncmp(mp->mnt_stat.f_fstypename, MOUNT_LFS, sizeof(mp->mnt_stat.f_fstypename)) == 0) { @@ -469,7 +464,7 @@ if (lfs_sb_getnextseg(fs) < lfs_sb_getcurseg(fs) && fs->lfs_nowrap) { /* Don't try to write if we're suspended */ mutex_exit(&lfs_lock); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); continue; } if (LFS_STARVED_FOR_SEGS(fs)) { @@ -477,7 +472,7 @@ DLOG((DLOG_FLUSH, "lfs_writerd: need cleaning before writing possible\n")); lfs_wakeup_cleaner(fs); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); continue; } @@ -504,22 +499,21 @@ mutex_exit(&lfs_lock); } KASSERT(!mutex_owned(&lfs_lock)); - vfs_unbusy(mp, false, &nmp); + vfs_unbusy(mp, false, NULL); } - if (lfsc + skipc == 0) { + if (lfsc == 0) { mutex_enter(&lfs_lock); lfs_writer_daemon = 0; lfs_writer_lid = 0; mutex_exit(&lfs_lock); - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); break; } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); mutex_enter(&lfs_lock); } KASSERT(!mutex_owned(&lfs_lock)); - KASSERT(!mutex_owned(&mountlist_lock)); /* Give up our extra reference so the module can be unloaded. */ mutex_enter(&vfs_list_lock);