- /* Initialize a starting descriptor. */
- bzero(&prevdesc, sizeof(prevdesc));
- prevdesc.cd_flags = CD_DECOMPOSED;
- prevdesc.cd_hint = dcp->c_childhint;
- prevdesc.cd_parentcnid = dcp->c_cnid;
- prevdesc.cd_nameptr = hfs_getnamehint(dcp, index);
- prevdesc.cd_namelen = prevdesc.cd_nameptr ? strlen(prevdesc.cd_nameptr) : 0;
-
+ /* Get a directory hint (cnode must be locked exclusive) */
+ dirhint = hfs_getdirhint(dcp, ((index - 1) & HFS_INDEX_MASK) | tag);
+
+ /* Hide tag from catalog layer. */
+ dirhint->dh_index &= HFS_INDEX_MASK;
+ if (dirhint->dh_index == HFS_INDEX_MASK) {
+ dirhint->dh_index = -1;
+ }
+
+ /*
+ * An ATTR_CMN_USERACCESS attribute request can result in a
+ * call to kauth_cred_ismember_gid(). So when requesting
+ * this attribute we downgrade our exclusive lock on dcp to
+ * a shared lock in case kauth_cred_ismember_gid generates
+ * an indirect call back into the file system.
+ */
+ if (alist->commonattr & ATTR_CMN_USERACCESS) {
+ lck_rw_lock_exclusive_to_shared(&dcp->c_rwlock);
+ dcp->c_lockowner = HFS_SHARED_OWNER;
+ shared_cnode_lock = 1;
+ }