[XFS] cleanup fid types mess
[sfrench/cifs-2.6.git] / fs / xfs / xfs_vnodeops.c
index 70bc82f65311e3b2a57a7cda2fd292256f8201f6..efd5aff9eaf6aa1d149fa6431ca6355e944c5b1a 100644 (file)
 #include "xfs_refcache.h"
 #include "xfs_trans_space.h"
 #include "xfs_log_priv.h"
+#include "xfs_filestream.h"
+#include "xfs_vnodeops.h"
 
-STATIC int
+int
 xfs_open(
-       bhv_desc_t      *bdp,
-       cred_t          *credp)
+       xfs_inode_t     *ip)
 {
        int             mode;
-       bhv_vnode_t     *vp = BHV_TO_VNODE(bdp);
-       xfs_inode_t     *ip = XFS_BHVTOI(bdp);
 
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
                return XFS_ERROR(EIO);
@@ -68,7 +67,7 @@ xfs_open(
         * If it's a directory with any blocks, read-ahead block 0
         * as we're almost certain to have the next operation be a read there.
         */
-       if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) {
+       if (S_ISDIR(ip->i_d.di_mode) && ip->i_d.di_nextents > 0) {
                mode = xfs_ilock_map_shared(ip);
                if (ip->i_d.di_nextents > 0)
                        (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK);
@@ -77,55 +76,19 @@ xfs_open(
        return 0;
 }
 
-STATIC int
-xfs_close(
-       bhv_desc_t      *bdp,
-       int             flags,
-       lastclose_t     lastclose,
-       cred_t          *credp)
-{
-       bhv_vnode_t     *vp = BHV_TO_VNODE(bdp);
-       xfs_inode_t     *ip = XFS_BHVTOI(bdp);
-
-       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
-               return XFS_ERROR(EIO);
-
-       if (lastclose != L_TRUE || !VN_ISREG(vp))
-               return 0;
-
-       /*
-        * If we previously truncated this file and removed old data in
-        * the process, we want to initiate "early" writeout on the last
-        * close.  This is an attempt to combat the notorious NULL files
-        * problem which is particularly noticable from a truncate down,
-        * buffered (re-)write (delalloc), followed by a crash.  What we
-        * are effectively doing here is significantly reducing the time
-        * window where we'd otherwise be exposed to that problem.
-        */
-       if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
-               return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE);
-       return 0;
-}
-
 /*
  * xfs_getattr
  */
-STATIC int
+int
 xfs_getattr(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        bhv_vattr_t     *vap,
-       int             flags,
-       cred_t          *credp)
+       int             flags)
 {
-       xfs_inode_t     *ip;
-       xfs_mount_t     *mp;
-       bhv_vnode_t     *vp;
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
+       xfs_mount_t     *mp = ip->i_mount;
 
-       vp  = BHV_TO_VNODE(bdp);
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
@@ -183,9 +146,8 @@ xfs_getattr(
                         * realtime extent size or the realtime volume's
                         * extent size.
                         */
-                       vap->va_blocksize = ip->i_d.di_extsize ?
-                               (ip->i_d.di_extsize << mp->m_sb.sb_blocklog) :
-                               (mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog);
+                       vap->va_blocksize =
+                               xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog;
                }
                break;
        }
@@ -245,14 +207,14 @@ xfs_getattr(
  */
 int
 xfs_setattr(
-       bhv_desc_t              *bdp,
+       xfs_inode_t             *ip,
        bhv_vattr_t             *vap,
        int                     flags,
        cred_t                  *credp)
 {
-       xfs_inode_t             *ip;
+       bhv_vnode_t             *vp = XFS_ITOV(ip);
+       xfs_mount_t             *mp = ip->i_mount;
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
        int                     mask;
        int                     code;
        uint                    lock_flags;
@@ -260,17 +222,15 @@ xfs_setattr(
        uid_t                   uid=0, iuid=0;
        gid_t                   gid=0, igid=0;
        int                     timeflags = 0;
-       bhv_vnode_t             *vp;
        xfs_prid_t              projid=0, iprojid=0;
        int                     mandlock_before, mandlock_after;
        struct xfs_dquot        *udqp, *gdqp, *olddquot1, *olddquot2;
        int                     file_owner;
        int                     need_iolock = 1;
 
-       vp = BHV_TO_VNODE(bdp);
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
-       if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+       if (mp->m_flags & XFS_MOUNT_RDONLY)
                return XFS_ERROR(EROFS);
 
        /*
@@ -281,9 +241,6 @@ xfs_setattr(
                return XFS_ERROR(EINVAL);
        }
 
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
-
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
@@ -367,7 +324,7 @@ xfs_setattr(
                        }
                }
        } else {
-               if (DM_EVENT_ENABLED (vp->v_vfsp, ip, DM_EVENT_TRUNCATE) &&
+               if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
                    !(flags & ATTR_DMI)) {
                        int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
                        code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, vp,
@@ -619,7 +576,30 @@ xfs_setattr(
                        code = xfs_igrow_start(ip, vap->va_size, credp);
                }
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
-               vn_iowait(vp); /* wait for the completion of any pending DIOs */
+
+               /*
+                * We are going to log the inode size change in this
+                * transaction so any previous writes that are beyond the on
+                * disk EOF and the new EOF that have not been written out need
+                * to be written here. If we do not write the data out, we
+                * expose ourselves to the null files problem.
+                *
+                * Only flush from the on disk size to the smaller of the in
+                * memory file size or the new size as that's the range we
+                * really care about here and prevents waiting for other data
+                * not within the range we care about here.
+                */
+               if (!code &&
+                   (ip->i_size != ip->i_d.di_size) &&
+                   (vap->va_size > ip->i_d.di_size)) {
+                       code = xfs_flush_pages(ip,
+                                       ip->i_d.di_size, vap->va_size,
+                                       XFS_B_ASYNC, FI_NONE);
+               }
+
+               /* wait for all I/O to complete */
+               vn_iowait(ip);
+
                if (!code)
                        code = xfs_itruncate_data(ip, vap->va_size);
                if (code) {
@@ -680,7 +660,7 @@ xfs_setattr(
                         * vnode and flush it when the file is closed, and
                         * do not wait the usual (long) time for writeout.
                         */
-                       VTRUNCATE(vp);
+                       xfs_iflags_set(ip, XFS_ITRUNCATED);
                }
                /*
                 * Have to do this even if the file's size doesn't change.
@@ -814,6 +794,8 @@ xfs_setattr(
                                di_flags |= XFS_DIFLAG_PROJINHERIT;
                        if (vap->va_xflags & XFS_XFLAG_NODEFRAG)
                                di_flags |= XFS_DIFLAG_NODEFRAG;
+                       if (vap->va_xflags & XFS_XFLAG_FILESTREAM)
+                               di_flags |= XFS_DIFLAG_FILESTREAM;
                        if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
                                if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
                                        di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -882,10 +864,6 @@ xfs_setattr(
         * racing calls to vop_vnode_change.
         */
        mandlock_after = MANDLOCK(vp, ip->i_d.di_mode);
-       if (mandlock_before != mandlock_after) {
-               bhv_vop_vnode_change(vp, VCHANGE_FLAGS_ENF_LOCKING,
-                                mandlock_after);
-       }
 
        xfs_iunlock(ip, lock_flags);
 
@@ -901,7 +879,7 @@ xfs_setattr(
                return code;
        }
 
-       if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_ATTRIBUTE) &&
+       if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
            !(flags & ATTR_DMI)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, vp, DM_RIGHT_NULL,
                                        NULL, DM_RIGHT_NULL, NULL, NULL,
@@ -929,19 +907,16 @@ xfs_setattr(
  * xfs_access
  * Null conversion from vnode mode bits to inode mode bits, as in efs.
  */
-STATIC int
+int
 xfs_access(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        int             mode,
        cred_t          *credp)
 {
-       xfs_inode_t     *ip;
        int             error;
 
-       vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
-                                              (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
-       ip = XFS_BHVTOI(bdp);
        xfs_ilock(ip, XFS_ILOCK_SHARED);
        error = xfs_iaccess(ip, mode, credp);
        xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -956,105 +931,88 @@ xfs_access(
  */
 #define SYMLINK_MAPS 2
 
-/*
- * xfs_readlink
- *
- */
 STATIC int
-xfs_readlink(
-       bhv_desc_t      *bdp,
-       uio_t           *uiop,
-       int             ioflags,
-       cred_t          *credp)
+xfs_readlink_bmap(
+       xfs_inode_t     *ip,
+       char            *link)
 {
-       xfs_inode_t     *ip;
-       int             count;
-       xfs_off_t       offset;
-       int             pathlen;
-       bhv_vnode_t     *vp;
-       int             error = 0;
-       xfs_mount_t     *mp;
-       int             nmaps;
+       xfs_mount_t     *mp = ip->i_mount;
+       int             pathlen = ip->i_d.di_size;
+       int             nmaps = SYMLINK_MAPS;
        xfs_bmbt_irec_t mval[SYMLINK_MAPS];
        xfs_daddr_t     d;
        int             byte_cnt;
        int             n;
        xfs_buf_t       *bp;
+       int             error = 0;
 
-       vp = BHV_TO_VNODE(bdp);
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
+       error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0,
+                       mval, &nmaps, NULL, NULL);
+       if (error)
+               goto out;
 
-       if (XFS_FORCED_SHUTDOWN(mp))
-               return XFS_ERROR(EIO);
+       for (n = 0; n < nmaps; n++) {
+               d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
+               byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 
-       xfs_ilock(ip, XFS_ILOCK_SHARED);
+               bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
+               error = XFS_BUF_GETERROR(bp);
+               if (error) {
+                       xfs_ioerror_alert("xfs_readlink",
+                                 ip->i_mount, bp, XFS_BUF_ADDR(bp));
+                       xfs_buf_relse(bp);
+                       goto out;
+               }
+               if (pathlen < byte_cnt)
+                       byte_cnt = pathlen;
+               pathlen -= byte_cnt;
 
-       ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
+               memcpy(link, XFS_BUF_PTR(bp), byte_cnt);
+               xfs_buf_relse(bp);
+       }
 
-       offset = uiop->uio_offset;
-       count = uiop->uio_resid;
+       link[ip->i_d.di_size] = '\0';
+       error = 0;
 
-       if (offset < 0) {
-               error = XFS_ERROR(EINVAL);
-               goto error_return;
-       }
-       if (count <= 0) {
-               error = 0;
-               goto error_return;
-       }
+ out:
+       return error;
+}
 
-       /*
-        * See if the symlink is stored inline.
-        */
-       pathlen = (int)ip->i_d.di_size;
+int
+xfs_readlink(
+       xfs_inode_t     *ip,
+       char            *link)
+{
+       xfs_mount_t     *mp = ip->i_mount;
+       int             pathlen;
+       int             error = 0;
 
-       if (ip->i_df.if_flags & XFS_IFINLINE) {
-               error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop);
-       }
-       else {
-               /*
-                * Symlink not inline.  Call bmap to get it in.
-                */
-               nmaps = SYMLINK_MAPS;
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
-               error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen),
-                                 0, NULL, 0, mval, &nmaps, NULL, NULL);
+       if (XFS_FORCED_SHUTDOWN(mp))
+               return XFS_ERROR(EIO);
 
-               if (error) {
-                       goto error_return;
-               }
+       xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-               for (n = 0; n < nmaps; n++) {
-                       d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
-                       byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
-                       bp = xfs_buf_read(mp->m_ddev_targp, d,
-                                     BTOBB(byte_cnt), 0);
-                       error = XFS_BUF_GETERROR(bp);
-                       if (error) {
-                               xfs_ioerror_alert("xfs_readlink",
-                                         ip->i_mount, bp, XFS_BUF_ADDR(bp));
-                               xfs_buf_relse(bp);
-                               goto error_return;
-                       }
-                       if (pathlen < byte_cnt)
-                               byte_cnt = pathlen;
-                       pathlen -= byte_cnt;
+       ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFLNK);
+       ASSERT(ip->i_d.di_size <= MAXPATHLEN);
 
-                       error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop);
-                       xfs_buf_relse (bp);
-               }
+       pathlen = ip->i_d.di_size;
+       if (!pathlen)
+               goto out;
 
+       if (ip->i_df.if_flags & XFS_IFINLINE) {
+               memcpy(link, ip->i_df.if_u1.if_data, pathlen);
+               link[pathlen] = '\0';
+       } else {
+               error = xfs_readlink_bmap(ip, link);
        }
 
-error_return:
+ out:
        xfs_iunlock(ip, XFS_ILOCK_SHARED);
        return error;
 }
 
-
 /*
  * xfs_fsync
  *
@@ -1064,29 +1022,27 @@ error_return:
  * be held while flushing the data, so acquire after we're done
  * with that.
  */
-STATIC int
+int
 xfs_fsync(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        int             flag,
-       cred_t          *credp,
        xfs_off_t       start,
        xfs_off_t       stop)
 {
-       xfs_inode_t     *ip;
        xfs_trans_t     *tp;
        int             error;
        int             log_flushed = 0, changed = 1;
 
-       vn_trace_entry(BHV_TO_VNODE(bdp),
-                       __FUNCTION__, (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        ASSERT(start >= 0 && stop >= -1);
 
        if (XFS_FORCED_SHUTDOWN(ip->i_mount))
                return XFS_ERROR(EIO);
 
+       if (flag & FSYNC_DATA)
+               filemap_fdatawait(vn_to_inode(XFS_ITOV(ip))->i_mapping);
+
        /*
         * We always need to make sure that the required inode state
         * is safe on disk.  The vnode might be clean but because
@@ -1201,13 +1157,15 @@ xfs_fsync(
 }
 
 /*
- * This is called by xfs_inactive to free any blocks beyond eof,
- * when the link count isn't zero.
+ * This is called by xfs_inactive to free any blocks beyond eof
+ * when the link count isn't zero and by xfs_dm_punch_hole() when
+ * punching a hole to EOF.
  */
-STATIC int
-xfs_inactive_free_eofblocks(
+int
+xfs_free_eofblocks(
        xfs_mount_t     *mp,
-       xfs_inode_t     *ip)
+       xfs_inode_t     *ip,
+       int             flags)
 {
        xfs_trans_t     *tp;
        int             error;
@@ -1216,6 +1174,7 @@ xfs_inactive_free_eofblocks(
        xfs_filblks_t   map_len;
        int             nimaps;
        xfs_bmbt_irec_t imap;
+       int             use_iolock = (flags & XFS_FREE_EOF_LOCK);
 
        /*
         * Figure out if there are any blocks beyond the end
@@ -1256,11 +1215,14 @@ xfs_inactive_free_eofblocks(
                 * cache and we can't
                 * do that within a transaction.
                 */
-               xfs_ilock(ip, XFS_IOLOCK_EXCL);
+               if (use_iolock)
+                       xfs_ilock(ip, XFS_IOLOCK_EXCL);
                error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
                                    ip->i_size);
                if (error) {
-                       xfs_iunlock(ip, XFS_IOLOCK_EXCL);
+                       xfs_trans_cancel(tp, 0);
+                       if (use_iolock)
+                               xfs_iunlock(ip, XFS_IOLOCK_EXCL);
                        return error;
                }
 
@@ -1297,7 +1259,8 @@ xfs_inactive_free_eofblocks(
                        error = xfs_trans_commit(tp,
                                                XFS_TRANS_RELEASE_LOG_RES);
                }
-               xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
+               xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL)
+                                           : XFS_ILOCK_EXCL));
        }
        return error;
 }
@@ -1540,26 +1503,49 @@ xfs_inactive_attrs(
        return 0;
 }
 
-STATIC int
+int
 xfs_release(
-       bhv_desc_t      *bdp)
+       xfs_inode_t     *ip)
 {
-       xfs_inode_t     *ip;
-       bhv_vnode_t     *vp;
-       xfs_mount_t     *mp;
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
+       xfs_mount_t     *mp = ip->i_mount;
        int             error;
 
-       vp = BHV_TO_VNODE(bdp);
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
-
        if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0))
                return 0;
 
        /* If this is a read-only mount, don't do this (would generate I/O) */
