X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/3ebac8783496629faa980d207379977e9b5dca72..528f664cb046a6bc60c14f34650cb0acdbdb084a:/usr/src/sys/ufs/ffs/ffs_inode.c diff --git a/usr/src/sys/ufs/ffs/ffs_inode.c b/usr/src/sys/ufs/ffs/ffs_inode.c index cf74b323fc..7ec3e8bcc4 100644 --- a/usr/src/sys/ufs/ffs/ffs_inode.c +++ b/usr/src/sys/ufs/ffs/ffs_inode.c @@ -1,4 +1,4 @@ -/* ffs_inode.c 4.13 82/06/29 */ +/* ffs_inode.c 4.23 82/08/10 */ #include "../h/param.h" #include "../h/systm.h" @@ -10,6 +10,9 @@ #include "../h/conf.h" #include "../h/buf.h" #include "../h/inline.h" +#ifdef QUOTA +#include "../h/quota.h" +#endif #define INOHSZ 63 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -98,8 +101,8 @@ iget(dev, fs, ino) register struct fs *fs; ino_t ino; { - register struct inode *ip; /* known to be r11 - see "asm" below */ - register union ihead *ih; /* known to be r10 - see "asm" below */ + register struct inode *ip; + register union ihead *ih; register struct mount *mp; register struct buf *bp; register struct dinode *dp; @@ -157,18 +160,10 @@ loop: * but that doesn't matter), and put it on the chain for * its new (ino, dev) pair */ -#ifndef UNFAST - asm("remque (r11),r0"); - asm("insque (r11),(r10)"); -#else - /* remque */ - ip->i_back->i_forw = ip->i_forw; - ip->i_forw->i_back = ip->i_back; - /* insque */ - ip->i_forw = ih->ih_chain[0]; - ip->i_back = (struct inode *)ih; - ih->ih_chain[0]->i_back = ip; - ih->ih_chain[0] = ip; + remque(ip); + insque(ip, ih); +#ifdef QUOTA + dqrele(ip->i_dquot); #endif ip->i_dev = dev; ip->i_fs = fs; @@ -187,12 +182,7 @@ loop: * be misleading to leave it on its hash chain. * 'iput' will take care of putting it back on the free list. */ -#ifndef UNFAST - asm("remque (r11),r0"); -#else - ip->i_back->i_forw = ip->i_forw; - ip->i_forw->i_back = ip->i_back; -#endif + remque(ip); ip->i_forw = ip; ip->i_back = ip; /* @@ -202,6 +192,9 @@ loop: * (probably the two methods are interchangable) */ ip->i_number = 0; +#ifdef QUOTA + ip->i_dquot = NODQUOT; +#endif iput(ip); return(NULL); } @@ -209,6 +202,12 @@ loop: dp += itoo(fs, ino); ip->i_ic = dp->di_ic; brelse(bp); +#ifdef QUOTA + if (ip->i_mode == 0) + ip->i_dquot = NODQUOT; + else + ip->i_dquot = inoquota(ip); +#endif return (ip); } @@ -239,11 +238,17 @@ irele(ip) if (ip->i_count == 1) { ip->i_flag |= ILOCK; if (ip->i_nlink <= 0) { - itrunc(ip); + itrunc(ip, 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 + 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); @@ -305,6 +310,8 @@ iupdat(ip, ta, tm, waitfor) if (ip->i_flag&ICHG) ip->i_ctime = time; ip->i_flag &= ~(IUPD|IACC|ICHG); + dp = bp->b_un.b_dino + itoo(fp, ip->i_number); + dp->di_ic = ip->i_ic; if (waitfor) bwrite(bp); else @@ -313,32 +320,40 @@ iupdat(ip, ta, tm, waitfor) } /* - * Free all the disk blocks associated - * with the specified inode structure. - * The blocks of the file are removed - * in reverse order. This FILO - * algorithm will tend to maintain - * a contiguous free list much longer - * than FIFO. + * Truncate the inode ip to at most + * length size. Free affected disk + * blocks -- the blocks of the file + * are removed in reverse order. */ -itrunc(ip) +itrunc(ip, length) register struct inode *ip; + register int length; { register i; dev_t dev; daddr_t bn; struct inode itmp; register struct fs *fs; - +#ifdef QUOTA + register long cnt = 0; + long tloop(); +#endif + /* + * Only plain files, directories and symbolic + * links contain blocks. + */ i = ip->i_mode & IFMT; if (i != IFREG && i != IFDIR && i != IFLNK) return; + if (ip->i_size <= length) + return; + /* * Clean inode on disk before freeing blocks * to insure no duplicates if system crashes. */ itmp = *ip; - itmp.i_size = 0; + itmp.i_size = length; for (i = 0; i < NDADDR; i++) itmp.i_db[i] = 0; for (i = 0; i < NIADDR; i++) @@ -359,7 +374,10 @@ itrunc(ip) bn = ip->i_ib[NIADDR-1]; if (bn != (daddr_t)0) { ip->i_ib[NIADDR - 1] = (daddr_t)0; - tloop(ip, bn, 1); +#ifdef QUOTA + cnt += +#endif + tloop(ip, bn, 1); } /* * release single indirect blocks second @@ -368,26 +386,40 @@ itrunc(ip) bn = ip->i_ib[i]; if (bn != (daddr_t)0) { ip->i_ib[i] = (daddr_t)0; - tloop(ip, bn, 0); +#ifdef QUOTA + cnt += +#endif + tloop(ip, bn, 0); } } /* * finally release direct blocks */ for (i = NDADDR - 1; i>=0; i--) { + register size; + bn = ip->i_db[i]; if (bn == (daddr_t)0) continue; ip->i_db[i] = (daddr_t)0; - fre(ip, bn, (off_t)blksize(fs, ip, i)); + fre(ip, bn, size = (off_t)blksize(fs, ip, i)); +#ifdef QUOTA + cnt += size / DEV_BSIZE; +#endif } ip->i_size = 0; /* * Inode was written and flags updated above. * No need to modify flags here. */ +#ifdef QUOTA + (void) chkdq(ip, -cnt, 0); +#endif } +#ifdef QUOTA +long +#endif tloop(ip, bn, indflg) register struct inode *ip; daddr_t bn; @@ -398,6 +430,9 @@ tloop(ip, bn, indflg) register daddr_t *bap; register struct fs *fs; daddr_t nb; +#ifdef QUOTA + register long cnt = 0; +#endif bp = NULL; fs = ip->i_fs; @@ -413,146 +448,25 @@ tloop(ip, bn, indflg) nb = bap[i]; if (nb == (daddr_t)0) continue; - if (indflg) - tloop(ip, nb, 0); - else + if (indflg) { +#ifdef QUOTA + cnt += +#endif + tloop(ip, nb, 0); + } else { fre(ip, nb, fs->fs_bsize); +#ifdef QUOTA + cnt += fs->fs_bsize / DEV_BSIZE; +#endif + } } if (bp != NULL) brelse(bp); fre(ip, bn, fs->fs_bsize); -} - -/* - * Make a new file. - */ -struct inode * -maknode(mode) - int mode; -{ - register struct inode *ip; - ino_t ipref; - - if ((mode & IFMT) == IFDIR) - ipref = dirpref(u.u_pdir->i_fs); - else - ipref = u.u_pdir->i_number; - ip = ialloc(u.u_pdir, ipref, mode); - if (ip == NULL) { - iput(u.u_pdir); - return(NULL); - } - ip->i_flag |= IACC|IUPD|ICHG; - if ((mode & IFMT) == 0) - mode |= IFREG; - ip->i_mode = mode & ~u.u_cmask; - ip->i_nlink = 1; - ip->i_uid = u.u_uid; - ip->i_gid = u.u_pdir->i_gid; - - /* - * Make sure inode goes to disk before directory entry. - */ - iupdat(ip, &time, &time, 1); - wdir(ip); - if (u.u_error) { - /* - * write error occurred trying to update directory - * so must deallocate the inode - */ - ip->i_nlink = 0; - ip->i_flag |= ICHG; - iput(ip); - return(NULL); - } - return(ip); -} - -/* - * Write a directory entry with - * parameters left as side effects - * to a call to namei. - */ -wdir(ip) - struct inode *ip; -{ - register struct direct *dp, *ndp; - struct fs *fs; - struct buf *bp; - int lbn, bn, base; - int loc, dsize, spccnt, newsize; - char *dirbuf; - - u.u_dent.d_ino = ip->i_number; - u.u_segflg = 1; - newsize = DIRSIZ(&u.u_dent); - /* - * if u.u_count == 0, a new directory block must be allocated. - */ - if (u.u_count == 0) { - u.u_dent.d_reclen = DIRBLKSIZ; - u.u_count = newsize; - u.u_base = (caddr_t)&u.u_dent; - writei(u.u_pdir); - iput(u.u_pdir); - return; - } - /* - * must read in an existing directory block - * to prepare to place the new entry into it. - */ - fs = u.u_pdir->i_fs; - lbn = lblkno(fs, u.u_offset); - base = blkoff(fs, u.u_offset); - bn = fsbtodb(fs, bmap(u.u_pdir, lbn, B_WRITE, base + u.u_count)); - if (u.u_offset + u.u_count > u.u_pdir->i_size) - u.u_pdir->i_size = u.u_offset + u.u_count; - bp = bread(u.u_pdir->i_dev, bn, blksize(fs, u.u_pdir, lbn)); - if (bp->b_flags & B_ERROR) { - brelse(bp); - return; - } - dirbuf = bp->b_un.b_addr + base; - dp = (struct direct *)dirbuf; - dsize = DIRSIZ(dp); - spccnt = dp->d_reclen - dsize; - /* - * if there is insufficient room to make an entry at this point - * namei insures that compacting from u.u_offset for u.u_count - * bytes will provide the necessary space. - */ - for (loc = dp->d_reclen; loc < u.u_count; ) { - ndp = (struct direct *)(dirbuf + loc); - if (dp->d_ino == 0) { - spccnt += dsize; - } else { - dp->d_reclen = dsize; - dp = (struct direct *)((char *)dp + dsize); - } - dsize = DIRSIZ(ndp); - spccnt += ndp->d_reclen - dsize; - loc += ndp->d_reclen; - bcopy(ndp, dp, dsize); - } - /* - * Update the pointer fields in the previous entry (if any), - * copy in the new entry, and write out the block. - */ - if (dp->d_ino == 0) { - if (spccnt + dsize < newsize) - panic("wdir: compact failed"); - u.u_dent.d_reclen = spccnt + dsize; - } else { - if (spccnt < newsize) - panic("wdir: compact failed"); - u.u_dent.d_reclen = spccnt; - dp->d_reclen = dsize; - dp = (struct direct *)((char *)dp + dsize); - } - bcopy(&u.u_dent, dp, newsize); - bwrite(bp); - u.u_pdir->i_flag |= IUPD|ICHG; - iput(u.u_pdir); +#ifdef QUOTA + cnt += fs->fs_bsize / DEV_BSIZE; + return(cnt); +#endif } /* @@ -568,23 +482,28 @@ wdir(ip) * * this is called from sumount()/sys3.c when dev is being unmounted */ +#ifdef QUOTA +iflush(dev, iq) + dev_t dev; + struct inode *iq; +#else iflush(dev) dev_t dev; +#endif { - register struct inode *ip; /* known to be r11 - see 'asm' below */ + register struct inode *ip; register open = 0; for (ip = inode; ip < inodeNINODE; ip++) { +#ifdef QUOTA + if (ip != iq && ip->i_dev == dev) +#else if (ip->i_dev == dev) +#endif if (ip->i_count) return(-1); else { -#ifndef UNFAST - asm("remque (r11),r0"); -#else - ip->i_back->i_forw = ip->i_forw; - ip->i_forw->i_back = ip->i_back; -#endif + remque(ip); ip->i_forw = ip; ip->i_back = ip; /* @@ -596,6 +515,10 @@ iflush(dev) * infrequently, we would gain very little, * while making the code bigger. */ +#ifdef QUOTA + dqrele(ip->i_dquot); + ip->i_dquot = NODQUOT; +#endif } else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK && ip->i_rdev == dev)