mount struct prefixes go from m_ to mnt_ and M_ to MNT_
[unix-history] / usr / src / sys / ufs / ffs / ufs_inode.c
index ae130f0..10db271 100644 (file)
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- *     @(#)ufs_inode.c 7.24 (Berkeley) %G%
+ *     @(#)ufs_inode.c 7.32 (Berkeley) %G%
  */
 
 #include "param.h"
 #include "systm.h"
 #include "mount.h"
 #include "user.h"
  */
 
 #include "param.h"
 #include "systm.h"
 #include "mount.h"
 #include "user.h"
+#include "proc.h"
 #include "file.h"
 #include "buf.h"
 #include "cmap.h"
 #include "vnode.h"
 #include "file.h"
 #include "buf.h"
 #include "cmap.h"
 #include "vnode.h"
+#include "../ufs/quota.h"
 #include "../ufs/inode.h"
 #include "../ufs/fs.h"
 #include "../ufs/ufsmount.h"
 #include "../ufs/inode.h"
 #include "../ufs/fs.h"
 #include "../ufs/ufsmount.h"
-#ifdef QUOTA
-#include "../ufs/quota.h"
-#endif
 #include "kernel.h"
 #include "malloc.h"
 
 #include "kernel.h"
 #include "malloc.h"
 
@@ -64,6 +63,9 @@ ufs_init()
                ih->ih_head[0] = ih;
                ih->ih_head[1] = ih;
        }
                ih->ih_head[0] = ih;
                ih->ih_head[1] = ih;
        }
