Module Name: src Committed By: dholland Date: Sat May 17 07:09:09 UTC 2014
Modified Files: src/sys/ufs/lfs: lfs_vnops.c ulfs_vnops.c Log Message: Move the ulfs-level (copy of ufs) vnops for symlink, create, and mkdir into lfs_vnops.c preparatory to folding them into the lfs entry points. (lfs_vnops.c now has four licenses. sigh.) To generate a diff of this commit: cvs rdiff -u -r1.264 -r1.265 src/sys/ufs/lfs/lfs_vnops.c cvs rdiff -u -r1.20 -r1.21 src/sys/ufs/lfs/ulfs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/lfs/lfs_vnops.c diff -u src/sys/ufs/lfs/lfs_vnops.c:1.264 src/sys/ufs/lfs/lfs_vnops.c:1.265 --- src/sys/ufs/lfs/lfs_vnops.c:1.264 Sat May 17 07:08:35 2014 +++ src/sys/ufs/lfs/lfs_vnops.c Sat May 17 07:09:09 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: lfs_vnops.c,v 1.264 2014/05/17 07:08:35 dholland Exp $ */ +/* $NetBSD: lfs_vnops.c,v 1.265 2014/05/17 07:09:09 dholland Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc. @@ -59,8 +59,73 @@ * @(#)lfs_vnops.c 8.13 (Berkeley) 6/10/95 */ +/* from NetBSD: ufs_vnops.c,v 1.213 2013/06/08 05:47:02 kardel Exp */ +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1982, 1986, 1989, 1993, 1995 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ufs_vnops.c 8.28 (Berkeley) 7/31/95 + */ + #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.264 2014/05/17 07:08:35 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.265 2014/05/17 07:09:09 dholland Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -112,6 +177,14 @@ static int lfs_setextattr(void *v); static int lfs_listextattr(void *v); static int lfs_deleteextattr(void *v); +/* + * A virgin directory (no blushing please). + */ +static const struct lfs_dirtemplate mastertemplate = { + 0, 12, LFS_DT_DIR, 1, ".", + 0, LFS_DIRBLKSIZ - 12, LFS_DT_DIR, 2, ".." +}; + /* Global vfs data structures for lfs. */ int (**lfs_vnodeop_p)(void *); const struct vnodeopv_entry_desc lfs_vnodeop_entries[] = { @@ -537,6 +610,59 @@ lfs_unmark_vnode(struct vnode *vp) mutex_exit(&lfs_lock); } +/* + * symlink -- make a symbolic link + */ +int +ulfs_symlink(void *v) +{ + struct vop_symlink_v3_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + char *a_target; + } */ *ap = v; + struct vnode *vp, **vpp; + struct inode *ip; + int len, error; + struct ulfs_lookup_results *ulr; + + vpp = ap->a_vpp; + + /* XXX should handle this material another way */ + ulr = &VTOI(ap->a_dvp)->i_crap; + ULFS_CHECK_CRAPCOUNTER(VTOI(ap->a_dvp)); + + fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); + error = ulfs_makeinode(LFS_IFLNK | ap->a_vap->va_mode, ap->a_dvp, ulr, + vpp, ap->a_cnp); + if (error) + goto out; + VN_KNOTE(ap->a_dvp, NOTE_WRITE); + vp = *vpp; + len = strlen(ap->a_target); + ip = VTOI(vp); + if (len < ip->i_lfs->um_maxsymlinklen) { + memcpy((char *)SHORTLINK(ip), ap->a_target, len); + ip->i_size = len; + DIP_ASSIGN(ip, size, len); + uvm_vnp_setsize(vp, ip->i_size); + ip->i_flag |= IN_CHANGE | IN_UPDATE; + if (vp->v_mount->mnt_flag & MNT_RELATIME) + ip->i_flag |= IN_ACCESS; + } else + error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, + UIO_SYSSPACE, IO_NODELOCKED | IO_JOURNALLOCKED, + ap->a_cnp->cn_cred, NULL, NULL); + VOP_UNLOCK(vp); + if (error) + vrele(vp); +out: + fstrans_done(ap->a_dvp->v_mount); + return (error); +} + int lfs_symlink(void *v) { @@ -744,6 +870,40 @@ lfs_mknod(void *v) return (0); } +/* + * Create a regular file + */ +int +ulfs_create(void *v) +{ + struct vop_create_v3_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap = v; + int error; + struct vnode *dvp = ap->a_dvp; + struct ulfs_lookup_results *ulr; + + /* XXX should handle this material another way */ + ulr = &VTOI(dvp)->i_crap; + ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); + + fstrans_start(dvp->v_mount, FSTRANS_SHARED); + error = + ulfs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), + dvp, ulr, ap->a_vpp, ap->a_cnp); + if (error) { + fstrans_done(dvp->v_mount); + return (error); + } + fstrans_done(dvp->v_mount); + VN_KNOTE(dvp, NOTE_WRITE); + VOP_UNLOCK(*ap->a_vpp); + return (0); +} + int lfs_create(void *v) { @@ -808,6 +968,156 @@ lfs_create(void *v) } int +ulfs_mkdir(void *v) +{ + struct vop_mkdir_v3_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap = v; + struct vnode *dvp = ap->a_dvp, *tvp; + struct vattr *vap = ap->a_vap; + struct componentname *cnp = ap->a_cnp; + struct inode *ip, *dp = VTOI(dvp); + struct buf *bp; + struct lfs_dirtemplate dirtemplate; + struct lfs_direct *newdir; + int error, dmode; + struct ulfsmount *ump = dp->i_ump; + struct lfs *fs = ump->um_lfs; + int dirblksiz = fs->um_dirblksiz; + struct ulfs_lookup_results *ulr; + + fstrans_start(dvp->v_mount, FSTRANS_SHARED); + + /* XXX should handle this material another way */ + ulr = &dp->i_crap; + ULFS_CHECK_CRAPCOUNTER(dp); + + if ((nlink_t)dp->i_nlink >= LINK_MAX) { + error = EMLINK; + goto out; + } + dmode = vap->va_mode & ACCESSPERMS; + dmode |= LFS_IFDIR; + /* + * Must simulate part of ulfs_makeinode here to acquire the inode, + * but not have it entered in the parent directory. The entry is + * made later after writing "." and ".." entries. + */ + if ((error = lfs_valloc(dvp, dmode, cnp->cn_cred, ap->a_vpp)) != 0) + goto out; + + tvp = *ap->a_vpp; + ip = VTOI(tvp); + + ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); + DIP_ASSIGN(ip, uid, ip->i_uid); + ip->i_gid = dp->i_gid; + DIP_ASSIGN(ip, gid, ip->i_gid); +#if defined(LFS_QUOTA) || defined(LFS_QUOTA2) + if ((error = lfs_chkiq(ip, 1, cnp->cn_cred, 0))) { + lfs_vfree(tvp, ip->i_number, dmode); + fstrans_done(dvp->v_mount); + vput(tvp); + return (error); + } +#endif + ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; + ip->i_mode = dmode; + DIP_ASSIGN(ip, mode, dmode); + tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ + ip->i_nlink = 2; + DIP_ASSIGN(ip, nlink, 2); + if (cnp->cn_flags & ISWHITEOUT) { + ip->i_flags |= UF_OPAQUE; + DIP_ASSIGN(ip, flags, ip->i_flags); + } + + /* + * Bump link count in parent directory to reflect work done below. + * Should be done before reference is created so cleanup is + * possible if we crash. + */ + dp->i_nlink++; + DIP_ASSIGN(dp, nlink, dp->i_nlink); + dp->i_flag |= IN_CHANGE; + if ((error = lfs_update(dvp, NULL, NULL, UPDATE_DIROP)) != 0) + goto bad; + + /* + * Initialize directory with "." and ".." from static template. + */ + dirtemplate = mastertemplate; + dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen; + dirtemplate.dot_ino = ulfs_rw32(ip->i_number, ULFS_MPNEEDSWAP(fs)); + dirtemplate.dotdot_ino = ulfs_rw32(dp->i_number, ULFS_MPNEEDSWAP(fs)); + dirtemplate.dot_reclen = ulfs_rw16(dirtemplate.dot_reclen, + ULFS_MPNEEDSWAP(fs)); + dirtemplate.dotdot_reclen = ulfs_rw16(dirtemplate.dotdot_reclen, + ULFS_MPNEEDSWAP(fs)); + if (fs->um_maxsymlinklen <= 0) { +#if BYTE_ORDER == LITTLE_ENDIAN + if (ULFS_MPNEEDSWAP(fs) == 0) +#else + if (ULFS_MPNEEDSWAP(fs) != 0) +#endif + { + dirtemplate.dot_type = dirtemplate.dot_namlen; + dirtemplate.dotdot_type = dirtemplate.dotdot_namlen; + dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0; + } else + dirtemplate.dot_type = dirtemplate.dotdot_type = 0; + } + if ((error = lfs_balloc(tvp, (off_t)0, dirblksiz, cnp->cn_cred, + B_CLRBUF, &bp)) != 0) + goto bad; + ip->i_size = dirblksiz; + DIP_ASSIGN(ip, size, dirblksiz); + ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; + uvm_vnp_setsize(tvp, ip->i_size); + memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate); + + /* + * Directory set up, now install it's entry in the parent directory. + * We must write out the buffer containing the new directory body + * before entering the new name in the parent. + */ + if ((error = VOP_BWRITE(bp->b_vp, bp)) != 0) + goto bad; + if ((error = lfs_update(tvp, NULL, NULL, UPDATE_DIROP)) != 0) { + goto bad; + } + newdir = pool_cache_get(ulfs_direct_cache, PR_WAITOK); + ulfs_makedirentry(ip, cnp, newdir); + error = ulfs_direnter(dvp, ulr, tvp, newdir, cnp, bp); + pool_cache_put(ulfs_direct_cache, newdir); + bad: + if (error == 0) { + VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); + VOP_UNLOCK(tvp); + } else { + dp->i_nlink--; + DIP_ASSIGN(dp, nlink, dp->i_nlink); + dp->i_flag |= IN_CHANGE; + /* + * No need to do an explicit lfs_truncate here, vrele will + * do this for us because we set the link count to 0. + */ + ip->i_nlink = 0; + DIP_ASSIGN(ip, nlink, 0); + ip->i_flag |= IN_CHANGE; + /* If IN_ADIROP, account for it */ + lfs_unmark_vnode(tvp); + vput(tvp); + } + out: + fstrans_done(dvp->v_mount); + return (error); +} + +int lfs_mkdir(void *v) { struct vop_mkdir_v3_args /* { @@ -959,11 +1269,10 @@ lfs_link(void *v) struct componentname *a_cnp; } */ *ap = v; struct lfs *fs; - struct vnode *dvp, **vpp; + struct vnode *dvp; int error; dvp = ap->a_dvp; - vpp = NULL; fs = VFSTOULFS(dvp->v_mount)->um_lfs; ASSERT_NO_SEGLOCK(fs); Index: src/sys/ufs/lfs/ulfs_vnops.c diff -u src/sys/ufs/lfs/ulfs_vnops.c:1.20 src/sys/ufs/lfs/ulfs_vnops.c:1.21 --- src/sys/ufs/lfs/ulfs_vnops.c:1.20 Thu Jan 23 10:13:57 2014 +++ src/sys/ufs/lfs/ulfs_vnops.c Sat May 17 07:09:09 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_vnops.c,v 1.20 2014/01/23 10:13:57 hannken Exp $ */ +/* $NetBSD: ulfs_vnops.c,v 1.21 2014/05/17 07:09:09 dholland Exp $ */ /* from NetBSD: ufs_vnops.c,v 1.213 2013/06/08 05:47:02 kardel Exp */ /*- @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.20 2014/01/23 10:13:57 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.21 2014/05/17 07:09:09 dholland Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -114,48 +114,6 @@ static int ulfs_chown(struct vnode *, ui struct lwp *); /* - * A virgin directory (no blushing please). - */ -static const struct lfs_dirtemplate mastertemplate = { - 0, 12, LFS_DT_DIR, 1, ".", - 0, LFS_DIRBLKSIZ - 12, LFS_DT_DIR, 2, ".." -}; - -/* - * Create a regular file - */ -int -ulfs_create(void *v) -{ - struct vop_create_v3_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap = v; - int error; - struct vnode *dvp = ap->a_dvp; - struct ulfs_lookup_results *ulr; - - /* XXX should handle this material another way */ - ulr = &VTOI(dvp)->i_crap; - ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); - - fstrans_start(dvp->v_mount, FSTRANS_SHARED); - error = - ulfs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), - dvp, ulr, ap->a_vpp, ap->a_cnp); - if (error) { - fstrans_done(dvp->v_mount); - return (error); - } - fstrans_done(dvp->v_mount); - VN_KNOTE(dvp, NOTE_WRITE); - VOP_UNLOCK(*ap->a_vpp); - return (0); -} - -/* * Open called. * * Nothing to do. @@ -713,156 +671,6 @@ ulfs_whiteout(void *v) } int -ulfs_mkdir(void *v) -{ - struct vop_mkdir_v3_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap = v; - struct vnode *dvp = ap->a_dvp, *tvp; - struct vattr *vap = ap->a_vap; - struct componentname *cnp = ap->a_cnp; - struct inode *ip, *dp = VTOI(dvp); - struct buf *bp; - struct lfs_dirtemplate dirtemplate; - struct lfs_direct *newdir; - int error, dmode; - struct ulfsmount *ump = dp->i_ump; - struct lfs *fs = ump->um_lfs; - int dirblksiz = fs->um_dirblksiz; - struct ulfs_lookup_results *ulr; - - fstrans_start(dvp->v_mount, FSTRANS_SHARED); - - /* XXX should handle this material another way */ - ulr = &dp->i_crap; - ULFS_CHECK_CRAPCOUNTER(dp); - - if ((nlink_t)dp->i_nlink >= LINK_MAX) { - error = EMLINK; - goto out; - } - dmode = vap->va_mode & ACCESSPERMS; - dmode |= LFS_IFDIR; - /* - * Must simulate part of ulfs_makeinode here to acquire the inode, - * but not have it entered in the parent directory. The entry is - * made later after writing "." and ".." entries. - */ - if ((error = lfs_valloc(dvp, dmode, cnp->cn_cred, ap->a_vpp)) != 0) - goto out; - - tvp = *ap->a_vpp; - ip = VTOI(tvp); - - ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); - DIP_ASSIGN(ip, uid, ip->i_uid); - ip->i_gid = dp->i_gid; - DIP_ASSIGN(ip, gid, ip->i_gid); -#if defined(LFS_QUOTA) || defined(LFS_QUOTA2) - if ((error = lfs_chkiq(ip, 1, cnp->cn_cred, 0))) { - lfs_vfree(tvp, ip->i_number, dmode); - fstrans_done(dvp->v_mount); - vput(tvp); - return (error); - } -#endif - ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_mode = dmode; - DIP_ASSIGN(ip, mode, dmode); - tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ - ip->i_nlink = 2; - DIP_ASSIGN(ip, nlink, 2); - if (cnp->cn_flags & ISWHITEOUT) { - ip->i_flags |= UF_OPAQUE; - DIP_ASSIGN(ip, flags, ip->i_flags); - } - - /* - * Bump link count in parent directory to reflect work done below. - * Should be done before reference is created so cleanup is - * possible if we crash. - */ - dp->i_nlink++; - DIP_ASSIGN(dp, nlink, dp->i_nlink); - dp->i_flag |= IN_CHANGE; - if ((error = lfs_update(dvp, NULL, NULL, UPDATE_DIROP)) != 0) - goto bad; - - /* - * Initialize directory with "." and ".." from static template. - */ - dirtemplate = mastertemplate; - dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen; - dirtemplate.dot_ino = ulfs_rw32(ip->i_number, ULFS_MPNEEDSWAP(fs)); - dirtemplate.dotdot_ino = ulfs_rw32(dp->i_number, ULFS_MPNEEDSWAP(fs)); - dirtemplate.dot_reclen = ulfs_rw16(dirtemplate.dot_reclen, - ULFS_MPNEEDSWAP(fs)); - dirtemplate.dotdot_reclen = ulfs_rw16(dirtemplate.dotdot_reclen, - ULFS_MPNEEDSWAP(fs)); - if (fs->um_maxsymlinklen <= 0) { -#if BYTE_ORDER == LITTLE_ENDIAN - if (ULFS_MPNEEDSWAP(fs) == 0) -#else - if (ULFS_MPNEEDSWAP(fs) != 0) -#endif - { - dirtemplate.dot_type = dirtemplate.dot_namlen; - dirtemplate.dotdot_type = dirtemplate.dotdot_namlen; - dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0; - } else - dirtemplate.dot_type = dirtemplate.dotdot_type = 0; - } - if ((error = lfs_balloc(tvp, (off_t)0, dirblksiz, cnp->cn_cred, - B_CLRBUF, &bp)) != 0) - goto bad; - ip->i_size = dirblksiz; - DIP_ASSIGN(ip, size, dirblksiz); - ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - uvm_vnp_setsize(tvp, ip->i_size); - memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate); - - /* - * Directory set up, now install it's entry in the parent directory. - * We must write out the buffer containing the new directory body - * before entering the new name in the parent. - */ - if ((error = VOP_BWRITE(bp->b_vp, bp)) != 0) - goto bad; - if ((error = lfs_update(tvp, NULL, NULL, UPDATE_DIROP)) != 0) { - goto bad; - } - newdir = pool_cache_get(ulfs_direct_cache, PR_WAITOK); - ulfs_makedirentry(ip, cnp, newdir); - error = ulfs_direnter(dvp, ulr, tvp, newdir, cnp, bp); - pool_cache_put(ulfs_direct_cache, newdir); - bad: - if (error == 0) { - VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK); - VOP_UNLOCK(tvp); - } else { - dp->i_nlink--; - DIP_ASSIGN(dp, nlink, dp->i_nlink); - dp->i_flag |= IN_CHANGE; - /* - * No need to do an explicit lfs_truncate here, vrele will - * do this for us because we set the link count to 0. - */ - ip->i_nlink = 0; - DIP_ASSIGN(ip, nlink, 0); - ip->i_flag |= IN_CHANGE; - /* If IN_ADIROP, account for it */ - lfs_unmark_vnode(tvp); - vput(tvp); - } - out: - fstrans_done(dvp->v_mount); - return (error); -} - -int ulfs_rmdir(void *v) { struct vop_rmdir_args /* { @@ -954,59 +762,6 @@ ulfs_rmdir(void *v) } /* - * symlink -- make a symbolic link - */ -int -ulfs_symlink(void *v) -{ - struct vop_symlink_v3_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - char *a_target; - } */ *ap = v; - struct vnode *vp, **vpp; - struct inode *ip; - int len, error; - struct ulfs_lookup_results *ulr; - - vpp = ap->a_vpp; - - /* XXX should handle this material another way */ - ulr = &VTOI(ap->a_dvp)->i_crap; - ULFS_CHECK_CRAPCOUNTER(VTOI(ap->a_dvp)); - - fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); - error = ulfs_makeinode(LFS_IFLNK | ap->a_vap->va_mode, ap->a_dvp, ulr, - vpp, ap->a_cnp); - if (error) - goto out; - VN_KNOTE(ap->a_dvp, NOTE_WRITE); - vp = *vpp; - len = strlen(ap->a_target); - ip = VTOI(vp); - if (len < ip->i_lfs->um_maxsymlinklen) { - memcpy((char *)SHORTLINK(ip), ap->a_target, len); - ip->i_size = len; - DIP_ASSIGN(ip, size, len); - uvm_vnp_setsize(vp, ip->i_size); - ip->i_flag |= IN_CHANGE | IN_UPDATE; - if (vp->v_mount->mnt_flag & MNT_RELATIME) - ip->i_flag |= IN_ACCESS; - } else - error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0, - UIO_SYSSPACE, IO_NODELOCKED | IO_JOURNALLOCKED, - ap->a_cnp->cn_cred, NULL, NULL); - VOP_UNLOCK(vp); - if (error) - vrele(vp); -out: - fstrans_done(ap->a_dvp->v_mount); - return (error); -} - -/* * Vnode op for reading directories. * * This routine handles converting from the on-disk directory format