ml_iterator_apply Switch from direct mountlist traversal to mountlist iterator. diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/compat/common/vfs_syscalls_20.c --- sys/compat/common/vfs_syscalls_20.c +++ sys/compat/common/vfs_syscalls_20.c @@ -203,7 +203,8 @@ compat_20_sys_getfsstat(struct lwp *l, c 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 @@ compat_20_sys_getfsstat(struct lwp *l, c 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)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sbuf, l, SCARG(uap, flags), 0); if (error) { - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); continue; } error = vfs2fs(sfsp, sbuf); @@ -233,9 +231,8 @@ compat_20_sys_getfsstat(struct lwp *l, c root |= strcmp(sbuf->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); if (root == 0 && l->l_proc->p_cwdi->cwdi_rdir) { /* * fake a root entry @@ -252,6 +249,7 @@ compat_20_sys_getfsstat(struct lwp *l, c else *retval = count; out: + mountlist_iterator_destroy(iter); free(sbuf, M_TEMP); return error; } diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/compat/ndis/subr_ndis.c --- sys/compat/ndis/subr_ndis.c +++ sys/compat/ndis/subr_ndis.c @@ -3042,6 +3042,8 @@ NdisOpenFile(ndis_status *status, ndis_h 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 @@ NdisOpenFile(ndis_status *status, ndis_h return; } - if (TAILQ_EMPTY(&mountlist)) { + mountlist_iterator_init(&iter); + if ((mp = mountlist_iterator_next(iter)) != NULL) + mountlist_iterator_done(iter); + 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 61eb299077d8 -r 2d7dfb96a6d8 sys/compat/netbsd32/netbsd32_compat_20.c --- sys/compat/netbsd32/netbsd32_compat_20.c +++ sys/compat/netbsd32/netbsd32_compat_20.c @@ -85,7 +85,8 @@ compat_20_netbsd32_getfsstat(struct lwp } */ 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 @@ compat_20_netbsd32_getfsstat(struct lwp 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)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sb, l, SCARG(uap, flags), 0); if (error) { - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); error = 0; continue; } @@ -118,9 +116,8 @@ compat_20_netbsd32_getfsstat(struct lwp root |= strcmp(sb->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); if (root == 0 && p->p_cwdi->cwdi_rdir) { /* @@ -144,6 +141,7 @@ compat_20_netbsd32_getfsstat(struct lwp else *retval = count; out: + mountlist_iterator_destroy(iter); STATVFSBUF_PUT(sb); return error; } diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/compat/osf1/osf1_mount.c --- sys/compat/osf1/osf1_mount.c +++ sys/compat/osf1/osf1_mount.c @@ -132,7 +132,8 @@ osf1_sys_fstatfs(struct lwp *l, const st 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 @@ osf1_sys_getfsstat(struct lwp *l, const 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)) != NULL) { if (osf_sfsp && count < maxcount) { sp = &mp->mnt_stat; /* @@ -171,9 +168,9 @@ osf1_sys_getfsstat(struct lwp *l, const } } count++; - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); if (osf_sfsp && count > maxcount) *retval = maxcount; else diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/compat/ultrix/ultrix_fs.c --- sys/compat/ultrix/ultrix_fs.c +++ sys/compat/ultrix/ultrix_fs.c @@ -206,9 +206,10 @@ make_ultrix_mntent(struct statvfs *sp, s 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 @@ ultrix_sys_getmnt(struct lwp *l, const s 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 @@ ultrix_sys_getmnt(struct lwp *l, const s 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); mp != NULL && skip-- > 0; - mp = TAILQ_NEXT(mp, mnt_list)) - continue; - mutex_exit(&mountlist_lock); + mp = mountlist_iterator_next(iter)) { + mountlist_iterator_done(iter); + } + 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)) != NULL) { if (sfsp != NULL) { struct ultrix_fs_data tem; sp = &mp->mnt_stat; @@ -288,9 +287,9 @@ ultrix_sys_getmnt(struct lwp *l, const s count++; } } - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); if (sfsp != NULL && count > maxcount) *retval = maxcount; diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/gdbscripts/vchain --- sys/gdbscripts/vchain +++ sys/gdbscripts/vchain @@ -53,14 +53,18 @@ print vnode chains for all mount points 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 61eb299077d8 -r 2d7dfb96a6d8 sys/kern/kern_veriexec.c --- sys/kern/kern_veriexec.c +++ sys/kern/kern_veriexec.c @@ -1363,20 +1363,17 @@ veriexec_file_dump(struct veriexec_file_ 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)) != NULL) { fileassoc_table_run(mp, veriexec_hook, (fileassoc_cb_t)veriexec_file_dump, rarray); - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return (0); } @@ -1384,24 +1381,21 @@ veriexec_dump(struct lwp *l, prop_array_ 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)) != 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); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return (error); } diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/kern/vfs_mount.c --- sys/kern/vfs_mount.c +++ sys/kern/vfs_mount.c @@ -235,11 +235,9 @@ vfs_getnewfsid(struct mount *mp) ++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]; @@ -254,17 +252,20 @@ vfs_getnewfsid(struct mount *mp) 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)) != 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); + mountlist_iterator_done(iter); + mountlist_iterator_destroy(iter); + return mp; } + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); return NULL; } @@ -833,6 +834,7 @@ err_unmounted: 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; @@ -846,14 +848,16 @@ dounmount(struct mount *mp, int flags, s /* * 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)) != NULL) { if (cmp->mnt_lower == mp) { - mutex_exit(&mountlist_lock); + mountlist_iterator_done(iter); + mountlist_iterator_destroy(iter); return EBUSY; } + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); /* * XXX Freeze syncer. Must do this before locking the @@ -987,16 +991,23 @@ vfs_unmount_print(struct mount *mp, cons 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)) != NULL) { if (nmp == NULL || mp->mnt_gen > nmp->mnt_gen) { + if (nmp) + vfs_destroy(nmp); nmp = mp; + atomic_inc_uint(&nmp->mnt_refcnt); } + mountlist_iterator_done(iter); } + mountlist_iterator_destroy(iter); if (nmp == NULL) { return false; } @@ -1005,7 +1016,6 @@ vfs_unmount_forceone(struct lwp *l) 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; @@ -1024,17 +1034,20 @@ vfs_unmount_forceone(struct lwp *l) 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)) != 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); + mountlist_iterator_done(iter); if ((error = dounmount(mp, force ? MNT_FORCE : 0, l)) == 0) { vfs_unmount_print(mp, ""); progress = true; @@ -1047,6 +1060,7 @@ vfs_unmountall1(struct lwp *l, bool forc any_error = true; } } + mountlist_iterator_destroy(iter); if (verbose) { printf("unmounting done\n"); } @@ -1230,10 +1244,16 @@ done: 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); + KASSERT(mp != NULL); + mountlist_iterator_done(iter); + mountlist_iterator_destroy(iter); + mp->mnt_flag |= MNT_ROOTFS; mp->mnt_op->vfs_refcount++; error = fstrans_mount(mp); diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/kern/vfs_subr.c --- sys/kern/vfs_subr.c +++ sys/kern/vfs_subr.c @@ -759,9 +759,10 @@ lazy_sync_vnode(struct vnode *vp) 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 @@ sched_sync(void *arg) /* * 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)) != NULL) { if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0 || mp->mnt_synclist_slot != syncer_delayno) { - nmp = TAILQ_NEXT(mp, mnt_list); + mountlist_iterator_done(iter); 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); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); mutex_enter(&syncer_data_lock); @@ -967,8 +966,9 @@ sysctl_kern_vnode(SYSCTLFN_ARGS) { 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 @@ sysctl_kern_vnode(SYSCTLFN_ARGS) 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)) != 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 @@ sysctl_kern_vnode(SYSCTLFN_ARGS) vrele(vp); vfs_vnode_iterator_destroy(marker); vfs_unbusy(mp, false, NULL); + mountlist_iterator_destroy(iter); sysctl_relock(); return (error); } @@ -1016,9 +1015,9 @@ sysctl_kern_vnode(SYSCTLFN_ARGS) bp += VPTRSZ + VNODESZ; } vfs_vnode_iterator_destroy(marker); - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); sysctl_relock(); *sizep = bp - where; @@ -1549,7 +1548,7 @@ vfs_vnode_lock_print(void *vlock, int fu 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,18 @@ void printlockedvnodes(void); 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); } - mutex_exit(&mountlist_lock); } #endif /* DDB || DEBUGPRINT */ diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/kern/vfs_syscalls.c --- sys/kern/vfs_syscalls.c +++ sys/kern/vfs_syscalls.c @@ -641,14 +641,12 @@ struct ctldebug debug0 = { "syncprt", &s 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)) != NULL) { fstrans_start(mp, FSTRANS_SHARED); mutex_enter(&mp->mnt_updating); if ((mp->mnt_flag & MNT_RDONLY) == 0) { @@ -660,9 +658,9 @@ do_sys_sync(struct lwp *l) } mutex_exit(&mp->mnt_updating); fstrans_done(mp); - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); #ifdef DEBUG if (syncprt) vfs_bufstats(); @@ -1251,24 +1249,22 @@ do_sys_getvfsstat(struct lwp *l, void *s 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)) != NULL) { if (sfsp && count < maxcount) { error = dostatvfs(mp, sb, l, flags, 0); if (error) { - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); error = 0; continue; } @@ -1281,9 +1277,8 @@ do_sys_getvfsstat(struct lwp *l, void *s root |= strcmp(sb->f_mntonname, "/") == 0; } count++; - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); if (root == 0 && p->p_cwdi->cwdi_rdir) { /* @@ -1305,6 +1300,7 @@ do_sys_getvfsstat(struct lwp *l, void *s else *retval = count; out: + mountlist_iterator_destroy(iter); STATVFSBUF_PUT(sb); return error; } diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/kern/vfs_trans.c --- sys/kern/vfs_trans.c +++ sys/kern/vfs_trans.c @@ -871,7 +871,7 @@ fstrans_dump(int full) 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 61eb299077d8 -r 2d7dfb96a6d8 sys/miscfs/procfs/procfs_linux.c --- sys/miscfs/procfs/procfs_linux.c +++ sys/miscfs/procfs/procfs_linux.c @@ -603,26 +603,24 @@ procfs_domounts(struct lwp *curl, struct { 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)) != 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); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); /* * If we are inside a chroot that is not itself a mount point, diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/ufs/lfs/lfs_bio.c --- sys/ufs/lfs/lfs_bio.c +++ sys/ufs/lfs/lfs_bio.c @@ -514,7 +514,8 @@ void 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 @@ lfs_flush(struct lfs *fs, int flags, int 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)) != 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(struct lfs *fs, int flags, int lfs_flush_fs(tfs, flags); mutex_exit(&lfs_lock); } - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - mutex_exit(&mountlist_lock); + mountlist_iterator_destroy(iter); } LFS_DEBUG_COUNTLOCKED("flush"); wakeup(&lfs_subsys_pages); diff -r 61eb299077d8 -r 2d7dfb96a6d8 sys/ufs/lfs/lfs_vfsops.c --- sys/ufs/lfs/lfs_vfsops.c +++ sys/ufs/lfs/lfs_vfsops.c @@ -387,11 +387,11 @@ struct pool lfs_lbnentry_pool; 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; @@ -446,14 +446,9 @@ lfs_writerd(void *arg) * 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)) != NULL) { KASSERT(!mutex_owned(&lfs_lock)); if (strncmp(mp->mnt_stat.f_fstypename, MOUNT_LFS, sizeof(mp->mnt_stat.f_fstypename)) == 0) { @@ -468,7 +463,7 @@ lfs_writerd(void *arg) 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); + mountlist_iterator_done(iter); continue; } if (LFS_STARVED_FOR_SEGS(fs)) { @@ -476,7 +471,7 @@ lfs_writerd(void *arg) DLOG((DLOG_FLUSH, "lfs_writerd: need cleaning before writing possible\n")); lfs_wakeup_cleaner(fs); - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); continue; } @@ -503,21 +498,20 @@ lfs_writerd(void *arg) mutex_exit(&lfs_lock); } KASSERT(!mutex_owned(&lfs_lock)); - vfs_unbusy(mp, false, &nmp); + mountlist_iterator_done(iter); } - if (lfsc + skipc == 0) { + if (lfsc == 0) { mutex_enter(&lfs_lock); lfs_writer_daemon = NULL; 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);