avoid null pointers
[unix-history] / usr / src / sys / ufs / ffs / ufs_quota.c
index b6b82b1..869adc5 100644 (file)
@@ -7,7 +7,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ufs_quota.c 7.8 (Berkeley) %G%
+ *     @(#)ufs_quota.c 7.11 (Berkeley) %G%
  */
 #include "param.h"
 #include "kernel.h"
  */
 #include "param.h"
 #include "kernel.h"
@@ -338,16 +338,17 @@ quotaon(p, mp, type, fname)
        if (error = vn_open(&nd, p, FREAD|FWRITE, 0))
                return (error);
        vp = nd.ni_vp;
        if (error = vn_open(&nd, p, FREAD|FWRITE, 0))
                return (error);
        vp = nd.ni_vp;
+       VOP_UNLOCK(vp);
        if (vp->v_type != VREG) {
        if (vp->v_type != VREG) {
-               vrele(vp);
+               (void) vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
                return (EACCES);
        }
        if (vfs_busy(mp)) {
                return (EACCES);
        }
        if (vfs_busy(mp)) {
-               vrele(vp);
+               (void) vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
                return (EBUSY);
        }
        if (*vpp != vp)
                return (EBUSY);
        }
        if (*vpp != vp)
-               quotaoff(mp, type);
+               quotaoff(p, mp, type);
        ump->um_qflags[type] |= QTF_OPENING;
        mp->mnt_flag |= MNT_QUOTA;
        vp->v_flag |= VSYSTEM;
        ump->um_qflags[type] |= QTF_OPENING;
        mp->mnt_flag |= MNT_QUOTA;
        vp->v_flag |= VSYSTEM;
@@ -370,13 +371,12 @@ quotaon(p, mp, type, fname)
        /*
         * Search vnodes associated with this mount point,
         * adding references to quota file being opened.
        /*
         * Search vnodes associated with this mount point,
         * adding references to quota file being opened.
-        * NB: only need to add dquot's for inodes being modified;
-        * vp->v_usecount == 0 below should use vp->v_writecnt == 0.
+        * NB: only need to add dquot's for inodes being modified.
         */
 again:
        for (vp = mp->mnt_mounth; vp; vp = nextvp) {
                nextvp = vp->v_mountf;
         */
 again:
        for (vp = mp->mnt_mounth; vp; vp = nextvp) {
                nextvp = vp->v_mountf;
-               if (vp->v_usecount == 0)
+               if (vp->v_writecount == 0)
                        continue;
                if (vget(vp))
                        goto again;
                        continue;
                if (vget(vp))
                        goto again;
@@ -390,7 +390,7 @@ again:
        }
        ump->um_qflags[type] &= ~QTF_OPENING;
        if (error)
        }
        ump->um_qflags[type] &= ~QTF_OPENING;
        if (error)
-               quotaoff(mp, type);
+               quotaoff(p, mp, type);
        vfs_unbusy(mp);
        return (error);
 }
        vfs_unbusy(mp);
        return (error);
 }
@@ -398,7 +398,8 @@ again:
 /*
  * Q_QUOTAOFF - turn off disk quotas for a filesystem.
  */
 /*
  * Q_QUOTAOFF - turn off disk quotas for a filesystem.
  */
-quotaoff(mp, type)
+quotaoff(p, mp, type)
+       struct proc *p;
        struct mount *mp;
        register int type;
 {
        struct mount *mp;
        register int type;
 {
@@ -407,6 +408,7 @@ quotaoff(mp, type)
        struct ufsmount *ump = VFSTOUFS(mp);
        register struct dquot *dq;
        register struct inode *ip;
        struct ufsmount *ump = VFSTOUFS(mp);
        register struct dquot *dq;
        register struct inode *ip;
+       int error;
        
        if ((mp->mnt_flag & MNT_MPBUSY) == 0)
                panic("quotaoff: not busy");
        
        if ((mp->mnt_flag & MNT_MPBUSY) == 0)
                panic("quotaoff: not busy");
@@ -432,7 +434,7 @@ again:
        }
        dqflush(qvp);
        qvp->v_flag &= ~VSYSTEM;
        }
        dqflush(qvp);
        qvp->v_flag &= ~VSYSTEM;
-       vrele(qvp);
+       error = vn_close(qvp, FREAD|FWRITE, p->p_ucred, p);
        ump->um_quotas[type] = NULLVP;
        crfree(ump->um_cred[type]);
        ump->um_cred[type] = NOCRED;
        ump->um_quotas[type] = NULLVP;
        crfree(ump->um_cred[type]);
        ump->um_cred[type] = NOCRED;
@@ -442,7 +444,7 @@ again:
                        break;
        if (type == MAXQUOTAS)
                mp->mnt_flag &= ~MNT_QUOTA;
                        break;
        if (type == MAXQUOTAS)
                mp->mnt_flag &= ~MNT_QUOTA;
-       return (0);
+       return (error);
 }
 
 /*
 }
 
 /*
@@ -579,14 +581,25 @@ qsync(mp)
        register int i;
 
        /*
        register int i;
 
        /*
-        * Search vnodes associated with this mount point,
-        * synchronizing any modified dquot structures.
+        * Check if the mount point has any quotas.
+        * If not, simply return.
         */
        if ((mp->mnt_flag & MNT_MPBUSY) == 0)
                panic("qsync: not busy");
         */
        if ((mp->mnt_flag & MNT_MPBUSY) == 0)
                panic("qsync: not busy");
+       for (i = 0; i < MAXQUOTAS; i++)
+               if (ump->um_quotas[i] != NULLVP)
+                       break;
+       if (i == MAXQUOTAS)
+               return (0);
+       /*
+        * Search vnodes associated with this mount point,
+        * synchronizing any modified dquot structures.
+        */
 again:
        for (vp = mp->mnt_mounth; vp; vp = nextvp) {
                nextvp = vp->v_mountf;
 again:
        for (vp = mp->mnt_mounth; vp; vp = nextvp) {
                nextvp = vp->v_mountf;
+               if (VOP_ISLOCKED(vp))
+                       continue;
                if (vget(vp))
                        goto again;
                for (i = 0; i < MAXQUOTAS; i++) {
                if (vget(vp))
                        goto again;
                for (i = 0; i < MAXQUOTAS; i++) {