-       if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+       if (mp->m_flags & XFS_MOUNT_RDONLY)
                return 0;
 
+       if (!XFS_FORCED_SHUTDOWN(mp)) {
+               int truncated;
+
+               /*
+                * If we are using filestreams, and we have an unlinked
+                * file that we are processing the last close on, then nothing
+                * will be able to reopen and write to this file. Purge this
+                * inode from the filestreams cache so that it doesn't delay
+                * teardown of the inode.
+                */
+               if ((ip->i_d.di_nlink == 0) && xfs_inode_is_filestream(ip))
+                       xfs_filestream_deassociate(ip);
+
+               /*
+                * If we previously truncated this file and removed old data
+                * in the process, we want to initiate "early" writeout on
+                * the last close.  This is an attempt to combat the notorious
+                * NULL files problem which is particularly noticable from a
+                * truncate down, buffered (re-)write (delalloc), followed by
+                * a crash.  What we are effectively doing here is
+                * significantly reducing the time window where we'd otherwise
+                * be exposed to that problem.
+                */
+               truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED);
+               if (truncated && VN_DIRTY(vp) && ip->i_delayed_blks > 0)
+                       xfs_flush_pages(ip, 0, -1, XFS_B_ASYNC, FI_NONE);
+       }
+
 #ifdef HAVE_REFCACHE
        /* If we are in the NFS reference cache then don't do this now */
        if (ip->i_refcache)
