]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_vfsops.c
xnu-792.6.76.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_vfsops.c
index 7ebe8aff727050771fff87363d7dc9037f378960..ba4a5983d9b836a1e2324d605de5f3a69e737770 100644 (file)
@@ -548,7 +548,7 @@ hfs_reload_callback(struct vnode *vp, void *cargs)
        /*
         * Re-read cnode data for all active vnodes (non-metadata files).
         */
-       if (!VNODE_IS_RSRC(vp)) {
+       if (!vnode_issystem(vp) && !VNODE_IS_RSRC(vp)) {
                struct cat_fork *datafork;
                struct cat_desc desc;
 
@@ -591,7 +591,6 @@ hfs_reload(struct mount *mountp, kauth_cred_t cred, struct proc *p)
        struct filefork *forkp;
        struct cat_desc cndesc;
        struct hfs_reload_cargs args;
-       int lockflags;
 
        hfsmp = VFSTOHFS(mountp);
        vcb = HFSTOVCB(hfsmp);
@@ -617,9 +616,7 @@ hfs_reload(struct mount *mountp, kauth_cred_t cred, struct proc *p)
         * the vnode will be in an 'unbusy' state (VNODE_WAIT) and 
         * properly referenced and unreferenced around the callback
         */
-       lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_EXCLUSIVE_LOCK);
        vnode_iterate(mountp, VNODE_RELOAD | VNODE_WAIT, hfs_reload_callback, (void *)&args);
-       hfs_systemfile_unlock(hfsmp, lockflags);
 
        if (args.error)
                return (args.error);
@@ -2163,6 +2160,7 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)
        struct cat_attr cnattr;
        struct cat_fork cnfork;
        struct componentname cn;
+       u_int32_t linkref = 0;
        int error;
        
        /* Check for cnids that should't be exported. */
@@ -2215,18 +2213,19 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)
                        return (error);
                }
 
-               /* Hide open files that have been deleted */
-               if ((hfsmp->hfs_privdir_desc.cd_cnid != 0) &&
-                   (cndesc.cd_parentcnid == hfsmp->hfs_privdir_desc.cd_cnid)) {
-                   // XXXdbg - if this is a hardlink, we could call
-                   //          hfs_chash_snoop() to see if there is
-                   //          already a cnode and vnode present for
-                   //          this fileid.  however I'd rather not
-                   //          risk it at this point in Tiger.
-                       cat_releasedesc(&cndesc);
-                       error = ENOENT;
-                       *vpp = NULL;
-                       return (error);
+               /*
+                * If we just looked up a raw hardlink inode,
+                * then finish initializing it.
+                */
+               if ((cndesc.cd_parentcnid == hfsmp->hfs_privdir_desc.cd_cnid) &&
+                   (bcmp(cndesc.cd_nameptr, HFS_INODE_PREFIX, HFS_INODE_PREFIX_LEN) == 0)) {
+                       linkref = strtoul((const char*)&cndesc.cd_nameptr[HFS_INODE_PREFIX_LEN], NULL, 10);
+                       cnattr.ca_rdev = linkref;
+
+                       // patch up the parentcnid
+                       if (cnattr.ca_attrblks != 0) {
+                           cndesc.cd_parentcnid = cnattr.ca_attrblks;
+                       }
                }
        }
 
@@ -2246,6 +2245,10 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)
 
        /* XXX should we supply the parent as well... ? */
        error = hfs_getnewvnode(hfsmp, NULLVP, &cn, &cndesc, 0, &cnattr, &cnfork, &vp);
+       if (error == 0 && linkref != 0) {
+               VTOC(vp)->c_flag |= C_HARDLINK;
+       }
+
        FREE_ZONE(cn.cn_pnbuf, cn.cn_pnlen, M_NAMEI);
 
        cat_releasedesc(&cndesc);
@@ -3277,7 +3280,6 @@ hfs_reclaimspace(struct hfsmount *hfsmp, u_long startblk)
                if (VTOF(vp)->ff_blocks > 0) {
                        error = hfs_relocate(vp, hfsmp->hfs_metazone_end + 1, kauth_cred_get(), current_proc());
                }
-               hfs_unlock(VTOC(vp));
                if (error) 
                        break;
 
@@ -3286,17 +3288,17 @@ hfs_reclaimspace(struct hfsmount *hfsmp, u_long startblk)
                        error = hfs_vgetrsrc(hfsmp, vp, &rvp, current_proc());
                        if (error)
                                break;
-                       hfs_lock(VTOC(rvp), HFS_EXCLUSIVE_LOCK);
                        error = hfs_relocate(rvp, hfsmp->hfs_metazone_end + 1, kauth_cred_get(), current_proc());
-                       hfs_unlock(VTOC(rvp));
                        vnode_put(rvp);
                        if (error)
                                break;
                }
+               hfs_unlock(VTOC(vp));
                vnode_put(vp);
                vp = NULL;
        }
        if (vp) {
+               hfs_unlock(VTOC(vp));
                vnode_put(vp);
                vp = NULL;
        }