Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/udf Use vfs_vnode_iterator for udf_do_sync.
details: https://anonhg.NetBSD.org/src/rev/250576a34d41
branches: trunk
changeset: 340132:250576a34d41
user: hannken <hannken%NetBSD.org@localhost>
date: Mon Aug 24 08:31:56 2015 +0000
description:
Use vfs_vnode_iterator for udf_do_sync.
- Build rb_tree to get an ordered list of nodes, sync them and
clean the tree.
- Stop abusing mntvnode_lock to serialize udf_do_sync, use new
mutex ump->sync_lock instead.
diffstat:
sys/fs/udf/udf.h | 4 +-
sys/fs/udf/udf_subr.c | 142 ++++++++++++++++++++---------------------------
sys/fs/udf/udf_vfsops.c | 8 +-
3 files changed, 66 insertions(+), 88 deletions(-)
diffs (truncated from 312 to 300 lines):
diff -r 545b2bccfa6a -r 250576a34d41 sys/fs/udf/udf.h
--- a/sys/fs/udf/udf.h Mon Aug 24 08:30:52 2015 +0000
+++ b/sys/fs/udf/udf.h Mon Aug 24 08:31:56 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf.h,v 1.49 2015/08/24 08:30:17 hannken Exp $ */
+/* $NetBSD: udf.h,v 1.50 2015/08/24 08:31:56 hannken Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -339,11 +339,11 @@
uint8_t metadata_flags;
/* rb tree for lookup icb to udf_node and sorted list for sync */
- kmutex_t ihash_lock;
struct rb_tree udf_node_tree;
/* syncing */
int syncing; /* are we syncing? */
+ kmutex_t sync_lock; /* serialize syncing */
/* late allocation */
int32_t uncommitted_lbs[UDF_PARTITIONS];
diff -r 545b2bccfa6a -r 250576a34d41 sys/fs/udf/udf_subr.c
--- a/sys/fs/udf/udf_subr.c Mon Aug 24 08:30:52 2015 +0000
+++ b/sys/fs/udf/udf_subr.c Mon Aug 24 08:31:56 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_subr.c,v 1.131 2015/08/24 08:30:17 hannken Exp $ */
+/* $NetBSD: udf_subr.c,v 1.132 2015/08/24 08:31:56 hannken Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.131 2015/08/24 08:30:17 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.132 2015/08/24 08:31:56 hannken Exp $");
#endif /* not lint */
@@ -3444,29 +3444,6 @@
}
-static void
-udf_register_node(struct udf_node *udf_node)
-{
- struct udf_mount *ump = udf_node->ump;
-
- /* add node to the rb tree */
- mutex_enter(&ump->ihash_lock);
- rb_tree_insert_node(&ump->udf_node_tree, udf_node);
- mutex_exit(&ump->ihash_lock);
-}
-
-
-static void
-udf_deregister_node(struct udf_node *udf_node)
-{
- struct udf_mount *ump = udf_node->ump;
-
- /* remove node from the rb tree */
- mutex_enter(&ump->ihash_lock);
- rb_tree_remove_node(&ump->udf_node_tree, udf_node);
- mutex_exit(&ump->ihash_lock);
-}
-
/* --------------------------------------------------------------------- */
static int
@@ -5310,9 +5287,6 @@
sizeof(struct long_ad)) == 0)
vp->v_vflag |= VV_ROOT;
- /* insert into the hash lookup */
- udf_register_node(udf_node);
-
icb_loc = node_icb_loc;
needs_indirect = 0;
strat4096 = 0;
@@ -5681,16 +5655,15 @@
/* remove dirhash if present */
dirhash_purge(&udf_node->dir_hash);
- /* remove from our hash lookup table */
- udf_deregister_node(udf_node);
-
/* destroy our lock */
mutex_destroy(&udf_node->node_mutex);
cv_destroy(&udf_node->node_lock);
/* dissociate our udf_node from the vnode */
genfs_node_destroy(udf_node->vnode);
+ mutex_enter(vp->v_interlock);
vp->v_data = NULL;
+ mutex_exit(vp->v_interlock);
/* free associated memory and the node itself */
for (extnr = 0; extnr < udf_node->num_extensions; extnr++) {
@@ -5828,9 +5801,6 @@
/* initialise genfs */
genfs_node_init(vp, &udf_genfsops);
- /* insert into the hash lookup */
- udf_register_node(udf_node);
-
/* get parent's unique ID for refering '..' if its a directory */
if (dir_node->fe) {
parent_unique_id = udf_rw64(dir_node->fe->unique_id);
@@ -6316,64 +6286,27 @@
/* --------------------------------------------------------------------- */
static void
-udf_sync_pass(struct udf_mount *ump, kauth_cred_t cred, int waitfor,
- int pass, int *ndirty)
+udf_sync_pass(struct udf_mount *ump, kauth_cred_t cred, int pass, int *ndirty)
{
struct udf_node *udf_node, *n_udf_node;
struct vnode *vp;
int vdirty, error;
- int on_type, on_flags, on_vnode;
-
-derailed:
- KASSERT(mutex_owned(&mntvnode_lock));
+
+ KASSERT(mutex_owned(&ump->sync_lock));
DPRINTF(SYNC, ("sync_pass %d\n", pass));
udf_node = RB_TREE_MIN(&ump->udf_node_tree);
for (;udf_node; udf_node = n_udf_node) {
DPRINTF(SYNC, ("."));
- udf_node->i_flags &= ~IN_SYNCED;
vp = udf_node->vnode;
- mutex_enter(vp->v_interlock);
n_udf_node = rb_tree_iterate(&ump->udf_node_tree,
udf_node, RB_DIR_RIGHT);
- if (n_udf_node)
- n_udf_node->i_flags |= IN_SYNCED;
-
- /* system nodes are not synced this way */
- if (vp->v_vflag & VV_SYSTEM) {
- mutex_exit(vp->v_interlock);
- continue;
- }
-
- /* check if its dirty enough to even try */
- on_type = (waitfor == MNT_LAZY || vp->v_type == VNON);
- on_flags = ((udf_node->i_flags &
- (IN_ACCESSED | IN_UPDATE | IN_MODIFIED)) == 0);
- on_vnode = LIST_EMPTY(&vp->v_dirtyblkhd)
- && UVM_OBJ_IS_CLEAN(&vp->v_uobj);
- if (on_type || (on_flags || on_vnode)) { /* XXX */
- /* not dirty (enough?) */
- mutex_exit(vp->v_interlock);
- continue;
- }
-
- mutex_exit(&mntvnode_lock);
- error = vget(vp, LK_NOWAIT, false /* !wait */);
- if (error) {
- mutex_enter(&mntvnode_lock);
- if (error == ENOENT)
- goto derailed;
- *ndirty += 1;
- continue;
- }
error = vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT);
if (error) {
KASSERT(error == EBUSY);
- vrele(vp);
- mutex_enter(&mntvnode_lock);
*ndirty += 1;
continue;
}
@@ -6400,34 +6333,69 @@
break;
}
- vput(vp);
- mutex_enter(&mntvnode_lock);
+ VOP_UNLOCK(vp);
}
DPRINTF(SYNC, ("END sync_pass %d\n", pass));
}
+static bool
+udf_sync_selector(void *cl, struct vnode *vp)
+{
+ struct udf_node *udf_node = VTOI(vp);
+
+ if (vp->v_vflag & VV_SYSTEM)
+ return false;
+ if (vp->v_type == VNON)
+ return false;
+ if (udf_node == NULL)
+ return false;
+ if ((udf_node->i_flags & (IN_ACCESSED | IN_UPDATE | IN_MODIFIED)) == 0)
+ return false;
+ if (LIST_EMPTY(&vp->v_dirtyblkhd) && UVM_OBJ_IS_CLEAN(&vp->v_uobj))
+ return false;
+
+ return true;
+}
+
void
udf_do_sync(struct udf_mount *ump, kauth_cred_t cred, int waitfor)
{
+ struct vnode_iterator *marker;
+ struct vnode *vp;
+ struct udf_node *udf_node, *udf_next_node;
int dummy, ndirty;
- mutex_enter(&mntvnode_lock);
-recount:
+ if (waitfor == MNT_LAZY)
+ return;
+
+ mutex_enter(&ump->sync_lock);
+
+ /* Fill the rbtree with nodes to sync. */
+ vfs_vnode_iterator_init(ump->vfs_mountp, &marker);
+ while ((vp = vfs_vnode_iterator_next(marker,
+ udf_sync_selector, NULL)) != NULL) {
+ udf_node = VTOI(vp);
+ udf_node->i_flags |= IN_SYNCED;
+ rb_tree_insert_node(&ump->udf_node_tree, udf_node);
+ }
+ vfs_vnode_iterator_destroy(marker);
+
dummy = 0;
DPRINTF(CALL, ("issue VOP_FSYNC(DATA only) on all nodes\n"));
DPRINTF(SYNC, ("issue VOP_FSYNC(DATA only) on all nodes\n"));
- udf_sync_pass(ump, cred, waitfor, 1, &dummy);
+ udf_sync_pass(ump, cred, 1, &dummy);
DPRINTF(CALL, ("issue VOP_FSYNC(COMPLETE) on all finished nodes\n"));
DPRINTF(SYNC, ("issue VOP_FSYNC(COMPLETE) on all finished nodes\n"));
- udf_sync_pass(ump, cred, waitfor, 2, &dummy);
+ udf_sync_pass(ump, cred, 2, &dummy);
if (waitfor == MNT_WAIT) {
+recount:
ndirty = ump->devvp->v_numoutput;
DPRINTF(SYNC, ("counting pending blocks: on devvp %d\n",
ndirty));
- udf_sync_pass(ump, cred, waitfor, 3, &ndirty);
+ udf_sync_pass(ump, cred, 3, &ndirty);
DPRINTF(SYNC, ("counted num dirty pending blocks %d\n",
ndirty));
@@ -6438,7 +6406,17 @@
}
}
- mutex_exit(&mntvnode_lock);
+ /* Clean the rbtree. */
+ for (udf_node = RB_TREE_MIN(&ump->udf_node_tree);
+ udf_node; udf_node = udf_next_node) {
+ udf_next_node = rb_tree_iterate(&ump->udf_node_tree,
+ udf_node, RB_DIR_RIGHT);
+ rb_tree_remove_node(&ump->udf_node_tree, udf_node);
+ udf_node->i_flags &= ~IN_SYNCED;
+ vrele(udf_node->vnode);
+ }
+
+ mutex_exit(&ump->sync_lock);
}
/* --------------------------------------------------------------------- */
diff -r 545b2bccfa6a -r 250576a34d41 sys/fs/udf/udf_vfsops.c
--- a/sys/fs/udf/udf_vfsops.c Mon Aug 24 08:30:52 2015 +0000
+++ b/sys/fs/udf/udf_vfsops.c Mon Aug 24 08:31:56 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_vfsops.c,v 1.70 2015/08/24 08:30:52 hannken Exp $ */
+/* $NetBSD: udf_vfsops.c,v 1.71 2015/08/24 08:31:56 hannken Exp $ */
/*
* Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.70 2015/08/24 08:30:52 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.71 2015/08/24 08:31:56 hannken Exp $");
#endif /* not lint */
@@ -259,9 +259,9 @@
MPFREE(ump->la_pmapping, M_TEMP);
MPFREE(ump->la_lmapping, M_TEMP);
- mutex_destroy(&ump->ihash_lock);
mutex_destroy(&ump->logvol_mutex);
mutex_destroy(&ump->allocate_mutex);
+ mutex_destroy(&ump->sync_lock);
Home |
Main Index |
Thread Index |
Old Index