+#ifdef QUOTA
+       dqinit();
+#endif /* QUOTA */
 }
 
 /*
 }
 
 /*
@@ -90,8 +92,8 @@ iget(xp, ino, ipp)
        struct vnode *nvp;
        struct buf *bp;
        struct dinode *dp;
        struct vnode *nvp;
        struct buf *bp;
        struct dinode *dp;
-       union  ihead *ih;
-       int error;
+       union ihead *ih;
+       int i, error;
 
        ih = &ihead[INOHASH(dev, ino)];
 loop:
 
        ih = &ihead[INOHASH(dev, ino)];
 loop:
@@ -119,10 +121,11 @@ loop:
        ip->i_vnode = nvp;
        ip->i_flag = 0;
        ip->i_devvp = 0;
        ip->i_vnode = nvp;
        ip->i_flag = 0;
        ip->i_devvp = 0;
-       ip->i_lastr = 0;
        ip->i_mode = 0;
        ip->i_mode = 0;
+       ip->i_diroff = 0;
 #ifdef QUOTA
 #ifdef QUOTA
-       ip->i_dquot = NODQUOT;
+       for (i = 0; i < MAXQUOTAS; i++)
+               ip->i_dquot[i] = NODQUOT;
 #endif
        /*
         * Put it onto its hash chain and lock it so that other requests for
 #endif
        /*
         * Put it onto its hash chain and lock it so that other requests for
@@ -139,6 +142,14 @@ loop:
         */
        if (error = bread(VFSTOUFS(mntp)->um_devvp, fsbtodb(fs, itod(fs, ino)),
            (int)fs->fs_bsize, NOCRED, &bp)) {
         */
        if (error = bread(VFSTOUFS(mntp)->um_devvp, fsbtodb(fs, itod(fs, ino)),
            (int)fs->fs_bsize, NOCRED, &bp)) {
+               /*
+                * The inode does not contain anything useful, so it would
+                * be misleading to leave it on its hash chain.
+                * Iput() will take care of putting it back on the free list.
+                */
+               remque(ip);
+               ip->i_forw = ip;
+               ip->i_back = ip;
                /*
                 * Unlock and discard unneeded inode.
                 */
                /*
                 * Unlock and discard unneeded inode.
                 */
@@ -156,6 +167,16 @@ loop:
         */
        vp = ITOV(ip);
        vp->v_type = IFTOVT(ip->i_mode);
         */
        vp = ITOV(ip);
        vp->v_type = IFTOVT(ip->i_mode);
+       if (vp->v_type == VFIFO) {
+#ifdef FIFO
+               extern struct vnodeops fifo_inodeops;
+               vp->v_op = &fifo_inodeops;
+#else
+               iput(ip);
+               *ipp = 0;
+               return (EOPNOTSUPP);
+#endif /* FIFO */
+       }
        if (vp->v_type == VCHR || vp->v_type == VBLK) {
                vp->v_op = &spec_inodeops;
                if (nvp = checkalias(vp, ip->i_rdev, mntp)) {
        if (vp->v_type == VCHR || vp->v_type == VBLK) {
                vp->v_op = &spec_inodeops;
                if (nvp = checkalias(vp, ip->i_rdev, mntp)) {
@@ -165,7 +186,6 @@ loop:
                        vp = nvp;
                        iq = VTOI(vp);
                        iq->i_vnode = vp;
                        vp = nvp;
                        iq = VTOI(vp);
                        iq->i_vnode = vp;
-                       iq->i_lastr = 0;
                        iq->i_flag = 0;
                        ILOCK(iq);
                        iq->i_din = ip->i_din;
                        iq->i_flag = 0;
                        ILOCK(iq);
                        iq->i_din = ip->i_din;
@@ -188,10 +208,6 @@ loop:
        ip->i_fs = fs;
        ip->i_devvp = VFSTOUFS(mntp)->um_devvp;
        VREF(ip->i_devvp);
        ip->i_fs = fs;
        ip->i_devvp = VFSTOUFS(mntp)->um_devvp;
        VREF(ip->i_devvp);
-#ifdef QUOTA
-       if (ip->i_mode != 0)
-               ip->i_dquot = inoquota(ip);
-#endif
        /*
         * Set up a generation number for this inode if it does not
         * already have one. This should only happen on old filesystems.
        /*
         * Set up a generation number for this inode if it does not
         * already have one. This should only happen on old filesystems.
@@ -200,7 +216,7 @@ loop:
                if (++nextgennumber < (u_long)time.tv_sec)
                        nextgennumber = time.tv_sec;
                ip->i_gen = nextgennumber;
                if (++nextgennumber < (u_long)time.tv_sec)
                        nextgennumber = time.tv_sec;
                ip->i_gen = nextgennumber;
-               if ((vp->v_mount->m_flag & M_RDONLY) == 0)
+               if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
                        ip->i_flag |= IMOD;
        }
        *ipp = ip;
                        ip->i_flag |= IMOD;
        }
        *ipp = ip;
@@ -230,7 +246,7 @@ ufs_inactive(vp)
        register struct inode *ip = VTOI(vp);
        int mode, error = 0;
 
        register struct inode *ip = VTOI(vp);
        int mode, error = 0;
 
-       if (prtactive && vp->v_count != 0)
+       if (prtactive && vp->v_usecount != 0)
                vprint("ufs_inactive: pushing active", vp);
        /*
         * Get rid of inodes related to stale file handles.
                vprint("ufs_inactive: pushing active", vp);
        /*
         * Get rid of inodes related to stale file handles.
@@ -241,34 +257,26 @@ ufs_inactive(vp)
                return (0);
        }
        ILOCK(ip);
                return (0);
        }
        ILOCK(ip);
-       if (ip->i_nlink <= 0 && (vp->v_mount->m_flag & M_RDONLY) == 0) {
+       if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+#ifdef QUOTA
+               if (!getinoquota(ip))
+                       (void) chkiq(ip, -1, NOCRED, 0);
+#endif
                error = itrunc(ip, (u_long)0, 0);
                mode = ip->i_mode;
                ip->i_mode = 0;
                error = itrunc(ip, (u_long)0, 0);
                mode = ip->i_mode;
                ip->i_mode = 0;
-               ip->i_rdev = 0;
                ip->i_flag |= IUPD|ICHG;
                ifree(ip, ip->i_number, mode);
                ip->i_flag |= IUPD|ICHG;
                ifree(ip, ip->i_number, mode);
-#ifdef QUOTA
-               (void) chkiq(ip->i_dev, ip, ip->i_uid, 0);
-               dqrele(ip->i_dquot);
-               ip->i_dquot = NODQUOT;
-#endif
        }
        IUPDAT(ip, &time, &time, 0);
        }
        IUPDAT(ip, &time, &time, 0);
+       IUNLOCK(ip);
+       ip->i_flag = 0;
        /*
         * If we are done with the inode, reclaim it
         * so that it can be reused immediately.
         */
        /*
         * If we are done with the inode, reclaim it
         * so that it can be reused immediately.
         */
-       if (vp->v_count == 0 && ip->i_mode == 0) {
-               vinvalbuf(vp, 0);
-               IUNLOCK(ip);
-               ip->i_flag = 0;
-               if ((vp->v_flag & VXLOCK) == 0)
-                       vgone(vp);
-               return (error);
-       }
-       IUNLOCK(ip);
-       ip->i_flag = 0;
+       if (vp->v_usecount == 0 && ip->i_mode == 0)
+               vgone(vp);
        return (error);
 }
 
        return (error);
 }
 
@@ -279,8 +287,9 @@ ufs_reclaim(vp)
        register struct vnode *vp;
 {
        register struct inode *ip = VTOI(vp);
        register struct vnode *vp;
 {
        register struct inode *ip = VTOI(vp);
+       int i;
 
 
-       if (prtactive && vp->v_count != 0)
+       if (prtactive && vp->v_usecount != 0)
                vprint("ufs_reclaim: pushing active", vp);
        /*
         * Remove the inode from its hash chain.
                vprint("ufs_reclaim: pushing active", vp);
        /*
         * Remove the inode from its hash chain.
@@ -297,8 +306,12 @@ ufs_reclaim(vp)
                ip->i_devvp = 0;
        }
 #ifdef QUOTA
                ip->i_devvp = 0;
        }
 #ifdef QUOTA
-       dqrele(ip->i_dquot);
-       ip->i_dquot = NODQUOT;
+       for (i = 0; i < MAXQUOTAS; i++) {
+               if (ip->i_dquot[i] != NODQUOT) {
+                       dqrele(vp, ip->i_dquot[i]);
+                       ip->i_dquot[i] = NODQUOT;
+               }
+       }
 #endif
        ip->i_flag = 0;
        return (0);
 #endif
        ip->i_flag = 0;
        return (0);
@@ -323,7 +336,7 @@ iupdat(ip, ta, tm, waitfor)
        fs = ip->i_fs;
        if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0)
                return (0);
        fs = ip->i_fs;
        if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0)
                return (0);
-       if (vp->v_mount->m_flag & M_RDONLY)
+       if (vp->v_mount->mnt_flag & MNT_RDONLY)
                return (0);
        error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)),
                (int)fs->fs_bsize, NOCRED, &bp);
                return (0);
        error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)),
                (int)fs->fs_bsize, NOCRED, &bp);
@@ -406,6 +419,10 @@ itrunc(oip, length, flags)
                aflags = B_CLRBUF;
                if (flags & IO_SYNC)
                        aflags |= B_SYNC;
                aflags = B_CLRBUF;
                if (flags & IO_SYNC)
                        aflags |= B_SYNC;
+#ifdef QUOTA
+               if (error = getinoquota(oip))
+                       return (error);
+#endif
                if (error = balloc(oip, lbn, offset, &bp, aflags))
                        return (error);
                oip->i_size = length;
                if (error = balloc(oip, lbn, offset, &bp, aflags))
                        return (error);
                oip->i_size = length;
@@ -522,7 +539,8 @@ done:
                oip->i_blocks = 0;
        oip->i_flag |= ICHG;
 #ifdef QUOTA
                oip->i_blocks = 0;
        oip->i_flag |= ICHG;
 #ifdef QUOTA
-       (void) chkdq(oip, -blocksreleased, 0);
+       if (!getinoquota(oip))
+               (void) chkdq(oip, -blocksreleased, NOCRED, 0);
 #endif
        return (allerror);
 }
 #endif
        return (allerror);
 }
@@ -580,8 +598,6 @@ indirtrunc(ip, bn, lastbn, level, countp)
                *countp = 0;
                return (error);
        }
                *countp = 0;
                return (error);
        }
-       if ((bp->b_flags & B_CACHE) == 0)
-               reassignbuf(bp, ITOV(ip));
        bap = bp->b_un.b_daddr;
        MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
        bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
        bap = bp->b_un.b_daddr;
        MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
        bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
@@ -639,8 +655,14 @@ ilock(ip)
 
        while (ip->i_flag & ILOCKED) {
                ip->i_flag |= IWANT;
 
        while (ip->i_flag & ILOCKED) {
                ip->i_flag |= IWANT;
+               if (ip->i_spare0 == u.u_procp->p_pid)
+                       panic("locking against myself");
+               ip->i_spare1 = u.u_procp->p_pid;
                (void) sleep((caddr_t)ip, PINOD);
        }
                (void) sleep((caddr_t)ip, PINOD);
        }
+       ip->i_spare1 = 0;
+       ip->i_spare0 = u.u_procp->p_pid;
+       u.u_spare[0]++;
        ip->i_flag |= ILOCKED;
 }
 
        ip->i_flag |= ILOCKED;
 }
 
@@ -653,50 +675,11 @@ iunlock(ip)
 
        if ((ip->i_flag & ILOCKED) == 0)
                vprint("iunlock: unlocked inode", ITOV(ip));
 
        if ((ip->i_flag & ILOCKED) == 0)
                vprint("iunlock: unlocked inode", ITOV(ip));
+       ip->i_spare0 = 0;
+       u.u_spare[0]--;
        ip->i_flag &= ~ILOCKED;
        if (ip->i_flag&IWANT) {
                ip->i_flag &= ~IWANT;
                wakeup((caddr_t)ip);
        }
 }
        ip->i_flag &= ~ILOCKED;
        if (ip->i_flag&IWANT) {
                ip->i_flag &= ~IWANT;
                wakeup((caddr_t)ip);
        }
 }
-
-/*
- * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
- * The mode is shifted to select the owner/group/other fields. The
- * super user is granted all permissions.
- *
- * NB: Called from vnode op table. It seems this could all be done
- * using vattr's but...
- */
-iaccess(ip, mode, cred)
-       register struct inode *ip;
-       register int mode;
-       struct ucred *cred;
-{
-       register gid_t *gp;
-       int i;
-
-       /*
-        * If you're the super-user, you always get access.
-        */
-       if (cred->cr_uid == 0)
-               return (0);
-       /*
-        * Access check is based on only one of owner, group, public.
-        * If not owner, then check group. If not a member of the
-        * group, then check public access.
-        */
-       if (cred->cr_uid != ip->i_uid) {
-               mode >>= 3;
-               gp = cred->cr_groups;
-               for (i = 0; i < cred->cr_ngroups; i++, gp++)
-                       if (ip->i_gid == *gp)
-                               goto found;
-               mode >>= 3;
-found:
-               ;
-       }
-       if ((ip->i_mode & mode) != 0)
-               return (0);
-       return (EACCES);
-}