Add vfs_trybusy() and mountlist_iterator_trynext() and use it for the syncer.
This commit is contained in:
parent
8c6f10d105
commit
bd152b56b5
@ -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_iterator_t *mi)
|
||||
* 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 *mi)
|
||||
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 *mi)
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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 *); /* unmount file systems */
|
||||
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_iterator_t; /* Opaque. */
|
||||
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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user