X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/ca91bdedd2489d9b5752953fdd5bfeab37b6031b..0a77f2784dfeeb48f31fce2136d65b59c321c607:/usr/src/sys/ufs/ffs/ffs_vnops.c diff --git a/usr/src/sys/ufs/ffs/ffs_vnops.c b/usr/src/sys/ufs/ffs/ffs_vnops.c index 89267be701..3b1656adbb 100644 --- a/usr/src/sys/ufs/ffs/ffs_vnops.c +++ b/usr/src/sys/ufs/ffs/ffs_vnops.c @@ -1,8 +1,5 @@ -/* ffs_vnops.c 4.25 82/06/07 */ +/* ffs_vnops.c 4.29 82/07/22 */ -#ifdef SIMFS -#include "../h/sysrenam.h" -#endif #include "../h/param.h" #include "../h/systm.h" #include "../h/dir.h" @@ -14,6 +11,11 @@ #include "../h/buf.h" #include "../h/proc.h" #include "../h/inline.h" +#ifdef EFS +#include "../net/in.h" +#include "../h/efs.h" +#endif +#include "../h/quota.h" chdir() { @@ -46,10 +48,8 @@ register struct inode **ipp; if(access(ip, IEXEC)) goto bad; iunlock(ip); - if (*ipp) { - ilock(*ipp); - iput(*ipp); - } + if (*ipp) + irele(*ipp); *ipp = ip; return; @@ -120,8 +120,10 @@ open1(ip, mode, trf) u.u_error = EISDIR; } } - if (u.u_error) - goto out; + if (u.u_error) { + iput(ip); + return; + } if (trf == 1) itrunc(ip); iunlock(ip); @@ -130,14 +132,17 @@ open1(ip, mode, trf) fp->f_flag = mode&(FREAD|FWRITE); i = u.u_r.r_val1; fp->f_inode = ip; +#ifdef EFS + openi(ip, mode&(FREAD|FWRITE), trf); +#else openi(ip, mode&(FREAD|FWRITE)); +#endif if (u.u_error == 0) return; u.u_ofile[i] = NULL; fp->f_count--; out: - if (ip != NULL) - iput(ip); + irele(ip); } /* @@ -193,8 +198,10 @@ link() ip = namei(uchar, 0, 1); /* well, this routine is doomed anyhow */ if (ip == NULL) return; - if ((ip->i_mode&IFMT)==IFDIR && !suser()) - goto out1; + if ((ip->i_mode&IFMT)==IFDIR && !suser()) { + iput(ip); + return; + } ip->i_nlink++; ip->i_flag |= ICHG; iupdat(ip, &time, &time, 1); @@ -220,7 +227,7 @@ out: ip->i_flag |= ICHG; } out1: - iput(ip); + irele(ip); } /* @@ -281,10 +288,31 @@ unlink() struct fs *fs; struct buf *bp; int lbn, bn, base; + int unlinkingdot = 0; pp = namei(uchar, 2, 0); if(pp == NULL) return; +#ifdef EFS + /* divert to extended file system if off machine. */ + if (efsinode(pp)) { + dev_t ndev = pp->i_rdev; + + iput(pp); /* avoid recursive hang on inode */ + efsunlink(ndev); + if (u.u_error != EEXIST) + return; + + /* + * If a null pathname remainder, then do + * the unlink locally after restoring state. + */ + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + pp = namei(uchar, 2, 0); + } +#endif + /* * Check for unlink(".") * to avoid hanging on the iget @@ -292,6 +320,7 @@ unlink() if (pp->i_number == u.u_dent.d_ino) { ip = pp; ip->i_count++; + unlinkingdot++; } else ip = iget(pp->i_dev, pp->i_fs, u.u_dent.d_ino); if(ip == NULL) @@ -343,7 +372,10 @@ unlink() ip->i_flag |= ICHG; out: - iput(ip); + if (unlinkingdot) + irele(ip); + else + iput(ip); out1: iput(pp); } @@ -370,8 +402,14 @@ seek() } if (uap->sbase == 1) uap->off += fp->f_offset; - else if (uap->sbase == 2) + else if (uap->sbase == 2) { +#ifdef EFS + struct inode *ip = fp->f_inode; + uap->off += efsinode(ip) ? efsfilesize(fp) : ip->i_size; +#else uap->off += fp->f_inode->i_size; +#endif + } fp->f_offset = uap->off; u.u_r.r_off = uap->off; } @@ -394,6 +432,19 @@ saccess() u.u_uid = u.u_ruid; u.u_gid = u.u_rgid; ip = namei(uchar, 0, 1); +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efssaccess(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = namei(uchar, 0, 1); + } +#endif if (ip != NULL) { if (uap->fmode&(IREAD>>6)) (void) access(ip, IREAD); @@ -422,6 +473,12 @@ fstat() fp = getf(uap->fdes); if (fp == NULL) return; +#ifdef EFS + if (efsinode(fp->f_inode)) { + efsfstat(fp->f_inode->i_rdev, fp); + return; + } +#endif if (fp->f_flag & FSOCKET) u.u_error = sostat(fp->f_socket, uap->sb); else @@ -443,6 +500,19 @@ stat() ip = namei(uchar, 0, 1); if (ip == NULL) return; +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efsstat(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = namei(uchar, 0, 1); + } +#endif stat1(ip, uap->sb); iput(ip); } @@ -462,6 +532,19 @@ lstat() ip = namei(uchar, 0, 0); if (ip == NULL) return; +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efslstat(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = namei(uchar, 0, 0); + } +#endif stat1(ip, uap->sb); iput(ip); } @@ -511,6 +594,20 @@ readlink() ip = namei(uchar, 0, 0); if (ip == NULL) return; +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efsreadlink(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = namei(uchar, 0, 0); + return (0); + } +#endif if ((ip->i_mode&IFMT) != IFLNK) { u.u_error = ENXIO; goto out; @@ -537,13 +634,44 @@ chmod() uap = (struct a *)u.u_ap; if ((ip = owner(1)) == NULL) return; +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efschmod(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = owner(1); + } +#endif ip->i_mode &= ~07777; - if (u.u_uid) + if (u.u_uid) { uap->fmode &= ~ISVTX; + if (ip->i_gid >= NGRPS || + (u.u_grps[ip->i_gid/(sizeof(int)*8)] & + (1 << ip->i_gid%(sizeof(int)*8))) == 0) + uap->fmode &= ~ISGID; +#if MUSH + if (u.u_quota->q_syflags & QF_UMASK && u.u_uid != 0 && + (ip->i_mode & IFMT) != IFCHR) + uap->fmode &= ~u.u_cmask; +#endif + } ip->i_mode |= uap->fmode&07777; ip->i_flag |= ICHG; if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0) xrele(ip); +#ifdef MELB + if ((ip->i_mode & ISUID) && ip->i_uid == 0) + printf("%s: ino %d (%s) setuid root\n" + , getfs(ip->i_dev)->s_fsmnt + , ip->i_number + , u.u_dent.d_name + ); +#endif iput(ip); } @@ -555,15 +683,71 @@ chown() int uid; int gid; } *uap; +#if QUOTA + register long change; +#endif uap = (struct a *)u.u_ap; if (!suser() || (ip = owner(0)) == NULL) return; - ip->i_uid = uap->uid; - ip->i_gid = uap->gid; +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efschown(ndev); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = owner(0); + } +#endif +#if QUOTA + /* + * This doesn't allow for holes in files (which hopefully don't + * happen often in files that we chown), and is not accurate anyway + * (eg: it totally ignores 3 level indir blk files - but hopefully + * noone who can make a file that big will have a quota) + */ + if (ip->i_uid == uap->uid) + change = 0; + else { + register struct fs *fs = ip->i_fs; + + if (ip->i_size > (change = NDADDR * fs->fs_bsize)) { + register off_t size; + + size = blkroundup(fs, ip->i_size) - change; + change += size; + change += fs->fs_bsize; + /* This assumes NIADDR <= 2 */ + if (size > NINDIR(fs) * fs->fs_bsize) + change += fs->fs_bsize; + } else + change = fragroundup(fs, ip->i_size); + change /= DEV_BSIZE; + } + chkdq(ip, -change, 1); + chkiq(ip->i_dev, ip, ip->i_uid, 1); + dqrele(ip->i_dquot); +#endif + /* + * keep uid/gid's in sane range - no err, so chown(file, uid, -1) + * will do something useful + */ + if (uap->uid >= 0 && uap->uid <= 32767) /* should have a const */ + ip->i_uid = uap->uid; + if (uap->gid >= 0 && uap->gid <= 32767) /* same here */ + ip->i_gid = uap->gid; ip->i_flag |= ICHG; if (u.u_ruid != 0) ip->i_mode &= ~(ISUID|ISGID); +#if QUOTA + ip->i_dquot = inoquota(ip); + chkdq(ip, change, 1); + chkiq(ip->i_dev, NULL, uap->uid, 1); +#endif iput(ip); } @@ -586,6 +770,19 @@ utime() if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) { u.u_error = EFAULT; } else { +#ifdef EFS + if (efsinode(ip)) { + dev_t ndev = ip->i_rdev; + + iput(ip); + efsutime(ndev, uap->fname, tv); + if (u.u_error != EEXIST) + return; + u.u_error = 0; + u.u_dirp = (caddr_t)u.u_arg[0]; + ip = owner(1); + } +#endif ip->i_flag |= IACC|IUPD|ICHG; iupdat(ip, &tv[0], &tv[1], 0); }