diff options
-rw-r--r-- | libdiskfs/priv.h | 42 |
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 |