]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_vnops.c
xnu-792.6.70.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_vnops.c
index 9edfa86ed243380dc04e32726741e40ae3f6fb7a..507bb153cb8b12485a6d3756b3816f86017fa636 100644 (file)
@@ -3,20 +3,19 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License").  You may not use this file except in compliance with the
+ * License.  Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
  * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -290,7 +289,7 @@ hfs_vnop_getattr(struct vnop_getattr_args *ap)
                        if (vnode_isvroot(vp)) {
                                if (hfsmp->hfs_privdir_desc.cd_cnid != 0)
                                        --entries;     /* hide private dir */
-                               if (hfsmp->jnl)
+                               if (hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY)))
                                        entries -= 2;  /* hide the journal files */
                        }
                        VATTR_RETURN(vap, va_nlink, (uint64_t)entries);
@@ -1891,6 +1890,10 @@ out:
 __private_extern__ void
 replace_desc(struct cnode *cp, struct cat_desc *cdp)
 {
+    if (&cp->c_desc == cdp) {
+        return;
+    }
+         
        /* First release allocated name buffer */
        if (cp->c_desc.cd_flags & CD_HASBUF && cp->c_desc.cd_nameptr != 0) {
                char *name = cp->c_desc.cd_nameptr;
@@ -3168,6 +3171,22 @@ hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp, struct vnode **rvpp, __un
                struct componentname cn;
                int lockflags;
 
+               /*
+                * Make sure cnode lock is exclusive, if not upgrade it.
+                *
+                * We assume that we were called from a read-only VNOP (getattr)
+                * and that its safe to have the cnode lock dropped and reacquired.
+                */
+               if (cp->c_lockowner != current_thread()) {
+                       /*
+                        * If the upgrade fails we loose the lock and
+                        * have to take the exclusive lock on our own.
+                        */
+                       if (lck_rw_lock_shared_to_exclusive(&cp->c_rwlock) != 0)
+                               lck_rw_lock_exclusive(&cp->c_rwlock);
+                       cp->c_lockowner = current_thread();
+               }
+
                lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
 
                /* Get resource fork data */