]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_quota.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_quota.c
index 5c219f0d88ae4c05e966ce4e5ee119e228108b38..989bd67bf1f728548eef2b8d5cc809ab9fe879c9 100644 (file)
@@ -106,6 +106,7 @@ hfs_getinoquota(cp)
        struct hfsmount *hfsmp;
        struct vnode *vp;
        int error;
        struct hfsmount *hfsmp;
        struct vnode *vp;
        int error;
+       int drop_usrquota = false;
 
        vp = cp->c_vp ? cp->c_vp : cp->c_rsrc_vp;
        hfsmp = VTOHFS(vp);
 
        vp = cp->c_vp ? cp->c_vp : cp->c_rsrc_vp;
        hfsmp = VTOHFS(vp);
@@ -113,20 +114,30 @@ hfs_getinoquota(cp)
         * Set up the user quota based on file uid.
         * EINVAL means that quotas are not enabled.
         */
         * Set up the user quota based on file uid.
         * EINVAL means that quotas are not enabled.
         */
-       if (cp->c_dquot[USRQUOTA] == NODQUOT &&
-           (error =
-               dqget(cp->c_uid, &hfsmp->hfs_qfiles[USRQUOTA], USRQUOTA, &cp->c_dquot[USRQUOTA])) &&
-           error != EINVAL)
-               return (error);
+       if (cp->c_dquot[USRQUOTA] == NODQUOT) {
+               error = dqget(cp->c_uid, &hfsmp->hfs_qfiles[USRQUOTA], USRQUOTA, &cp->c_dquot[USRQUOTA]);
+               if ((error != 0) && (error != EINVAL)) {
+                       return error;
+               } else if (error == 0) {
+                       drop_usrquota = true;
+               }
+       }
+
        /*
         * Set up the group quota based on file gid.
         * EINVAL means that quotas are not enabled.
         */
        /*
         * Set up the group quota based on file gid.
         * EINVAL means that quotas are not enabled.
         */
-       if (cp->c_dquot[GRPQUOTA] == NODQUOT &&
-           (error =
-               dqget(cp->c_gid, &hfsmp->hfs_qfiles[GRPQUOTA], GRPQUOTA, &cp->c_dquot[GRPQUOTA])) &&
-           error != EINVAL)
-               return (error);
+       if (cp->c_dquot[GRPQUOTA] == NODQUOT) {
+              error = dqget(cp->c_gid, &hfsmp->hfs_qfiles[GRPQUOTA], GRPQUOTA, &cp->c_dquot[GRPQUOTA]);
+              if ((error != 0) && (error != EINVAL)) {
+                      if (drop_usrquota == true) {
+                              dqrele(cp->c_dquot[USRQUOTA]);
+                              cp->c_dquot[USRQUOTA] = NODQUOT;
+                      }
+                      return error;
+              }
+       }
+
        return (0);
 }
 
        return (0);
 }
 
@@ -561,9 +572,9 @@ hfs_quotaon(p, mp, type, fnamep)
                goto out;
        }
        vfs_setflags(mp, (u_int64_t)((unsigned int)MNT_QUOTA));
                goto out;
        }
        vfs_setflags(mp, (u_int64_t)((unsigned int)MNT_QUOTA));
-       HFS_MOUNT_LOCK(hfsmp, TRUE)
+       hfs_lock_mount (hfsmp);
        hfsmp->hfs_flags |= HFS_QUOTAS;
        hfsmp->hfs_flags |= HFS_QUOTAS;
-       HFS_MOUNT_UNLOCK(hfsmp, TRUE);
+       hfs_unlock_mount (hfsmp);
        vnode_setnoflush(vp);
        /*
         * Save the credential of the process that turned on quotas.
        vnode_setnoflush(vp);
        /*
         * Save the credential of the process that turned on quotas.
@@ -693,9 +704,9 @@ hfs_quotaoff(__unused struct proc *p, struct mount *mp, register int type)
                        break;
        if (type == MAXQUOTAS) {
                vfs_clearflags(mp, (u_int64_t)((unsigned int)MNT_QUOTA));
                        break;
        if (type == MAXQUOTAS) {
                vfs_clearflags(mp, (u_int64_t)((unsigned int)MNT_QUOTA));
-               HFS_MOUNT_LOCK(hfsmp, TRUE)
+               hfs_lock_mount (hfsmp);
                hfsmp->hfs_flags &= ~HFS_QUOTAS;
                hfsmp->hfs_flags &= ~HFS_QUOTAS;
-               HFS_MOUNT_UNLOCK(hfsmp, TRUE);
+               hfs_unlock_mount (hfsmp);
        }
 
        qf_put(qfp, QTF_CLOSING);
        }
 
        qf_put(qfp, QTF_CLOSING);