diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2020-09-15 22:13:21 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2020-09-15 22:13:21 +0000 |
commit | 4601f5f5ee10e6ea093c6c7289a7157ed527d9d8 (patch) | |
tree | 2a751a5186374a1bebf8de7e773fef7031b8d833 | |
parent | 3c484f325e60e961c476dfb6ebd992290667d6dd (diff) |
Notes
-rw-r--r-- | sys/fs/tmpfs/tmpfs.h | 3 | ||||
-rw-r--r-- | sys/fs/tmpfs/tmpfs_subr.c | 35 | ||||
-rw-r--r-- | sys/fs/tmpfs/tmpfs_vnops.c | 2 |
3 files changed, 18 insertions, 22 deletions
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index b15a83af7eba9..ac8fe0c1c2d66 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -228,7 +228,7 @@ struct tmpfs_node { int tn_vpstate; /* (i) */ /* Transient refcounter on this node. */ - u_int tn_refcount; /* (m) + (i) */ + u_int tn_refcount; /* 0<->1 (m) + (i) */ /* misc data field for different tn_type node */ union { @@ -412,7 +412,6 @@ struct tmpfs_dir_cursor { */ void tmpfs_ref_node(struct tmpfs_node *node); -void tmpfs_ref_node_locked(struct tmpfs_node *node); int tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *, enum vtype, uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *, const char *, dev_t, struct tmpfs_node **); diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 7d5d719001486..d9844bc3c7c9b 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/priv.h> #include <sys/proc.h> #include <sys/random.h> +#include <sys/refcount.h> #include <sys/rwlock.h> #include <sys/stat.h> #include <sys/sysctl.h> @@ -211,21 +212,15 @@ tmpfs_pages_check_avail(struct tmpfs_mount *tmp, size_t req_pages) void tmpfs_ref_node(struct tmpfs_node *node) { +#ifdef INVARIANTS + u_int old; - TMPFS_NODE_LOCK(node); - tmpfs_ref_node_locked(node); - TMPFS_NODE_UNLOCK(node); -} - -void -tmpfs_ref_node_locked(struct tmpfs_node *node) -{ - - TMPFS_NODE_ASSERT_LOCKED(node); - KASSERT(node->tn_refcount > 0, ("node %p zero refcount", node)); - KASSERT(node->tn_refcount < UINT_MAX, ("node %p refcount %u", node, - node->tn_refcount)); - node->tn_refcount++; + old = +#endif + refcount_acquire(&node->tn_refcount); +#ifdef INVARIANTS + KASSERT(old > 0, ("node %p zero refcount", node)); +#endif } /* @@ -370,6 +365,8 @@ tmpfs_alloc_node(struct mount *mp, struct tmpfs_mount *tmp, enum vtype type, void tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node) { + if (refcount_release_if_not_last(&node->tn_refcount)) + return; TMPFS_LOCK(tmp); TMPFS_NODE_LOCK(node); @@ -384,19 +381,19 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, bool detach) { vm_object_t uobj; + bool last; TMPFS_MP_ASSERT_LOCKED(tmp); TMPFS_NODE_ASSERT_LOCKED(node); - KASSERT(node->tn_refcount > 0, ("node %p refcount zero", node)); - node->tn_refcount--; - if (node->tn_attached && (detach || node->tn_refcount == 0)) { + last = refcount_release(&node->tn_refcount); + if (node->tn_attached && (detach || last)) { MPASS(tmp->tm_nodes_inuse > 0); tmp->tm_nodes_inuse--; LIST_REMOVE(node, tn_entries); node->tn_attached = false; } - if (node->tn_refcount > 0) + if (!last) return (false); #ifdef INVARIANTS @@ -596,7 +593,7 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag, error = 0; tm = VFS_TO_TMPFS(mp); TMPFS_NODE_LOCK(node); - tmpfs_ref_node_locked(node); + tmpfs_ref_node(node); loop: TMPFS_NODE_ASSERT_LOCKED(node); if ((vp = node->tn_vnode) != NULL) { diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 61dd148c73051..c5d0702801e95 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -1663,7 +1663,7 @@ restart: if (tnp->tn_type != VDIR) continue; TMPFS_NODE_LOCK(tnp); - tmpfs_ref_node_locked(tnp); + tmpfs_ref_node(tnp); /* * tn_vnode cannot be instantiated while we hold the |