]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/vfs/vfs_syscalls.c
xnu-792.21.3.tar.gz
[apple/xnu.git] / bsd / vfs / vfs_syscalls.c
index 5675ce21f2d0af3554496d159841f264213810af..340c6ab9d1633d01d675586fd29c134bf0eb84e6 100644 (file)
@@ -1,23 +1,29 @@
 /*
  * Copyright (c) 1995-2005 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * 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.
+ * 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. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ 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
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * Copyright (c) 1989, 1993
@@ -190,6 +196,7 @@ mount(struct proc *p, register struct mount_args *uap, __unused register_t *retv
        int mntalloc = 0;
        mode_t accessmode;
        boolean_t is_64bit;
+       boolean_t is_rwlock_locked = FALSE;
 
        AUDIT_ARG(fflags, uap->flags);
 
@@ -227,13 +234,13 @@ mount(struct proc *p, register struct mount_args *uap, __unused register_t *retv
                }
                mount_unlock(mp);
                lck_rw_lock_exclusive(&mp->mnt_rwlock);
+               is_rwlock_locked = TRUE;
                /*
                 * We only allow the filesystem to be reloaded if it
                 * is currently mounted read-only.
                 */
                if ((uap->flags & MNT_RELOAD) &&
                    ((mp->mnt_flag & MNT_RDONLY) == 0)) {
-                       lck_rw_done(&mp->mnt_rwlock);
                        error = ENOTSUP;
                        goto out1;
                }
@@ -243,7 +250,6 @@ mount(struct proc *p, register struct mount_args *uap, __unused register_t *retv
                 */
                if (mp->mnt_vfsstat.f_owner != kauth_cred_getuid(context.vc_ucred) &&
                    (error = suser(context.vc_ucred, &p->p_acflag))) {
-                       lck_rw_done(&mp->mnt_rwlock);
                        goto out1;
                }
                /*
@@ -333,6 +339,7 @@ mount(struct proc *p, register struct mount_args *uap, __unused register_t *retv
        TAILQ_INIT(&mp->mnt_newvnodes);
        mount_lock_init(mp);
        lck_rw_lock_exclusive(&mp->mnt_rwlock);
+       is_rwlock_locked = TRUE;
        mp->mnt_op = vfsp->vfc_vfsops;
        mp->mnt_vtable = vfsp;
        mount_list_lock();
@@ -471,6 +478,7 @@ update:
                        mp->mnt_flag = flag;
                vfs_event_signal(NULL, VQ_UPDATE, (intptr_t)NULL);
                lck_rw_done(&mp->mnt_rwlock);
+               is_rwlock_locked = FALSE;
                if (!error)
                        enablequotas(mp,&context);
                goto out2;
@@ -490,6 +498,7 @@ update:
                vfs_event_signal(NULL, VQ_MOUNT, (intptr_t)NULL);
                checkdirs(vp, &context);
                lck_rw_done(&mp->mnt_rwlock);
+               is_rwlock_locked = FALSE;
                mount_list_add(mp);
                /* 
                 * there is no cleanup code here so I have made it void 
@@ -523,6 +532,7 @@ update:
                        vnode_rele(device_vnode);
                }
                lck_rw_done(&mp->mnt_rwlock);
+               is_rwlock_locked = FALSE;
                mount_lock_destroy(mp);
                FREE_ZONE((caddr_t)mp, sizeof (struct mount), M_MOUNT);
        }
@@ -544,6 +554,10 @@ out2:
        if (devpath && devvp)
                vnode_put(devvp);
 out1:
+       /* Release mnt_rwlock only when it was taken */
+       if (is_rwlock_locked == TRUE) {
+               lck_rw_done(&mp->mnt_rwlock);
+       }
        if (mntalloc)
                FREE_ZONE((caddr_t)mp, sizeof (struct mount), M_MOUNT);
        vnode_put(vp);