Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/ufs/lfs/ulfs_vnops.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/ufs/lfs/ulfs_vnops.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.21 retrieving revision 1.21.6.2 diff -u -p -r1.21 -r1.21.6.2 --- src/sys/ufs/lfs/ulfs_vnops.c 2014/05/17 07:09:09 1.21 +++ src/sys/ufs/lfs/ulfs_vnops.c 2015/06/06 14:40:31 1.21.6.2 @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_vnops.c,v 1.21 2014/05/17 07:09:09 dholland Exp $ */ +/* $NetBSD: ulfs_vnops.c,v 1.21.6.2 2015/06/06 14:40:31 skrll Exp $ */ /* from NetBSD: ufs_vnops.c,v 1.213 2013/06/08 05:47:02 kardel Exp */ /*- @@ -67,7 +67,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.21 2014/05/17 07:09:09 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.21.6.2 2015/06/06 14:40:31 skrll Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -502,18 +502,21 @@ ulfs_remove(void *v) } */ *ap = v; struct vnode *vp, *dvp; struct inode *ip; + struct mount *mp; int error; struct ulfs_lookup_results *ulr; vp = ap->a_vp; dvp = ap->a_dvp; ip = VTOI(vp); + mp = dvp->v_mount; + KASSERT(mp == vp->v_mount); /* XXX Not stable without lock. */ /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); - fstrans_start(dvp->v_mount, FSTRANS_SHARED); + fstrans_start(mp, FSTRANS_SHARED); if (vp->v_type == VDIR || (ip->i_flags & (IMMUTABLE | APPEND)) || (VTOI(dvp)->i_flags & APPEND)) error = EPERM; @@ -528,7 +531,7 @@ ulfs_remove(void *v) else vput(vp); vput(dvp); - fstrans_done(dvp->v_mount); + fstrans_done(mp); return (error); } @@ -538,7 +541,7 @@ ulfs_remove(void *v) int ulfs_link(void *v) { - struct vop_link_args /* { + struct vop_link_v2_args /* { struct vnode *a_dvp; struct vnode *a_vp; struct componentname *a_cnp; @@ -546,6 +549,7 @@ ulfs_link(void *v) struct vnode *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; struct componentname *cnp = ap->a_cnp; + struct mount *mp = dvp->v_mount; struct inode *ip; struct lfs_direct *newdir; int error; @@ -553,13 +557,13 @@ ulfs_link(void *v) KASSERT(dvp != vp); KASSERT(vp->v_type != VDIR); - KASSERT(dvp->v_mount == vp->v_mount); + KASSERT(mp == vp->v_mount); /* XXX Not stable without lock. */ /* XXX should handle this material another way */ ulr = &VTOI(dvp)->i_crap; ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); - fstrans_start(dvp->v_mount, FSTRANS_SHARED); + fstrans_start(mp, FSTRANS_SHARED); error = vn_lock(vp, LK_EXCLUSIVE); if (error) { VOP_ABORTOP(dvp, cnp); @@ -596,8 +600,7 @@ ulfs_link(void *v) out2: VN_KNOTE(vp, NOTE_LINK); VN_KNOTE(dvp, NOTE_WRITE); - vput(dvp); - fstrans_done(dvp->v_mount); + fstrans_done(mp); return (error); } @@ -934,7 +937,7 @@ ulfs_readlink(void *v) uiomove((char *)SHORTLINK(ip), isize, ap->a_uio); return (0); } - return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); + return (lfs_bufrd(vp, ap->a_uio, 0, ap->a_cred)); } /* @@ -1171,39 +1174,27 @@ ulfs_vinit(struct mount *mntp, int (**sp * Allocate a new inode. */ int -ulfs_makeinode(int mode, struct vnode *dvp, const struct ulfs_lookup_results *ulr, +ulfs_makeinode(struct vattr *vap, struct vnode *dvp, + const struct ulfs_lookup_results *ulr, struct vnode **vpp, struct componentname *cnp) { - struct inode *ip, *pdir; + struct inode *ip; struct lfs_direct *newdir; struct vnode *tvp; int error; - pdir = VTOI(dvp); - - if ((mode & LFS_IFMT) == 0) - mode |= LFS_IFREG; - - if ((error = lfs_valloc(dvp, mode, cnp->cn_cred, vpp)) != 0) { - return (error); + error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, &tvp); + if (error) + return error; + error = vn_lock(tvp, LK_EXCLUSIVE); + if (error) { + vrele(tvp); + return error; } - tvp = *vpp; + lfs_mark_vnode(tvp); + *vpp = tvp; ip = VTOI(tvp); - ip->i_gid = pdir->i_gid; - DIP_ASSIGN(ip, gid, ip->i_gid); - ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); - DIP_ASSIGN(ip, uid, ip->i_uid); -#if defined(LFS_QUOTA) || defined(LFS_QUOTA2) - if ((error = lfs_chkiq(ip, 1, cnp->cn_cred, 0))) { - lfs_vfree(tvp, ip->i_number, mode); - vput(tvp); - return (error); - } -#endif ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_mode = mode; - DIP_ASSIGN(ip, mode, mode); - tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ ip->i_nlink = 1; DIP_ASSIGN(ip, nlink, 1); @@ -1211,7 +1202,7 @@ ulfs_makeinode(int mode, struct vnode *d if (ip->i_mode & ISGID) { error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_WRITE_SECURITY, tvp, NULL, genfs_can_chmod(tvp->v_type, cnp->cn_cred, ip->i_uid, - ip->i_gid, mode)); + ip->i_gid, MAKEIMODE(vap->va_type, vap->va_mode))); if (error) { ip->i_mode &= ~ISGID; DIP_ASSIGN(ip, mode, ip->i_mode); @@ -1247,7 +1238,6 @@ ulfs_makeinode(int mode, struct vnode *d ip->i_flag |= IN_CHANGE; /* If IN_ADIROP, account for it */ lfs_unmark_vnode(tvp); - tvp->v_type = VNON; /* explodes later if VBLK */ vput(tvp); return (error); } @@ -1320,3 +1310,45 @@ ulfs_gop_markupdate(struct vnode *vp, in ip->i_flag |= mask; } } + +int +ulfs_bufio(enum uio_rw rw, struct vnode *vp, void *buf, size_t len, off_t off, + int ioflg, kauth_cred_t cred, size_t *aresid, struct lwp *l) +{ + struct iovec iov; + struct uio uio; + int error; + + KASSERT(ISSET(ioflg, IO_NODELOCKED)); + KASSERT(VOP_ISLOCKED(vp)); + KASSERT(rw != UIO_WRITE || VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + + iov.iov_base = buf; + iov.iov_len = len; + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_resid = len; + uio.uio_offset = off; + uio.uio_rw = rw; + UIO_SETUP_SYSSPACE(&uio); + + switch (rw) { + case UIO_READ: + error = lfs_bufrd(vp, &uio, ioflg, cred); + break; + case UIO_WRITE: + error = lfs_bufwr(vp, &uio, ioflg, cred); + break; + default: + panic("invalid uio rw: %d", (int)rw); + } + + if (aresid) + *aresid = uio.uio_resid; + else if (uio.uio_resid && error == 0) + error = EIO; + + KASSERT(VOP_ISLOCKED(vp)); + KASSERT(rw != UIO_WRITE || VOP_ISLOCKED(vp) == LK_EXCLUSIVE); + return error; +}