X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/cfef43737c9be4fd12e0f4cb87d50ed730391313..c08094697ede949543913593622ee52e7fab5512:/usr/src/sys/ufs/ffs/ufs_vnops.c?ds=inline diff --git a/usr/src/sys/ufs/ffs/ufs_vnops.c b/usr/src/sys/ufs/ffs/ufs_vnops.c index f7f51d5278..9f387861f2 100644 --- a/usr/src/sys/ufs/ffs/ufs_vnops.c +++ b/usr/src/sys/ufs/ffs/ufs_vnops.c @@ -4,7 +4,7 @@ * * %sccs.include.redist.c% * - * @(#)ufs_vnops.c 7.72 (Berkeley) %G% + * @(#)ufs_vnops.c 7.88 (Berkeley) %G% */ #include @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -30,16 +32,9 @@ #include #include -int ufs_chmod __P((struct vnode *, int, struct proc *)); -int ufs_chown __P((struct vnode *, u_int, u_int, struct proc *)); - -enum vtype iftovt_tab[16] = { - VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, - VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, -}; -int vttoif_tab[9] = { - 0, IFREG, IFDIR, IFBLK, IFCHR, IFLNK, IFSOCK, IFIFO, IFMT, -}; +int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *)); +int ufs_chown + __P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *)); #ifdef _NOQUAD #define SETHIGH(q, h) (q).val[_QUAD_HIGHWORD] = (h) @@ -67,8 +62,7 @@ union _qcvt { * Create a regular file */ int -ufs_create(dvp, vpp, cnp, vap) /* converted to CN. */ -/* was: ufs_create(ndp, vap, p) */ +ufs_create(dvp, vpp, cnp, vap) struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; @@ -87,8 +81,7 @@ ufs_create(dvp, vpp, cnp, vap) /* converted to CN. */ */ /* ARGSUSED */ int -ufs_mknod(dvp, vpp, cnp, vap) /* converted to CN. */ -/* was: ufs_mknod(ndp, vap, cred, p) */ +ufs_mknod(dvp, vpp, cnp, vap) struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; @@ -243,12 +236,9 @@ ufs_getattr(vp, vap, cred, p) #else vap->va_qsize = ip->i_din.di_qsize; #endif - vap->va_atime.tv_sec = ip->i_atime; - vap->va_atime.tv_usec = 0; - vap->va_mtime.tv_sec = ip->i_mtime; - vap->va_mtime.tv_usec = 0; - vap->va_ctime.tv_sec = ip->i_ctime; - vap->va_ctime.tv_usec = 0; + vap->va_atime = ip->i_atime; + vap->va_mtime = ip->i_mtime; + vap->va_ctime = ip->i_ctime; vap->va_flags = ip->i_flags; vap->va_gen = ip->i_gen; /* this doesn't belong here */ @@ -292,13 +282,13 @@ ufs_setattr(vp, vap, cred, p) /* * Go through the fields and update iff not VNOVAL. */ - if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL) - if (error = ufs_chown(vp, vap->va_uid, vap->va_gid, p)) + if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) + if (error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) return (error); if (vap->va_size != VNOVAL) { if (vp->v_type == VDIR) return (EISDIR); - if (error = VOP_TRUNCATE(vp, vap->va_size, 0)) /* IO_SYNC? */ + if (error = VOP_TRUNCATE(vp, vap->va_size, 0, cred)) return (error); } ip = VTOI(vp); @@ -315,8 +305,8 @@ ufs_setattr(vp, vap, cred, p) return (error); } error = 0; - if (vap->va_mode != (u_short)VNOVAL) - error = ufs_chmod(vp, (int)vap->va_mode, p); + if (vap->va_mode != (mode_t)VNOVAL) + error = ufs_chmod(vp, (int)vap->va_mode, cred, p); if (vap->va_flags != VNOVAL) { if (cred->cr_uid != ip->i_uid && (error = suser(cred, &p->p_acflag))) @@ -337,12 +327,12 @@ ufs_setattr(vp, vap, cred, p) * Inode must be locked before calling. */ static int -ufs_chmod(vp, mode, p) +ufs_chmod(vp, mode, cred, p) register struct vnode *vp; register int mode; + register struct ucred *cred; struct proc *p; { - register struct ucred *cred = p->p_ucred; register struct inode *ip = VTOI(vp); int error; @@ -368,14 +358,14 @@ ufs_chmod(vp, mode, p) * inode must be locked prior to call. */ static int -ufs_chown(vp, uid, gid, p) +ufs_chown(vp, uid, gid, cred, p) register struct vnode *vp; - u_int uid; - u_int gid; + uid_t uid; + gid_t gid; + struct ucred *cred; struct proc *p; { register struct inode *ip = VTOI(vp); - register struct ucred *cred = p->p_ucred; uid_t ouid; gid_t ogid; int error = 0; @@ -384,9 +374,9 @@ ufs_chown(vp, uid, gid, p) long change; #endif - if (uid == (u_short)VNOVAL) + if (uid == (uid_t)VNOVAL) uid = ip->i_uid; - if (gid == (u_short)VNOVAL) + if (gid == (gid_t)VNOVAL) gid = ip->i_gid; /* * If we don't own the file, are trying to change the owner @@ -538,8 +528,7 @@ ufs_seek(vp, oldoff, newoff, cred) * in unlinking directories. */ int -ufs_remove(dvp, vp, cnp) /* converted to CN. */ -/* old: ufs_remove(ndp, p) */ +ufs_remove(dvp, vp, cnp) struct vnode *dvp, *vp; struct componentname *cnp; { @@ -565,21 +554,20 @@ ufs_remove(dvp, vp, cnp) /* converted to CN. */ * link vnode call */ int -ufs_link(vp, tdvp, cnp) /* converted to CN. */ -/* old: ufs_link(vp, ndp, p) */ - register struct vnode *vp; /* source vnode */ +ufs_link(tdvp, vp, cnp) struct vnode *tdvp; + register struct vnode *vp; /* source vnode */ struct componentname *cnp; { register struct inode *ip; int error; -#ifdef DIANOSTIC +#ifdef DIAGNOSTIC if ((cnp->cn_flags & HASBUF) == 0) panic("ufs_link: no name"); #endif ip = VTOI(vp); - if ((unsigned short)ip->i_nlink >= LINK_MAX) { + if ((nlink_t)ip->i_nlink >= LINK_MAX) { free(cnp->cn_pnbuf, M_NAMEI); return (EMLINK); } @@ -608,26 +596,27 @@ ufs_link(vp, tdvp, cnp) /* converted to CN. */ * Used by lookup to re-aquire things. */ int -relookup(dvp, vpp, cnp) /* converted to CN */ +relookup(dvp, vpp, cnp) struct vnode *dvp, **vpp; struct componentname *cnp; { - register char *cp; /* pointer into pathname argument */ register struct vnode *dp = 0; /* the directory we are searching */ struct vnode *tdp; /* saved dp */ struct mount *mp; /* mount table entry */ int docache; /* == 0 do not cache last component */ int wantparent; /* 1 => wantparent or lockparent flag */ int rdonly; /* lookup read-only flag bit */ + char *cp; /* DEBUG: check name ptr/len */ + int newhash; /* DEBUG: check name hash */ int error = 0; - int newhash; /* * Setup: break out flag bits into variables. */ wantparent = cnp->cn_flags & (LOCKPARENT|WANTPARENT); docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; - if (cnp->cn_nameiop == DELETE || (wantparent && cnp->cn_nameiop != CREATE)) + if (cnp->cn_nameiop == DELETE || + (wantparent && cnp->cn_nameiop != CREATE)) docache = 0; rdonly = cnp->cn_flags & RDONLY; cnp->cn_flags &= ~ISSYMLINK; @@ -644,36 +633,16 @@ relookup(dvp, vpp, cnp) /* converted to CN */ * the name set the SAVENAME flag. When done, they assume * responsibility for freeing the pathname buffer. */ -/* NEEDWORK: is hash computed needed */ - newhash = 0; - for (cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++) +#ifdef NAMEI_DIAGNOSTIC + for (newhash = 0, cp = cnp->cn_nameptr; *cp != 0 && *cp != '/'; cp++) newhash += (unsigned char)*cp; if (newhash != cnp->cn_hash) panic("relookup: bad hash"); if (cnp->cn_namelen != cp - cnp->cn_nameptr) panic ("relookup: bad len"); - if (cnp->cn_namelen >= NAME_MAX) { - error = ENAMETOOLONG; - goto bad; - } -#ifdef NAMEI_DIAGNOSTIC /* NEEDSWORK: should go */ - { char c = *cp; - *cp = '\0'; + if (*cp != 0) + panic("relookup: not last component"); printf("{%s}: ", cnp->cn_nameptr); - *cp = c; } -#endif -#if 0 - cnp->cn_pathlen -= cnp->cn_namelen; - ndp->ni_next = cp; -#endif -#if 0 - cnp->cn_flags |= MAKEENTRY; - if (*cp == '\0' && docache == 0) - cnp->cn_flags &= ~MAKEENTRY; - if (cnp->cn_namelen == 2 && - cnp->ni_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.') - cnp->cn_flags |= ISDOTDOT; - else cnp->cn_flags &= ~ISDOTDOT; #endif /* @@ -698,37 +667,6 @@ relookup(dvp, vpp, cnp) /* converted to CN */ return (0); } - /* - * Handle "..": two special cases. - * 1. If at root directory (e.g. after chroot) - * then ignore it so can't get out. - * 2. If this vnode is the root of a mounted - * filesystem, then replace it with the - * vnode which was mounted on so we take the - * .. in the other file system. - */ -#if 0 - /* This shouldn't happen because rename throws out .. */ - /* NEEDSWORK: what to do about this? */ - if (cnp->cn_flags & ISDOTDOT) { - for (;;) { - if (dp == ndp->ni_rootdir) { - ndp->ni_dvp = dp; - ndp->ni_vp = dp; - VREF(dp); - goto nextname; - } - if ((dp->v_flag & VROOT) == 0 || - (cnp->cn_flags & NOCROSSMOUNT)) - break; - tdp = dp; - dp = dp->v_mount->mnt_vnodecovered; - vput(tdp); - VREF(dp); - VOP_LOCK(dp); - } - } -#endif if (cnp->cn_flags & ISDOTDOT) panic ("relookup: lookup on dot-dot"); @@ -740,11 +678,7 @@ relookup(dvp, vpp, cnp) /* converted to CN */ if (*vpp != NULL) panic("leaf should be empty"); #endif -#ifdef NAMEI_DIAGNOSTIC - printf("not found\n"); -#endif - if (cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == DELETE || - error != ENOENT || *cp != 0) + if (error != EJUSTRETURN) goto bad; /* * If creating and at end of pathname, then can consider @@ -754,94 +688,27 @@ relookup(dvp, vpp, cnp) /* converted to CN */ error = EROFS; goto bad; } + /* ASSERT(dvp == ndp->ni_startdir) */ + if (cnp->cn_flags & SAVESTART) + VREF(dvp); /* * We return with ni_vp NULL to indicate that the entry * doesn't currently exist, leaving a pointer to the * (possibly locked) directory inode in ndp->ni_dvp. */ -#ifdef JOHNH - /* - * no need because we don't need to do another lookup. - * NEEDSWORK: don't do release. - * but wait...let's try it a different way. - */ - if (cnp->cn_flags & SAVESTART) { -#if 0 - ndp->ni_startdir = ndp->ni_dvp; - VREF(ndp->ni_startdir); -#else - /* - * startdir == dvp, always - */ - VREF(dvp); -#endif - } -#endif return (0); } -#ifdef NAMEI_DIAGNOSTIC - printf("found\n"); -#endif - dp = *vpp; + +#ifdef DIAGNOSTIC /* * Check for symbolic link */ -#if 0 - if ((dp->v_type == VLNK) && - ((cnp->cn_flags & FOLLOW) || *ndp->ni_next == '/')) { - cnp->cn_flags |= ISSYMLINK; - return (0); - } -#endif - if (dp->v_type == VLNK) { + if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW)) panic ("relookup: symlink found.\n"); - }; - - /* - * Check to see if the vnode has been mounted on; - * if so find the root of the mounted file system. - */ -#if 0 - /* NEEDSWORK: mounts should not be crossed in cnlookup */ - /* - * Checked for in rename (returns EXDEV). - */ -mntloop: - while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && - (cnp->cn_flags & NOCROSSMOUNT) == 0) { - if (mp->mnt_flag & MNT_MLOCK) { - mp->mnt_flag |= MNT_MWAIT; - sleep((caddr_t)mp, PVFS); - goto mntloop; - } - if (error = VFS_ROOT(dp->v_mountedhere, &tdp)) - goto bad2; - vput(dp); - ndp->ni_vp = dp = tdp; - } #endif - if (dp->v_type == VDIR && (dp->v_mountedhere)) - panic ("relookup: mount point encountered."); - nextname: - /* - * Not a symbolic link. If more pathname, - * continue at next component, else return. - */ -#if 0 - if (*ndp->ni_next == '/') { - cnp->cn_nameptr = ndp->ni_next; - while (*cnp->cn_nameptr == '/') { - ndp->ni_nameptr++; - ndp->ni_pathlen--; - } - vrele(ndp->ni_dvp); - goto dirloop; - } -#endif - /* * Check for read-only file systems. */ @@ -857,14 +724,9 @@ nextname: goto bad2; } } - if (cnp->cn_flags & SAVESTART) { -#if 0 - ndp->ni_startdir = ndp->ni_dvp; - VREF(ndp->ni_startdir); -#endif - /* ASSERT(dvp==ndp->ni_startdir) */ + /* ASSERT(dvp == ndp->ni_startdir) */ + if (cnp->cn_flags & SAVESTART) VREF(dvp); - } if (!wantparent) vrele(dvp); @@ -909,8 +771,7 @@ bad: */ int ufs_rename(fdvp, fvp, fcnp, - tdvp, tvp, tcnp) /* converted to CN. */ -/* old: ufs_rename(fndp, tndp, p) */ + tdvp, tvp, tcnp) struct vnode *fdvp, *fvp; struct componentname *fcnp; struct vnode *tdvp, *tvp; @@ -922,7 +783,7 @@ ufs_rename(fdvp, fvp, fcnp, int error = 0; int fdvpneedsrele = 1, tdvpneedsrele = 1; -#ifdef DIANOSTIC +#ifdef DIAGNOSTIC if ((tcnp->cn_flags & HASBUF) == 0 || (fcnp->cn_flags & HASBUF) == 0) panic("ufs_rename: no name"); @@ -1034,7 +895,7 @@ ufs_rename(fdvp, fvp, fcnp, * parent we don't fool with the link count. */ if (doingdirectory && newparent) { - if ((unsigned short)dp->i_nlink >= LINK_MAX) { + if ((nlink_t)dp->i_nlink >= LINK_MAX) { error = EMLINK; goto bad; } @@ -1119,7 +980,8 @@ ufs_rename(fdvp, fvp, fcnp, if (doingdirectory) { if (--xp->i_nlink != 0) panic("rename: linked directory"); - error = VOP_TRUNCATE(ITOV(xp), (u_long)0, IO_SYNC); + error = VOP_TRUNCATE(ITOV(xp), (off_t)0, IO_SYNC, + tcnp->cn_cred); } xp->i_flag |= ICHG; ufs_iput(xp); @@ -1135,7 +997,7 @@ unlinkit: if ((fcnp->cn_flags & SAVESTART) == 0) panic("ufs_rename: lost from startdir"); p->p_spare[1]--; - (void) relookup(fdvp, &fvp, fcnp); /* NEEDSWORK: startdir stuff */ + (void) relookup(fdvp, &fvp, fcnp); if (fvp != NULL) { xp = VTOI(fvp); dp = VTOI(fdvp); @@ -1179,7 +1041,7 @@ unlinkit: if (dirbuf.dotdot_namlen != 2 || dirbuf.dotdot_name[0] != '.' || dirbuf.dotdot_name[1] != '.') { - ufs_dirbad(xp, 12, + ufs_dirbad(xp, (doff_t)12, "rename: mangled dir"); } else { dirbuf.dotdot_ino = newparent; @@ -1231,8 +1093,7 @@ static struct dirtemplate mastertemplate = { * Mkdir system call */ int -ufs_mkdir(dvp, vpp, cnp, vap) /* converted to CN. */ -/* was: ufs_mkdir(cnp, vap) */ +ufs_mkdir(dvp, vpp, cnp, vap) struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; @@ -1244,12 +1105,12 @@ ufs_mkdir(dvp, vpp, cnp, vap) /* converted to CN. */ int error; int dmode; -#ifdef DIANOSTIC +#ifdef DIAGNOSTIC if ((cnp->cn_flags & HASBUF) == 0) panic("ufs_mkdir: no name"); #endif dp = VTOI(dvp); - if ((unsigned short)dp->i_nlink >= LINK_MAX) { + if ((nlink_t)dp->i_nlink >= LINK_MAX) { free(cnp->cn_pnbuf, M_NAMEI); ufs_iput(dp); return (EMLINK); @@ -1340,9 +1201,9 @@ bad: * Rmdir system call. */ int -ufs_rmdir(dvp, vp, cnp) /* converted to CN. */ -/* old: ufs_rmdir(ndp, p) */ - struct vnode *dvp, *vp; +ufs_rmdir(dvp, vp, cnp) + struct vnode *dvp; + struct vnode *vp; struct componentname *cnp; { register struct inode *ip, *dp; @@ -1395,7 +1256,7 @@ ufs_rmdir(dvp, vp, cnp) /* converted to CN. */ * worry about them later. */ ip->i_nlink -= 2; - error = VOP_TRUNCATE(vp, (u_long)0, IO_SYNC); + error = VOP_TRUNCATE(vp, (off_t)0, IO_SYNC, cnp->cn_cred); cache_purge(ITOV(ip)); out: if (dvp) @@ -1408,8 +1269,7 @@ out: * symlink -- make a symbolic link */ int -ufs_symlink(dvp, vpp, cnp, vap, target) /* converted to CN. */ -/* old: ufs_symlink(ndp, vap, target, p) */ +ufs_symlink(dvp, vpp, cnp, vap, target) struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; @@ -1428,7 +1288,13 @@ ufs_symlink(dvp, vpp, cnp, vap, target) /* converted to CN. */ } /* - * Vnode op for read and write + * Vnode op for reading directories. + * + * The routine below assumes that the on-disk format of a directory + * is the same as that defined by . If the on-disk + * format changes, then it will be necessary to do a conversion + * from the on-disk format that read returns to the format defined + * by . */ int ufs_readdir(vp, uio, cred, eofflagp) @@ -1474,7 +1340,7 @@ ufs_readlink(vp, uiop, cred) */ /* ARGSUSED */ int -ufs_abortop(dvp, cnp) /* converted to CN. */ +ufs_abortop(dvp, cnp) struct vnode *dvp; struct componentname *cnp; { @@ -1528,8 +1394,6 @@ ufs_islocked(vp) * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. */ -int checkoverlap = 0; - int ufs_strategy(bp) register struct buf *bp; @@ -1543,8 +1407,12 @@ ufs_strategy(bp) panic("ufs_strategy: spec"); if (bp->b_blkno == bp->b_lblkno) { if (error = - VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno)) + VOP_BMAP(bp->b_vp, bp->b_lblkno, NULL, &bp->b_blkno)) { + bp->b_error = error; + bp->b_flags |= B_ERROR; + biodone(bp); return (error); + } if ((long)bp->b_blkno == -1) clrbuf(bp); } @@ -1552,11 +1420,6 @@ ufs_strategy(bp) biodone(bp); return (0); } -#ifdef DIAGNOSTIC - if (checkoverlap && bp->b_vp->v_mount->mnt_stat.f_type == MOUNT_UFS) - ffs_checkoverlap(bp, ip); -#endif - vp = ip->i_devvp; bp->b_dev = vp->v_rdev; (vp->v_op->vop_strategy)(bp); @@ -1794,7 +1657,8 @@ ufs_advlock(vp, id, op, fl, flags) int ufs_vinit(mntp, specops, fifoops, vpp) struct mount *mntp; - struct vnodeops *specops, *fifoops; + int (**specops)(); + int (**fifoops)(); struct vnode **vpp; { struct inode *ip, *nip; @@ -1849,8 +1713,7 @@ ufs_vinit(mntp, specops, fifoops, vpp) * Allocate a new inode. */ int -ufs_makeinode(mode, dvp, vpp, cnp) /* converted to CN */ -/* OLD: ufs_makeinode(mode, ndp, vpp) */ +ufs_makeinode(mode, dvp, vpp, cnp) int mode; struct vnode *dvp; struct vnode **vpp; @@ -1861,7 +1724,7 @@ ufs_makeinode(mode, dvp, vpp, cnp) /* converted to CN */ int error; pdir = VTOI(dvp); -#ifdef DIANOSTIC +#ifdef DIAGNOSTIC if ((cnp->cn_flags & HASBUF) == 0) panic("ufs_makeinode: no name"); #endif @@ -1920,21 +1783,3 @@ bad: ufs_iput(ip); return (error); } - - -#if defined(JOHNH) && 0 -/* - * A hack to get the kernel to compile. - */ -int -hang_addrlist() -{ - return 0; -} -int -free_addrlist() -{ - return 0; -} -#endif -