+static inline void
+free_inode_if_unneeded(struct wim_inode *inode)
+{
+ if (inode->i_nlink)
+ return;
+#ifdef WITH_FUSE
+ if (inode->i_num_opened_fds)
+ return;
+#endif
+ free_inode(inode);
+}
+
+/* Associate a dentry with the specified inode. */
+void
+d_associate(struct wim_dentry *dentry, struct wim_inode *inode)
+{
+ wimlib_assert(!dentry->d_inode);
+
+ list_add_tail(&dentry->d_alias, &inode->i_dentry);
+ dentry->d_inode = inode;
+ inode->i_nlink++;
+}
+
+/* Disassociate a dentry from its inode, if any. Following this, free the inode
+ * if it is no longer in use. */
+void
+d_disassociate(struct wim_dentry *dentry)
+{
+ struct wim_inode *inode = dentry->d_inode;
+
+ if (unlikely(!inode))
+ return;
+
+ wimlib_assert(inode->i_nlink > 0);
+
+ list_del(&dentry->d_alias);
+ dentry->d_inode = NULL;
+ inode->i_nlink--;
+
+ free_inode_if_unneeded(inode);
+}
+
+#ifdef WITH_FUSE
+void
+inode_dec_num_opened_fds(struct wim_inode *inode)
+{
+ wimlib_assert(inode->i_num_opened_fds > 0);
+
+ if (--inode->i_num_opened_fds == 0) {
+ /* The last file descriptor to this inode was closed. */
+ FREE(inode->i_fds);
+ inode->i_fds = NULL;
+ inode->i_num_allocated_fds = 0;
+
+ free_inode_if_unneeded(inode);
+ }
+}
+#endif
+