X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2fc1f182af106c37b41ba174ccd893f532ac8d36..82161bc863f8bfc002a6ffd03a59c3548161874f:/usr/src/sys/ufs/ffs/ufs_inode.c diff --git a/usr/src/sys/ufs/ffs/ufs_inode.c b/usr/src/sys/ufs/ffs/ufs_inode.c index ae130f0503..10db2713c9 100644 --- a/usr/src/sys/ufs/ffs/ufs_inode.c +++ b/usr/src/sys/ufs/ffs/ufs_inode.c @@ -14,23 +14,22 @@ * 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 "proc.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" -#ifdef QUOTA -#include "../ufs/quota.h" -#endif #include "kernel.h" #include "malloc.h" @@ -64,6 +63,9 @@ ufs_init() 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; - union ihead *ih; - int error; + union ihead *ih; + int i, error; 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_lastr = 0; ip->i_mode = 0; + ip->i_diroff = 0; #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 @@ -139,6 +142,14 @@ loop: */ 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. */ @@ -156,6 +167,16 @@ loop: */ 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)) { @@ -165,7 +186,6 @@ loop: 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; @@ -188,10 +208,6 @@ loop: 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. @@ -200,7 +216,7 @@ loop: 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; @@ -230,7 +246,7 @@ ufs_inactive(vp) 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. @@ -241,34 +257,26 @@ ufs_inactive(vp) 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; - ip->i_rdev = 0; 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); + IUNLOCK(ip); + ip->i_flag = 0; /* * 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); } @@ -279,8 +287,9 @@ ufs_reclaim(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. @@ -297,8 +306,12 @@ ufs_reclaim(vp) 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); @@ -323,7 +336,7 @@ iupdat(ip, ta, tm, waitfor) 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); @@ -406,6 +419,10 @@ itrunc(oip, length, flags) 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; @@ -522,7 +539,8 @@ done: 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); } @@ -580,8 +598,6 @@ indirtrunc(ip, bn, lastbn, level, countp) *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); @@ -639,8 +655,14 @@ ilock(ip) 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); } + ip->i_spare1 = 0; + ip->i_spare0 = u.u_procp->p_pid; + u.u_spare[0]++; ip->i_flag |= ILOCKED; } @@ -653,50 +675,11 @@ iunlock(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); } } - -/* - * 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); -}