- vp = hfsmp->hfs_attrdata_vp;
- if (vp == NULLVP) {
- struct cat_desc cat_desc;
- struct cat_attr cat_attr;
- struct cat_fork cat_fork;
-
- /* We don't tag it as a system file since we intend to use cluster I/O. */
- bzero(&cat_desc, sizeof(cat_desc));
- cat_desc.cd_parentcnid = kHFSRootParentID;
- cat_desc.cd_nameptr = (const u_int8_t *)hfs_attrdatafilename;
- cat_desc.cd_namelen = strlen(hfs_attrdatafilename);
- cat_desc.cd_cnid = kHFSAttributeDataFileID;
-
- bzero(&cat_attr, sizeof(cat_attr));
- cat_attr.ca_linkcount = 1;
- cat_attr.ca_mode = S_IFREG;
- cat_attr.ca_fileid = cat_desc.cd_cnid;
- cat_attr.ca_blocks = hfsmp->totalBlocks;
-
- /*
- * The attribute data file is a virtual file that spans the
- * entire file system space.
- *
- * Each extent-based attribute occupies a unique portion of
- * in this virtual file. The cluster I/O is done using actual
- * allocation block offsets so no additional mapping is needed
- * for the VNOP_BLOCKMAP call.
- *
- * This approach allows the attribute data to be cached without
- * incurring the high cost of using a separate vnode per attribute.
- *
- * Since we need to acquire the attribute b-tree file lock anyways,
- * the virtual file doesn't introduce any additional serialization.
- */
- bzero(&cat_fork, sizeof(cat_fork));
- cat_fork.cf_size = (u_int64_t)hfsmp->totalBlocks * (u_int64_t)hfsmp->blockSize;
- cat_fork.cf_blocks = hfsmp->totalBlocks;
- cat_fork.cf_extents[0].startBlock = 0;
- cat_fork.cf_extents[0].blockCount = cat_fork.cf_blocks;
-
- result = hfs_getnewvnode(hfsmp, NULL, NULL, &cat_desc, 0, &cat_attr, &cat_fork, &vp);
- if (result == 0) {
- HFS_MOUNT_LOCK(hfsmp, 1);
- /* Check if someone raced us for creating this vnode. */
- if (hfsmp->hfs_attrdata_vp != NULLVP) {
- HFS_MOUNT_UNLOCK(hfsmp, 1);
- vnode_put(vp);
- vnode_recycle(vp);
- vp = hfsmp->hfs_attrdata_vp;
- } else {
- hfsmp->hfs_attrdata_vp = vp;
- HFS_MOUNT_UNLOCK(hfsmp, 1);
- /* Keep a reference on this vnode until unmount */
- vnode_ref_ext(vp, O_EVTONLY);
- hfs_unlock(VTOC(vp));
- }
- }
- } else {
- if ((result = vnode_get(vp)))
- vp = NULLVP;
+ /*
+ * The attribute data file is a virtual file that spans the
+ * entire file system space.
+ *
+ * Each extent-based attribute occupies a unique portion of
+ * in this virtual file. The cluster I/O is done using actual
+ * allocation block offsets so no additional mapping is needed
+ * for the VNOP_BLOCKMAP call.
+ *
+ * This approach allows the attribute data to be cached without
+ * incurring the high cost of using a separate vnode per attribute.
+ *
+ * Since we need to acquire the attribute b-tree file lock anyways,
+ * the virtual file doesn't introduce any additional serialization.
+ */
+ bzero(&cat_fork, sizeof(cat_fork));
+ cat_fork.cf_size = (u_int64_t)hfsmp->totalBlocks * (u_int64_t)hfsmp->blockSize;
+ cat_fork.cf_blocks = hfsmp->totalBlocks;
+ cat_fork.cf_extents[0].startBlock = 0;
+ cat_fork.cf_extents[0].blockCount = cat_fork.cf_blocks;
+
+ result = hfs_getnewvnode(hfsmp, NULL, NULL, &cat_desc, 0, &cat_attr,
+ &cat_fork, &vp, &newvnode_flags);
+ if (result == 0) {
+ hfsmp->hfs_attrdata_vp = vp;
+ hfs_unlock(VTOC(vp));