+ hfs_chash_unlock(hfsmp);
+}
+
+/* Search a cnode in the hash. This function does not return cnode which
+ * are getting created, destroyed or in transition. Note that this function
+ * does not acquire the cnode hash mutex, and expects the caller to acquire it.
+ * On success, returns pointer to the cnode found. On failure, returns NULL.
+ */
+static
+struct cnode *
+hfs_chash_search_cnid(struct hfsmount *hfsmp, cnid_t cnid)
+{
+ struct cnode *cp;
+
+ for (cp = CNODEHASH(hfsmp, cnid)->lh_first; cp; cp = cp->c_hash.le_next) {
+ if (cp->c_fileid == cnid) {
+ break;
+ }
+ }
+
+ /* If cnode is being created or reclaimed, return error. */
+ if (cp && ISSET(cp->c_hflag, H_ALLOC | H_TRANSIT | H_ATTACH)) {
+ cp = NULL;
+ }
+
+ return cp;
+}
+
+/* Search a cnode corresponding to given device and ID in the hash. If the
+ * found cnode has kHFSHasChildLinkBit cleared, set it. If the cnode is not
+ * found, no new cnode is created and error is returned.
+ *
+ * Return values -
+ * -1 : The cnode was not found.
+ * 0 : The cnode was found, and the kHFSHasChildLinkBit was already set.
+ * 1 : The cnode was found, the kHFSHasChildLinkBit was not set, and the
+ * function had to set that bit.
+ */
+__private_extern__
+int
+hfs_chash_set_childlinkbit(struct hfsmount *hfsmp, cnid_t cnid)
+{
+ int retval = -1;
+ struct cnode *cp;
+
+ hfs_chash_lock_spin(hfsmp);
+
+ cp = hfs_chash_search_cnid(hfsmp, cnid);
+ if (cp) {
+ if (cp->c_attr.ca_recflags & kHFSHasChildLinkMask) {
+ retval = 0;
+ } else {
+ cp->c_attr.ca_recflags |= kHFSHasChildLinkMask;
+ retval = 1;
+ }
+ }
+ hfs_chash_unlock(hfsmp);
+
+ return retval;