Module Name: src Committed By: hannken Date: Mon Apr 17 08:34:27 UTC 2017
Modified Files: src/sys/kern: vfs_mount.c vfs_subr.c src/sys/sys: mount.h Log Message: Add vfs_trybusy() and mountlist_iterator_trynext() and use it for the syncer. To generate a diff of this commit: cvs rdiff -u -r1.57 -r1.58 src/sys/kern/vfs_mount.c cvs rdiff -u -r1.462 -r1.463 src/sys/kern/vfs_subr.c cvs rdiff -u -r1.225 -r1.226 src/sys/sys/mount.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_mount.c diff -u src/sys/kern/vfs_mount.c:1.57 src/sys/kern/vfs_mount.c:1.58 --- src/sys/kern/vfs_mount.c:1.57 Mon Apr 17 08:32:55 2017 +++ src/sys/kern/vfs_mount.c Mon Apr 17 08:34:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_mount.c,v 1.57 2017/04/17 08:32:55 hannken Exp $ */ +/* $NetBSD: vfs_mount.c,v 1.58 2017/04/17 08:34:27 hannken Exp $ */ /*- * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.57 2017/04/17 08:32:55 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.58 2017/04/17 08:34:27 hannken Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -311,13 +311,17 @@ vfs_rele(struct mount *mp) * => The caller must hold a pre-existing reference to the mount. * => Will fail if the file system is being unmounted, or is unmounted. */ -int -vfs_busy(struct mount *mp) +static inline int +_vfs_busy(struct mount *mp, bool wait) { KASSERT(mp->mnt_refcnt > 0); - mutex_enter(&mp->mnt_unmounting); + if (wait) { + mutex_enter(&mp->mnt_unmounting); + } else if (!mutex_tryenter(&mp->mnt_unmounting)) { + return EBUSY; + } if (__predict_false((mp->mnt_iflag & IMNT_GONE) != 0)) { mutex_exit(&mp->mnt_unmounting); return ENOENT; @@ -329,6 +333,20 @@ vfs_busy(struct mount *mp) return 0; } +int +vfs_busy(struct mount *mp) +{ + + return _vfs_busy(mp, true); +} + +int +vfs_trybusy(struct mount *mp) +{ + + return _vfs_busy(mp, false); +} + /* * Unbusy a busy filesystem. * @@ -1524,11 +1542,12 @@ mountlist_iterator_destroy(mount_iterato * Return the next mount or NULL for this iterator. * Mark it busy on success. */ -struct mount * -mountlist_iterator_next(mount_iterator_t *mi) +static inline struct mount * +_mountlist_iterator_next(mount_iterator_t *mi, bool wait) { struct mountlist_entry *me, *marker = &mi->mi_entry; struct mount *mp; + int error; if (marker->me_mount != NULL) { vfs_unbusy(marker->me_mount); @@ -1559,7 +1578,11 @@ mountlist_iterator_next(mount_iterator_t mutex_exit(&mountlist_lock); /* Try to mark this mount busy and return on success. */ - if (vfs_busy(mp) == 0) { + if (wait) + error = vfs_busy(mp); + else + error = vfs_trybusy(mp); + if (error == 0) { vfs_rele(mp); marker->me_mount = mp; return mp; @@ -1569,6 +1592,20 @@ mountlist_iterator_next(mount_iterator_t } } +struct mount * +mountlist_iterator_next(mount_iterator_t *mi) +{ + + return _mountlist_iterator_next(mi, true); +} + +struct mount * +mountlist_iterator_trynext(mount_iterator_t *mi) +{ + + return _mountlist_iterator_next(mi, false); +} + /* * Attach new mount to the end of the mount list. */ Index: src/sys/kern/vfs_subr.c diff -u src/sys/kern/vfs_subr.c:1.462 src/sys/kern/vfs_subr.c:1.463 --- src/sys/kern/vfs_subr.c:1.462 Wed Apr 12 10:26:33 2017 +++ src/sys/kern/vfs_subr.c Mon Apr 17 08:34:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_subr.c,v 1.462 2017/04/12 10:26:33 hannken Exp $ */ +/* $NetBSD: vfs_subr.c,v 1.463 2017/04/17 08:34:27 hannken Exp $ */ /*- * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.462 2017/04/12 10:26:33 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.463 2017/04/17 08:34:27 hannken Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -775,7 +775,7 @@ sched_sync(void *arg) * Sync mounts whose dirty time has expired. */ mountlist_iterator_init(&iter); - while ((mp = mountlist_iterator_next(iter)) != NULL) { + while ((mp = mountlist_iterator_trynext(iter)) != NULL) { if ((mp->mnt_iflag & IMNT_ONWORKLIST) == 0 || mp->mnt_synclist_slot != syncer_delayno) { continue; Index: src/sys/sys/mount.h diff -u src/sys/sys/mount.h:1.225 src/sys/sys/mount.h:1.226 --- src/sys/sys/mount.h:1.225 Mon Apr 17 08:32:01 2017 +++ src/sys/sys/mount.h Mon Apr 17 08:34:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mount.h,v 1.225 2017/04/17 08:32:01 hannken Exp $ */ +/* $NetBSD: mount.h,v 1.226 2017/04/17 08:34:27 hannken Exp $ */ /* * Copyright (c) 1989, 1991, 1993 @@ -417,6 +417,7 @@ bool vfs_unmountall(struct lwp *); / bool vfs_unmountall1(struct lwp *, bool, bool); bool vfs_unmount_forceone(struct lwp *); int vfs_busy(struct mount *); +int vfs_trybusy(struct mount *); int vfs_rootmountalloc(const char *, const char *, struct mount **); void vfs_unbusy(struct mount *); int vfs_attach(struct vfsops *); @@ -496,6 +497,7 @@ typedef struct mount_iterator mount_iter void mountlist_iterator_init(mount_iterator_t **); void mountlist_iterator_destroy(mount_iterator_t *); struct mount *mountlist_iterator_next(mount_iterator_t *); +struct mount *mountlist_iterator_trynext(mount_iterator_t *); struct mount *_mountlist_next(struct mount *); void mountlist_append(struct mount *); void mountlist_remove(struct mount *);