+ return (error);
+}
+
+/*
+ * symlink -- make a symbolic link
+ */
+ufs_symlink(ndp, vap, target)
+ struct nameidata *ndp;
+ struct vattr *vap;
+ char *target;
+{
+ struct inode *ip;
+ int error;
+
+ error = maknode(IFLNK | vap->va_mode, ndp, &ip);
+ if (error)
+ return (error);
+ error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0,
+ UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0);
+ iput(ip);
+ return (error);
+}
+
+/*
+ * Vnode op for read and write
+ */
+ufs_readdir(vp, uio, cred)
+ struct vnode *vp;
+ register struct uio *uio;
+ struct ucred *cred;
+{
+ int count, lost, error;
+
+ count = uio->uio_resid;
+ count &= ~(DIRBLKSIZ - 1);
+ lost = uio->uio_resid - count;
+ if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1)))
+ return (EINVAL);
+ uio->uio_resid = count;
+ uio->uio_iov->iov_len = count;
+ error = ufs_read(vp, uio, 0, cred);
+ uio->uio_resid += lost;
+ return (error);
+}
+
+/*
+ * Return target name of a symbolic link
+ */
+ufs_readlink(vp, uiop, cred)
+ struct vnode *vp;
+ struct uio *uiop;
+ struct ucred *cred;
+{
+
+ return (ufs_read(vp, uiop, 0, cred));
+}
+
+/*
+ * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
+ * done. Iff ni_vp/ni_dvp not null and locked, unlock.
+ */
+ufs_abortop(ndp)
+ register struct nameidata *ndp;
+{
+ register struct inode *ip;
+
+ if (ndp->ni_vp) {
+ ip = VTOI(ndp->ni_vp);
+ if (ip->i_flag & ILOCKED)
+ IUNLOCK(ip);
+ vrele(ndp->ni_vp);
+ }
+ if (ndp->ni_dvp) {
+ ip = VTOI(ndp->ni_dvp);
+ if (ip->i_flag & ILOCKED)
+ IUNLOCK(ip);
+ vrele(ndp->ni_dvp);
+ }
+ return;
+}
+
+ufs_lock(vp)
+ struct vnode *vp;
+{
+ register struct inode *ip = VTOI(vp);
+
+ ILOCK(ip);
+ return (0);
+}
+
+ufs_unlock(vp)
+ struct vnode *vp;
+{
+ register struct inode *ip = VTOI(vp);
+
+ if (!(ip->i_flag & ILOCKED))
+ panic("ufs_unlock NOT LOCKED");
+ IUNLOCK(ip);
+ return (0);