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