summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdiskfs/priv.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index 7d88fd28..2e3db6ca 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -17,6 +17,8 @@
extern mach_port_t fs_control_port; /* receive right */
+spin_lock_t _diskfs_node_refcnt_lock = SPIN_LOCK_INITIALIZER;
+
/* Called by MiG to translate ports into struct protid *.
fsmutations.h arranges for this to happen for the io and
fs interfaces. */
@@ -35,6 +37,46 @@ diskfs_end_using_protid_port (struct protid *cred)
ports_done_with_port (cred);
}
+/* Add a reference to a node. */
+extern inline void
+diskfs_nref (struct node *np)
+{
+ spin_lock (&_diskfs_node_refcnt_lock);
+ np->references++;
+ spin_unlock (&_diskfs_node_refcnt_lock);
+}
+
+/* Unlock node NP and release a reference */
+extern inline void
+diskfs_nput (struct node *np)
+{
+ spin_lock (&_diskfs_node_refcnt_lock);
+ np->references--;
+ if (np->references == 0)
+ {
+ diskfs_drop_node (np);
+ spin_unlock (&_diskfs_node_refcnt_lock);
+ }
+ else
+ {
+ spin_unlock (&_diskfs_node_refcnt_lock);
+ mutex_unlock (&np->lock);
+ }
+}
+
+/* Release a reference on NP. If NP is locked by anyone, then this cannot
+ be the last reference (because you must hold a reference in order to
+ hold the lock). */
+extern inline void
+diskfs_nrele (struct node *np)
+{
+ spin_lock (&_diskfs_node_refcnt_lock);
+ np->references--;
+ if (np->references == 0)
+ diskfs_drop_node (np);
+ spin_unlock (&_diskfs_node_refcnt_lock);
+}
+
/* This macro locks the node associated with PROTID, and then
evaluates the expression OPERATION; then it syncs the inode
(without waiting) and unlocks everything, and then returns