@@ -1573,7 +1559,8 @@ xfs_release(
                     (ip->i_df.if_flags & XFS_IFEXTENTS))  &&
                    (!(ip->i_d.di_flags &
                                (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
-                       if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+                       error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+                       if (error)
                                return error;
                        /* Update linux inode block count after free above */
                        vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
@@ -1592,13 +1579,11 @@ xfs_release(
  * now be truncated.  Also, we clear all of the read-ahead state
  * kept for the inode here since the file is now closed.
  */
-STATIC int
+int
 xfs_inactive(
-       bhv_desc_t      *bdp,
-       cred_t          *credp)
+       xfs_inode_t     *ip)
 {
-       xfs_inode_t     *ip;
-       bhv_vnode_t     *vp;
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
        xfs_bmap_free_t free_list;
        xfs_fsblock_t   first_block;
        int             committed;
@@ -1607,10 +1592,7 @@ xfs_inactive(
        int             error;
        int             truncate;
 
-       vp = BHV_TO_VNODE(bdp);
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        /*
         * If the inode is already free, then there can be nothing
@@ -1635,15 +1617,14 @@ xfs_inactive(
 
        mp = ip->i_mount;
 
-       if (ip->i_d.di_nlink == 0 &&
-           DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_DESTROY)) {
+       if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY)) {
                (void) XFS_SEND_DESTROY(mp, vp, DM_RIGHT_NULL);
        }
 
        error = 0;
 
        /* If this is a read-only mount, don't do this (would generate I/O) */
-       if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
+       if (mp->m_flags & XFS_MOUNT_RDONLY)
                goto out;
 
        if (ip->i_d.di_nlink != 0) {
@@ -1654,7 +1635,8 @@ xfs_inactive(
                     (!(ip->i_d.di_flags &
                                (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
                      (ip->i_delayed_blks != 0)))) {
-                       if ((error = xfs_inactive_free_eofblocks(mp, ip)))
+                       error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK);
+                       if (error)
                                return VN_INACTIVE_CACHE;
                        /* Update linux inode block count after free above */
                        vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
@@ -1680,6 +1662,7 @@ xfs_inactive(
 
                error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0);
                if (error) {
+                       xfs_trans_cancel(tp, 0);
                        xfs_iunlock(ip, XFS_IOLOCK_EXCL);
                        return VN_INACTIVE_CACHE;
                }
@@ -1811,34 +1794,24 @@ xfs_inactive(
 }
 
 
-/*
- * xfs_lookup
- */
-STATIC int
+int
 xfs_lookup(
-       bhv_desc_t              *dir_bdp,
+       xfs_inode_t             *dp,
        bhv_vname_t             *dentry,
-       bhv_vnode_t             **vpp,
-       int                     flags,
-       bhv_vnode_t             *rdir,
-       cred_t                  *credp)
+       bhv_vnode_t             **vpp)
 {
-       xfs_inode_t             *dp, *ip;
+       xfs_inode_t             *ip;
        xfs_ino_t               e_inum;
        int                     error;
        uint                    lock_mode;
-       bhv_vnode_t             *dir_vp;
 
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
-       dp = XFS_BHVTOI(dir_bdp);
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
        if (XFS_FORCED_SHUTDOWN(dp->i_mount))
                return XFS_ERROR(EIO);
 
        lock_mode = xfs_ilock_map_shared(dp);
-       error = xfs_dir_lookup_int(dir_bdp, lock_mode, dentry, &e_inum, &ip);
+       error = xfs_dir_lookup_int(dp, lock_mode, dentry, &e_inum, &ip);
        if (!error) {
                *vpp = XFS_ITOV(ip);
                ITRACE(ip);
@@ -1847,53 +1820,43 @@ xfs_lookup(
        return error;
 }
 
-
-/*
- * xfs_create (create a new file).
- */
-STATIC int
+int
 xfs_create(
-       bhv_desc_t              *dir_bdp,
+       xfs_inode_t             *dp,
        bhv_vname_t             *dentry,
-       bhv_vattr_t             *vap,
+       mode_t                  mode,
+       xfs_dev_t               rdev,
        bhv_vnode_t             **vpp,
        cred_t                  *credp)
 {
        char                    *name = VNAME(dentry);
-       bhv_vnode_t             *dir_vp;
-       xfs_inode_t             *dp, *ip;
+       xfs_mount_t             *mp = dp->i_mount;
+       bhv_vnode_t             *dir_vp = XFS_ITOV(dp);
+       xfs_inode_t             *ip;
        bhv_vnode_t             *vp = NULL;
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
-       xfs_dev_t               rdev;
        int                     error;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
-       boolean_t               dp_joined_to_trans;
+       boolean_t               unlock_dp_on_error = B_FALSE;
        int                     dm_event_sent = 0;
        uint                    cancel_flags;
        int                     committed;
        xfs_prid_t              prid;
        struct xfs_dquot        *udqp, *gdqp;
        uint                    resblks;
-       int                     dm_di_mode;
        int                     namelen;
 
        ASSERT(!*vpp);
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
-       dp = XFS_BHVTOI(dir_bdp);
-       mp = dp->i_mount;
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
-       dm_di_mode = vap->va_mode;
        namelen = VNAMELEN(dentry);
 
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
                                dir_vp, DM_RIGHT_NULL, NULL,
                                DM_RIGHT_NULL, name, NULL,
-                               dm_di_mode, 0, 0);
+                               mode, 0, 0);
 
                if (error)
                        return error;
@@ -1908,8 +1871,6 @@ xfs_create(
        udqp = gdqp = NULL;
        if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
                prid = dp->i_d.di_projid;
-       else if (vap->va_mask & XFS_AT_PROJID)
-               prid = (xfs_prid_t)vap->va_projid;
        else
                prid = (xfs_prid_t)dfltprid;
 
@@ -1923,7 +1884,6 @@ xfs_create(
                goto std_return;
 
        ip = NULL;
-       dp_joined_to_trans = B_FALSE;
 
        tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
        cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
@@ -1943,11 +1903,11 @@ xfs_create(
        }
        if (error) {
                cancel_flags = 0;
-               dp = NULL;
                goto error_return;
        }
 
        xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+       unlock_dp_on_error = B_TRUE;
 
        XFS_BMAP_INIT(&free_list, &first_block);
 
@@ -1962,8 +1922,7 @@ xfs_create(
 
        if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen)))
                goto error_return;
-       rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0;
-       error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1,
+       error = xfs_dir_ialloc(&tp, dp, mode, 1,
                        rdev, credp, prid, resblks > 0,
                        &ip, &committed);
        if (error) {
@@ -1981,15 +1940,15 @@ xfs_create(
        ASSERT(ismrlocked (&ip->i_lock, MR_UPDATE));
 
        /*
-        * Now we join the directory inode to the transaction.
-        * We do not do it earlier because xfs_dir_ialloc
-        * might commit the previous transaction (and release
-        * all the locks).
+        * Now we join the directory inode to the transaction.  We do not do it
+        * earlier because xfs_dir_ialloc might commit the previous transaction
+        * (and release all the locks).  An error from here on will result in
+        * the transaction cancel unlocking dp so don't do it explicitly in the
+        * error path.
         */
-
        VN_HOLD(dir_vp);
        xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-       dp_joined_to_trans = B_TRUE;
+       unlock_dp_on_error = B_FALSE;
 
        error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino,
                                        &first_block, &free_list, resblks ?
@@ -2043,25 +2002,18 @@ xfs_create(
        XFS_QM_DQRELE(mp, udqp);
        XFS_QM_DQRELE(mp, gdqp);
 
-       /*
-        * Propagate the fact that the vnode changed after the
-        * xfs_inode locks have been released.
-        */
-       bhv_vop_vnode_change(vp, VCHANGE_FLAGS_TRUNCATED, 3);
-
        *vpp = vp;
 
        /* Fallthrough to std_return with error = 0  */
 
 std_return:
-       if ( (*vpp || (error != 0 && dm_event_sent != 0)) &&
-                       DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
-                                                       DM_EVENT_POSTCREATE)) {
+       if ((*vpp || (error != 0 && dm_event_sent != 0)) &&
+           DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
                        dir_vp, DM_RIGHT_NULL,
                        *vpp ? vp:NULL,
                        DM_RIGHT_NULL, name, NULL,
-                       dm_di_mode, error, 0);
+                       mode, error, 0);
        }
        return error;
 
@@ -2073,11 +2025,12 @@ std_return:
        if (tp != NULL)
                xfs_trans_cancel(tp, cancel_flags);
 
-       if (!dp_joined_to_trans && (dp != NULL))
-               xfs_iunlock(dp, XFS_ILOCK_EXCL);
        XFS_QM_DQRELE(mp, udqp);
        XFS_QM_DQRELE(mp, gdqp);
 
+       if (unlock_dp_on_error)
+               xfs_iunlock(dp, XFS_ILOCK_EXCL);
+
        goto std_return;
 
  abort_rele:
@@ -2217,9 +2170,9 @@ static inline int
 xfs_lock_inumorder(int lock_mode, int subclass)
 {
        if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
-               lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
+               lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
        if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
-               lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
+               lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_ILOCK_SHIFT;
 
        return lock_mode;
 }
@@ -2348,22 +2301,16 @@ int remove_which_error_return = 0;
 #define        REMOVE_DEBUG_TRACE(x)
 #endif /* ! DEBUG */
 
-
-/*
- * xfs_remove
- *
- */
-STATIC int
+int
 xfs_remove(
-       bhv_desc_t              *dir_bdp,
-       bhv_vname_t             *dentry,
-       cred_t                  *credp)
+       xfs_inode_t             *dp,
+       bhv_vname_t             *dentry)
 {
-       bhv_vnode_t             *dir_vp;
+       bhv_vnode_t             *dir_vp = XFS_ITOV(dp);
        char                    *name = VNAME(dentry);
-       xfs_inode_t             *dp, *ip;
+       xfs_mount_t             *mp = dp->i_mount;
+       xfs_inode_t             *ip;
        xfs_trans_t             *tp = NULL;
-       xfs_mount_t             *mp;
        int                     error = 0;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
@@ -2374,11 +2321,7 @@ xfs_remove(
        uint                    resblks;
        int                     namelen;
 
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
-
-       dp = XFS_BHVTOI(dir_bdp);
-       mp = dp->i_mount;
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
@@ -2390,7 +2333,7 @@ xfs_remove(
                IRELE(ip);
        }
 
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
                                        DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
                                        name, NULL, dm_di_mode, 0, 0);
@@ -2421,7 +2364,7 @@ xfs_remove(
 
        dm_di_mode = ip->i_d.di_mode;
 
-       vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        ITRACE(ip);
 
@@ -2546,19 +2489,22 @@ xfs_remove(
         */
        xfs_refcache_purge_ip(ip);
 
-       vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
-
        /*
-        * Let interposed file systems know about removed links.
+        * If we are using filestreams, kill the stream association.
+        * If the file is still open it may get a new one but that
+        * will get killed on last close in xfs_close() so we don't
+        * have to worry about that.
         */
-       bhv_vop_link_removed(XFS_ITOV(ip), dir_vp, link_zero);
+       if (link_zero && xfs_inode_is_filestream(ip))
+               xfs_filestream_deassociate(ip);
+
+       vn_trace_exit(ip, __FUNCTION__, (inst_t *)__return_address);
 
        IRELE(ip);
 
 /*     Fall through to std_return with error = 0 */
  std_return:
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp,
-                                               DM_EVENT_POSTREMOVE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
                                dir_vp, DM_RIGHT_NULL,
                                NULL, DM_RIGHT_NULL,
@@ -2596,46 +2542,36 @@ xfs_remove(
        goto std_return;
 }
 
-
-/*
- * xfs_link
- *
- */
-STATIC int
+int
 xfs_link(
-       bhv_desc_t              *target_dir_bdp,
+       xfs_inode_t             *tdp,
        bhv_vnode_t             *src_vp,
-       bhv_vname_t             *dentry,
-       cred_t                  *credp)
+       bhv_vname_t             *dentry)
 {
-       xfs_inode_t             *tdp, *sip;
+       bhv_vnode_t             *target_dir_vp = XFS_ITOV(tdp);
+       xfs_mount_t             *mp = tdp->i_mount;
+       xfs_inode_t             *sip = xfs_vtoi(src_vp);
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
        xfs_inode_t             *ips[2];
        int                     error;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
        int                     cancel_flags;
        int                     committed;
-       bhv_vnode_t             *target_dir_vp;
        int                     resblks;
        char                    *target_name = VNAME(dentry);
        int                     target_namelen;
 
-       target_dir_vp = BHV_TO_VNODE(target_dir_bdp);
-       vn_trace_entry(target_dir_vp, __FUNCTION__, (inst_t *)__return_address);
-       vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(tdp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(xfs_vtoi(src_vp), __FUNCTION__, (inst_t *)__return_address);
 
        target_namelen = VNAMELEN(dentry);
        ASSERT(!VN_ISDIR(src_vp));
 
-       sip = xfs_vtoi(src_vp);
-       tdp = XFS_BHVTOI(target_dir_bdp);
-       mp = tdp->i_mount;
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       if (DM_EVENT_ENABLED(src_vp->v_vfsp, tdp, DM_EVENT_LINK)) {
+       if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
                                        target_dir_vp, DM_RIGHT_NULL,
                                        src_vp, DM_RIGHT_NULL,
@@ -2746,8 +2682,7 @@ xfs_link(
 
        /* Fall through to std_return with error = 0. */
 std_return:
-       if (DM_EVENT_ENABLED(src_vp->v_vfsp, sip,
-                                               DM_EVENT_POSTLINK)) {
+       if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
                                target_dir_vp, DM_RIGHT_NULL,
                                src_vp, DM_RIGHT_NULL,
@@ -2765,57 +2700,43 @@ std_return:
 }
 
 
-/*
- * xfs_mkdir
- *
- */
-STATIC int
+int
 xfs_mkdir(
-       bhv_desc_t              *dir_bdp,
+       xfs_inode_t             *dp,
        bhv_vname_t             *dentry,
-       bhv_vattr_t             *vap,
+       mode_t                  mode,
        bhv_vnode_t             **vpp,
        cred_t                  *credp)
 {
+       bhv_vnode_t             *dir_vp = XFS_ITOV(dp);
        char                    *dir_name = VNAME(dentry);
-       xfs_inode_t             *dp;
+       int                     dir_namelen = VNAMELEN(dentry);
+       xfs_mount_t             *mp = dp->i_mount;
        xfs_inode_t             *cdp;   /* inode of created dir */
        bhv_vnode_t             *cvp;   /* vnode of created dir */
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
        int                     cancel_flags;
        int                     error;
        int                     committed;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
-       bhv_vnode_t             *dir_vp;
-       boolean_t               dp_joined_to_trans;
+       boolean_t               unlock_dp_on_error = B_FALSE;
        boolean_t               created = B_FALSE;
        int                     dm_event_sent = 0;
        xfs_prid_t              prid;
        struct xfs_dquot        *udqp, *gdqp;
        uint                    resblks;
-       int                     dm_di_mode;
-       int                     dir_namelen;
-
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       dp = XFS_BHVTOI(dir_bdp);
-       mp = dp->i_mount;
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       dir_namelen = VNAMELEN(dentry);
-
        tp = NULL;
-       dp_joined_to_trans = B_FALSE;
-       dm_di_mode = vap->va_mode;
 
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
                                        dir_vp, DM_RIGHT_NULL, NULL,
                                        DM_RIGHT_NULL, dir_name, NULL,
-                                       dm_di_mode, 0, 0);
+                                       mode, 0, 0);
                if (error)
                        return error;
                dm_event_sent = 1;
@@ -2823,14 +2744,12 @@ xfs_mkdir(
 
        /* Return through std_return after this point. */
 
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
        mp = dp->i_mount;
        udqp = gdqp = NULL;
        if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
                prid = dp->i_d.di_projid;
-       else if (vap->va_mask & XFS_AT_PROJID)
-               prid = (xfs_prid_t)vap->va_projid;
        else
                prid = (xfs_prid_t)dfltprid;
 
@@ -2856,11 +2775,11 @@ xfs_mkdir(
        }
        if (error) {
                cancel_flags = 0;
-               dp = NULL;
                goto error_return;
        }
 
        xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+       unlock_dp_on_error = B_TRUE;
 
        /*
         * Check for directory link count overflow.
@@ -2883,7 +2802,7 @@ xfs_mkdir(
        /*
         * create the directory inode.
         */
-       error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2,
+       error = xfs_dir_ialloc(&tp, dp, mode, 2,
                        0, credp, prid, resblks > 0,
                &cdp, NULL);
        if (error) {
@@ -2897,11 +2816,13 @@ xfs_mkdir(
         * Now we add the directory inode to the transaction.
         * We waited until now since xfs_dir_ialloc might start
         * a new transaction.  Had we joined the transaction
-        * earlier, the locks might have gotten released.
+        * earlier, the locks might have gotten released. An error
+        * from here on will result in the transaction cancel
+        * unlocking dp so don't do it explicitly in the error path.
         */
        VN_HOLD(dir_vp);
        xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-       dp_joined_to_trans = B_TRUE;
+       unlock_dp_on_error = B_FALSE;
 
        XFS_BMAP_INIT(&free_list, &first_block);
 
@@ -2968,15 +2889,14 @@ xfs_mkdir(
         * xfs_trans_commit. */
 
 std_return:
-       if ( (created || (error != 0 && dm_event_sent != 0)) &&
-                       DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
-                                               DM_EVENT_POSTCREATE)) {
+       if ((created || (error != 0 && dm_event_sent != 0)) &&
+           DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
                                        dir_vp, DM_RIGHT_NULL,
                                        created ? XFS_ITOV(cdp):NULL,
                                        DM_RIGHT_NULL,
                                        dir_name, NULL,
-                                       dm_di_mode, error, 0);
+                                       mode, error, 0);
        }
        return error;
 
@@ -2990,56 +2910,43 @@ std_return:
        XFS_QM_DQRELE(mp, udqp);
        XFS_QM_DQRELE(mp, gdqp);
 
-       if (!dp_joined_to_trans && (dp != NULL)) {
+       if (unlock_dp_on_error)
                xfs_iunlock(dp, XFS_ILOCK_EXCL);
-       }
 
        goto std_return;
 }
 
-
-/*
- * xfs_rmdir
- *
- */
-STATIC int
+int
 xfs_rmdir(
-       bhv_desc_t              *dir_bdp,
-       bhv_vname_t             *dentry,
-       cred_t                  *credp)
+       xfs_inode_t             *dp,
+       bhv_vname_t             *dentry)
 {
+       bhv_vnode_t             *dir_vp = XFS_ITOV(dp);
        char                    *name = VNAME(dentry);
-       xfs_inode_t             *dp;
-       xfs_inode_t             *cdp;   /* child directory */
+       int                     namelen = VNAMELEN(dentry);
+       xfs_mount_t             *mp = dp->i_mount;
+       xfs_inode_t             *cdp;   /* child directory */
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
        int                     error;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
        int                     cancel_flags;
        int                     committed;
-       bhv_vnode_t             *dir_vp;
        int                     dm_di_mode = S_IFDIR;
        int                     last_cdp_link;
-       int                     namelen;
        uint                    resblks;
 
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       dp = XFS_BHVTOI(dir_bdp);
-       mp = dp->i_mount;
-
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
-       if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
+       if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
-       namelen = VNAMELEN(dentry);
 
        if (!xfs_get_dir_entry(dentry, &cdp)) {
                dm_di_mode = cdp->i_d.di_mode;
                IRELE(cdp);
        }
 
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
                                        dir_vp, DM_RIGHT_NULL,
                                        NULL, DM_RIGHT_NULL,
@@ -3218,17 +3125,12 @@ xfs_rmdir(
        }
 
 
-       /*
-        * Let interposed file systems know about removed links.
-        */
-       bhv_vop_link_removed(XFS_ITOV(cdp), dir_vp, last_cdp_link);
-
        IRELE(cdp);
 
        /* Fall through to std_return with error = 0 or the errno
         * from xfs_trans_commit. */
  std_return:
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
                                        dir_vp, DM_RIGHT_NULL,
                                        NULL, DM_RIGHT_NULL,
@@ -3247,56 +3149,24 @@ xfs_rmdir(
        goto std_return;
 }
 
-
-/*
- * Read dp's entries starting at uiop->uio_offset and translate them into
- * bufsize bytes worth of struct dirents starting at bufbase.
- */
-STATIC int
-xfs_readdir(
-       bhv_desc_t      *dir_bdp,
-       uio_t           *uiop,
-       cred_t          *credp,
-       int             *eofp)
-{
-       xfs_inode_t     *dp;
-       xfs_trans_t     *tp = NULL;
-       int             error = 0;
-       uint            lock_mode;
-
-       vn_trace_entry(BHV_TO_VNODE(dir_bdp), __FUNCTION__,
-                                              (inst_t *)__return_address);
-       dp = XFS_BHVTOI(dir_bdp);
-
-       if (XFS_FORCED_SHUTDOWN(dp->i_mount))
-               return XFS_ERROR(EIO);
-
-       lock_mode = xfs_ilock_map_shared(dp);
-       error = xfs_dir_getdents(tp, dp, uiop, eofp);
-       xfs_iunlock_map_shared(dp, lock_mode);
-       return error;
-}
-
-
-STATIC int
+int
 xfs_symlink(
-       bhv_desc_t              *dir_bdp,
+       xfs_inode_t             *dp,
        bhv_vname_t             *dentry,
-       bhv_vattr_t             *vap,
        char                    *target_path,
+       mode_t                  mode,
        bhv_vnode_t             **vpp,
        cred_t                  *credp)
 {
+       bhv_vnode_t             *dir_vp = XFS_ITOV(dp);
+       xfs_mount_t             *mp = dp->i_mount;
        xfs_trans_t             *tp;
-       xfs_mount_t             *mp;
-       xfs_inode_t             *dp;
        xfs_inode_t             *ip;
        int                     error;
        int                     pathlen;
        xfs_bmap_free_t         free_list;
        xfs_fsblock_t           first_block;
-       boolean_t               dp_joined_to_trans;
-       bhv_vnode_t             *dir_vp;
+       boolean_t               unlock_dp_on_error = B_FALSE;
        uint                    cancel_flags;
        int                     committed;
        xfs_fileoff_t           first_fsb;
@@ -3315,16 +3185,12 @@ xfs_symlink(
        int                     link_namelen;
 
        *vpp = NULL;
-       dir_vp = BHV_TO_VNODE(dir_bdp);
-       dp = XFS_BHVTOI(dir_bdp);
-       dp_joined_to_trans = B_FALSE;
        error = 0;
        ip = NULL;
        tp = NULL;
 
-       vn_trace_entry(dir_vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(dp, __FUNCTION__, (inst_t *)__return_address);
 
-       mp = dp->i_mount;
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
@@ -3363,7 +3229,7 @@ xfs_symlink(
                }
        }
 
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_SYMLINK)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dir_vp,
                                        DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
                                        link_name, target_path, 0, 0, 0);
@@ -3376,8 +3242,6 @@ xfs_symlink(
        udqp = gdqp = NULL;
        if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
                prid = dp->i_d.di_projid;
-       else if (vap->va_mask & XFS_AT_PROJID)
-               prid = (xfs_prid_t)vap->va_projid;
        else
                prid = (xfs_prid_t)dfltprid;
 
@@ -3410,11 +3274,11 @@ xfs_symlink(
        }
        if (error) {
                cancel_flags = 0;
-               dp = NULL;
                goto error_return;
        }
 
        xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
+       unlock_dp_on_error = B_TRUE;
 
        /*
         * Check whether the directory allows new symlinks or not.
@@ -3446,7 +3310,7 @@ xfs_symlink(
        /*
         * Allocate an inode for the symlink.
         */
-       error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (vap->va_mode&~S_IFMT),
+       error = xfs_dir_ialloc(&tp, dp, S_IFLNK | (mode & ~S_IFMT),
                               1, 0, credp, prid, resblks > 0, &ip, NULL);
        if (error) {
                if (error == ENOSPC)
@@ -3455,9 +3319,14 @@ xfs_symlink(
        }
        ITRACE(ip);
 
+       /*
+        * An error after we've joined dp to the transaction will result in the
+        * transaction cancel unlocking dp so don't do it explicitly in the
+        * error path.
+        */
        VN_HOLD(dir_vp);
        xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-       dp_joined_to_trans = B_TRUE;
+       unlock_dp_on_error = B_FALSE;
 
        /*
         * Also attach the dquot(s) to it, if applicable.
@@ -3563,8 +3432,7 @@ xfs_symlink(
        /* Fall through to std_return with error = 0 or errno from
         * xfs_trans_commit     */
 std_return:
-       if (DM_EVENT_ENABLED(dir_vp->v_vfsp, XFS_BHVTOI(dir_bdp),
-                            DM_EVENT_POSTSYMLINK)) {
+       if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) {
                (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
                                        dir_vp, DM_RIGHT_NULL,
                                        error ? NULL : XFS_ITOV(ip),
@@ -3591,35 +3459,21 @@ std_return:
        XFS_QM_DQRELE(mp, udqp);
        XFS_QM_DQRELE(mp, gdqp);
 
-       if (!dp_joined_to_trans && (dp != NULL)) {
+       if (unlock_dp_on_error)
                xfs_iunlock(dp, XFS_ILOCK_EXCL);
-       }
 
        goto std_return;
 }
 
 
-/*
- * xfs_fid2
- *
- * A fid routine that takes a pointer to a previously allocated
- * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
- */
-STATIC int
+int
 xfs_fid2(
-       bhv_desc_t      *bdp,
-       fid_t           *fidp)
+       xfs_inode_t     *ip,
+       xfs_fid_t       *xfid)
 {
-       xfs_inode_t     *ip;
-       xfs_fid2_t      *xfid;
-
-       vn_trace_entry(BHV_TO_VNODE(bdp), __FUNCTION__,
-                                      (inst_t *)__return_address);
-       ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
-       xfid = (xfs_fid2_t *)fidp;
-       ip = XFS_BHVTOI(bdp);
-       xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
+       xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len);
        xfid->fid_pad = 0;
        /*
         * use memcpy because the inode is a long long and there's no
@@ -3632,21 +3486,13 @@ xfs_fid2(
 }
 
 
-/*
- * xfs_rwlock
- */
 int
 xfs_rwlock(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        bhv_vrwlock_t   locktype)
 {
-       xfs_inode_t     *ip;
-       bhv_vnode_t     *vp;
-
-       vp = BHV_TO_VNODE(bdp);
-       if (VN_ISDIR(vp))
+       if (S_ISDIR(ip->i_d.di_mode))
                return 1;
-       ip = XFS_BHVTOI(bdp);
        if (locktype == VRWLOCK_WRITE) {
                xfs_ilock(ip, XFS_IOLOCK_EXCL);
        } else if (locktype == VRWLOCK_TRY_READ) {
@@ -3663,21 +3509,13 @@ xfs_rwlock(
 }
 
 
-/*
- * xfs_rwunlock
- */
 void
 xfs_rwunlock(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        bhv_vrwlock_t   locktype)
 {
-       xfs_inode_t     *ip;
-       bhv_vnode_t     *vp;
-
-       vp = BHV_TO_VNODE(bdp);
-       if (VN_ISDIR(vp))
-               return;
-       ip = XFS_BHVTOI(bdp);
+       if (S_ISDIR(ip->i_d.di_mode))
+               return;
        if (locktype == VRWLOCK_WRITE) {
                /*
                 * In the write case, we may have added a new entry to
@@ -3695,20 +3533,16 @@ xfs_rwunlock(
        return;
 }
 
-STATIC int
+
+int
 xfs_inode_flush(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        int             flags)
 {
-       xfs_inode_t     *ip;
-       xfs_mount_t     *mp;
-       xfs_inode_log_item_t *iip;
+       xfs_mount_t     *mp = ip->i_mount;
+       xfs_inode_log_item_t *iip = ip->i_itemp;
        int             error = 0;
 
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
-       iip = ip->i_itemp;
-
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
@@ -3730,12 +3564,16 @@ xfs_inode_flush(
                        sync_lsn = log->l_last_sync_lsn;
                        GRANT_UNLOCK(log, s);
 
-                       if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) <= 0))
-                               return 0;
+                       if ((XFS_LSN_CMP(iip->ili_last_lsn, sync_lsn) > 0)) {
+                               if (flags & FLUSH_SYNC)
+                                       log_flags |= XFS_LOG_SYNC;
+                               error = xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+                               if (error)
+                                       return error;
+                       }
 
-                       if (flags & FLUSH_SYNC)
-                               log_flags |= XFS_LOG_SYNC;
-                       return xfs_log_force(mp, iip->ili_last_lsn, log_flags);
+                       if (ip->i_update_core == 0)
+                               return 0;
                }
        }
 
@@ -3749,9 +3587,6 @@ xfs_inode_flush(
        if (flags & FLUSH_INODE) {
                int     flush_flags;
 
-               if (xfs_ipincount(ip))
-                       return EAGAIN;
-
                if (flags & FLUSH_SYNC) {
                        xfs_ilock(ip, XFS_ILOCK_SHARED);
                        xfs_iflock(ip);
@@ -3776,24 +3611,20 @@ xfs_inode_flush(
        return error;
 }
 
+
 int
-xfs_set_dmattrs (
-       bhv_desc_t      *bdp,
+xfs_set_dmattrs(
+       xfs_inode_t     *ip,
        u_int           evmask,
-       u_int16_t       state,
-       cred_t          *credp)
+       u_int16_t       state)
 {
-       xfs_inode_t     *ip;
+       xfs_mount_t     *mp = ip->i_mount;
        xfs_trans_t     *tp;
-       xfs_mount_t     *mp;
        int             error;
 
        if (!capable(CAP_SYS_ADMIN))
                return XFS_ERROR(EPERM);
 
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
-
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
@@ -3816,17 +3647,13 @@ xfs_set_dmattrs (
        return error;
 }
 
-STATIC int
+int
 xfs_reclaim(
-       bhv_desc_t      *bdp)
+       xfs_inode_t     *ip)
 {
-       xfs_inode_t     *ip;
-       bhv_vnode_t     *vp;
+       bhv_vnode_t     *vp = XFS_ITOV(ip);
 
-       vp = BHV_TO_VNODE(bdp);
-       ip = XFS_BHVTOI(bdp);
-
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        ASSERT(!VN_MAPPED(vp));
 
@@ -3836,7 +3663,7 @@ xfs_reclaim(
                return 0;
        }
 
-       vn_iowait(vp);
+       vn_iowait(ip);
 
        ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
 
@@ -3868,7 +3695,8 @@ xfs_reclaim(
                XFS_MOUNT_ILOCK(mp);
                spin_lock(&ip->i_flags_lock);
                __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
-               vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
+               vn_to_inode(vp)->i_private = NULL;
+               ip->i_vnode = NULL;
                spin_unlock(&ip->i_flags_lock);
                list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
                XFS_MOUNT_IUNLOCK(mp);
@@ -3882,7 +3710,7 @@ xfs_finish_reclaim(
        int             locked,
        int             sync_mode)
 {
-       xfs_ihash_t     *ih = ip->i_hash;
+       xfs_perag_t     *pag = xfs_get_perag(ip->i_mount, ip->i_ino);
        bhv_vnode_t     *vp = XFS_ITOV_NULL(ip);
        int             error;
 
@@ -3894,12 +3722,12 @@ xfs_finish_reclaim(
         * Once we have the XFS_IRECLAIM flag set it will not touch
         * us.
         */
-       write_lock(&ih->ih_lock);
+       write_lock(&pag->pag_ici_lock);
        spin_lock(&ip->i_flags_lock);
        if (__xfs_iflags_test(ip, XFS_IRECLAIM) ||
            (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) {
                spin_unlock(&ip->i_flags_lock);
-               write_unlock(&ih->ih_lock);
+               write_unlock(&pag->pag_ici_lock);
                if (locked) {
                        xfs_ifunlock(ip);
                        xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -3908,7 +3736,8 @@ xfs_finish_reclaim(
        }
        __xfs_iflags_set(ip, XFS_IRECLAIM);
        spin_unlock(&ip->i_flags_lock);
-       write_unlock(&ih->ih_lock);
+       write_unlock(&pag->pag_ici_lock);
+       xfs_put_perag(ip->i_mount, pag);
 
        /*
         * If the inode is still dirty, then flush it out.  If the inode
@@ -4042,27 +3871,21 @@ xfs_alloc_file_space(
        int                     committed;
        int                     error;
 
-       vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        if (XFS_FORCED_SHUTDOWN(mp))
                return XFS_ERROR(EIO);
 
-       rt = XFS_IS_REALTIME_INODE(ip);
-       if (unlikely(rt)) {
-               if (!(extsz = ip->i_d.di_extsize))
-                       extsz = mp->m_sb.sb_rextsize;
-       } else {
-               extsz = ip->i_d.di_extsize;
-       }
-
        if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
                return error;
 
        if (len <= 0)
                return XFS_ERROR(EINVAL);
 
+       rt = XFS_IS_REALTIME_INODE(ip);
+       extsz = xfs_get_extsz_hint(ip);
+
        count = len;
-       error = 0;
        imapp = &imaps[0];
        nimaps = 1;
        bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0);
@@ -4072,7 +3895,7 @@ xfs_alloc_file_space(
        /*      Generate a DMAPI event if needed.       */
        if (alloc_type != 0 && offset < ip->i_size &&
                        (attr_flags&ATTR_DMI) == 0  &&
-                       DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
+                       DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
                xfs_off_t           end_dmi_offset;
 
                end_dmi_offset = offset+len;
@@ -4186,9 +4009,8 @@ retry:
                allocatesize_fsb -= allocated_fsb;
        }
 dmapi_enospc_check:
-       if (error == ENOSPC && (attr_flags&ATTR_DMI) == 0 &&
-           DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_NOSPACE)) {
-
+       if (error == ENOSPC && (attr_flags & ATTR_DMI) == 0 &&
+           DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
                error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
                                XFS_ITOV(ip), DM_RIGHT_NULL,
                                XFS_ITOV(ip), DM_RIGHT_NULL,
@@ -4319,7 +4141,7 @@ xfs_free_file_space(
        vp = XFS_ITOV(ip);
        mp = ip->i_mount;
 
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
                return error;
@@ -4332,9 +4154,8 @@ xfs_free_file_space(
        end_dmi_offset = offset + len;
        endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
 
-       if (offset < ip->i_size &&
-           (attr_flags & ATTR_DMI) == 0 &&
-           DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
+       if (offset < ip->i_size && (attr_flags & ATTR_DMI) == 0 &&
+           DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
                if (end_dmi_offset > ip->i_size)
                        end_dmi_offset = ip->i_size;
                error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
@@ -4348,7 +4169,7 @@ xfs_free_file_space(
                need_iolock = 0;
        if (need_iolock) {
                xfs_ilock(ip, XFS_IOLOCK_EXCL);
-               vn_iowait(vp);  /* wait for the completion of any pending DIOs */
+               vn_iowait(ip);  /* wait for the completion of any pending DIOs */
        }
 
        rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
@@ -4357,7 +4178,8 @@ xfs_free_file_space(
        if (VN_CACHED(vp) != 0) {
                xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
                                ctooff(offtoct(ioffset)), -1);
-               error = bhv_vop_flushinval_pages(vp, ctooff(offtoct(ioffset)),
+               error = xfs_flushinval_pages(ip,
+                               ctooff(offtoct(ioffset)),
                                -1, FI_REMAPF_LOCKED);
                if (error)
                        goto out_unlock_iolock;
@@ -4424,9 +4246,12 @@ xfs_free_file_space(
        while (!error && !done) {
 
                /*
-                * allocate and setup the transaction
+                * allocate and setup the transaction. Allow this
+                * transaction to dip into the reserve blocks to ensure
+                * the freeing of the space succeeds at ENOSPC.
                 */
                tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
+               tp->t_flags |= XFS_TRANS_RESERVE;
                error = xfs_trans_reserve(tp,
                                          resblks,
                                          XFS_WRITE_LOG_RES(mp),
@@ -4505,35 +4330,29 @@ xfs_free_file_space(
  */
 int
 xfs_change_file_space(
-       bhv_desc_t      *bdp,
+       xfs_inode_t     *ip,
        int             cmd,
        xfs_flock64_t   *bf,
        xfs_off_t       offset,
        cred_t          *credp,
        int             attr_flags)
 {
+       xfs_mount_t     *mp = ip->i_mount;
        int             clrprealloc;
        int             error;
        xfs_fsize_t     fsize;
-       xfs_inode_t     *ip;
-       xfs_mount_t     *mp;
        int             setprealloc;
        xfs_off_t       startoffset;
        xfs_off_t       llen;
        xfs_trans_t     *tp;
        bhv_vattr_t     va;
-       bhv_vnode_t     *vp;
 
-       vp = BHV_TO_VNODE(bdp);
-       vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
+       vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
 
        /*
         * must be a regular file and have write permission
         */
-       if (!VN_ISREG(vp))
+       if (!S_ISREG(ip->i_d.di_mode))
                return XFS_ERROR(EINVAL);
 
        xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -4615,7 +4434,7 @@ xfs_change_file_space(
                va.va_mask = XFS_AT_SIZE;
                va.va_size = startoffset;
 
-               error = xfs_setattr(bdp, &va, attr_flags, credp);
+               error = xfs_setattr(ip, &va, attr_flags, credp);
 
                if (error)
                        return error;
@@ -4674,47 +4493,3 @@ xfs_change_file_space(
 
        return error;
 }
-
-bhv_vnodeops_t xfs_vnodeops = {
-       BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS),
-       .vop_open               = xfs_open,
-       .vop_close              = xfs_close,
-       .vop_read               = xfs_read,
-#ifdef HAVE_SPLICE
-       .vop_splice_read        = xfs_splice_read,
-       .vop_splice_write       = xfs_splice_write,
-#endif
-       .vop_write              = xfs_write,
-       .vop_ioctl              = xfs_ioctl,
-       .vop_getattr            = xfs_getattr,
-       .vop_setattr            = xfs_setattr,
-       .vop_access             = xfs_access,
-       .vop_lookup             = xfs_lookup,
-       .vop_create             = xfs_create,
-       .vop_remove             = xfs_remove,
-       .vop_link               = xfs_link,
-       .vop_rename             = xfs_rename,
-       .vop_mkdir              = xfs_mkdir,
-       .vop_rmdir              = xfs_rmdir,
-       .vop_readdir            = xfs_readdir,
-       .vop_symlink            = xfs_symlink,
-       .vop_readlink           = xfs_readlink,
-       .vop_fsync              = xfs_fsync,
-       .vop_inactive           = xfs_inactive,
-       .vop_fid2               = xfs_fid2,
-       .vop_rwlock             = xfs_rwlock,
-       .vop_rwunlock           = xfs_rwunlock,
-       .vop_bmap               = xfs_bmap,
-       .vop_reclaim            = xfs_reclaim,
-       .vop_attr_get           = xfs_attr_get,
-       .vop_attr_set           = xfs_attr_set,
-       .vop_attr_remove        = xfs_attr_remove,
-       .vop_attr_list          = xfs_attr_list,
-       .vop_link_removed       = (vop_link_removed_t)fs_noval,
-       .vop_vnode_change       = (vop_vnode_change_t)fs_noval,
-       .vop_tosspages          = fs_tosspages,
-       .vop_flushinval_pages   = fs_flushinval_pages,
-       .vop_flush_pages        = fs_flush_pages,
-       .vop_release            = xfs_release,
-       .vop_iflush             = xfs_inode_flush,
-};