Merge git://oss.sgi.com:8090/xfs-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 22 Jun 2006 01:10:19 +0000 (18:10 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 22 Jun 2006 01:10:19 +0000 (18:10 -0700)
* git://oss.sgi.com:8090/xfs-2.6: (43 commits)
  [XFS] Remove files from the build that are now unused.
  [XFS] Fix a Makefile issue related to exports.o handling.
  [XFS] Remove version 1 directory code. Never functioned on Linux, just
  [XFS] Map EFSCORRUPTED to an actual error code, not just a made up one
  [XFS] Kill direct access to ->count in valusema(); all we ever use it for
  [XFS] Remove unneeded conditional code on NFS export interface related
  [XFS] Remove an incorrect use of unlikely() on a relatively likely code
  [XFS] Push some common code out of write path into core XFS code for
  [XFS] Remove unnecessary local from open_exec dmapi path.
  [XFS] Minor XFS documentation updates.
  [XFS] Fix broken const use inside local suffix_strtoul routine.
  [XFS] Fix nused counter.  It's currently getting set to -1 rather than
  [XFS] Fix mismerge of the fs_writable cleanup patch causing a freeze/thaw
  [XFS] Fix up debug code so that bulkstat wont generate thousands of
  [XFS] Remove unused parameter from di2xflags routine.
  [XFS] Cleanup a missed porting conversion, and freezing.
  [XFS] Resolve a namespace collision on remaining vtypes for FreeBSD
  [XFS] Resolve a namespace collision on vnode/vnodeops for FreeBSD porters.
  [XFS] Resolve a namespace collision on vfs/vfsops for FreeBSD porters.
  [XFS] statvfs component of directory/project quota support, code
  ...

109 files changed:
MAINTAINERS
fs/xfs/Kconfig
fs/xfs/Makefile-linux-2.6
fs/xfs/linux-2.6/kmem.h
fs/xfs/linux-2.6/mrlock.h
fs/xfs/linux-2.6/sema.h
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_aops.h
fs/xfs/linux-2.6/xfs_export.c
fs/xfs/linux-2.6/xfs_file.c
fs/xfs/linux-2.6/xfs_fs_subr.c
fs/xfs/linux-2.6/xfs_globals.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/linux-2.6/xfs_ioctl32.c
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_linux.h
fs/xfs/linux-2.6/xfs_lrw.c
fs/xfs/linux-2.6/xfs_lrw.h
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_super.h
fs/xfs/linux-2.6/xfs_sysctl.c
fs/xfs/linux-2.6/xfs_sysctl.h
fs/xfs/linux-2.6/xfs_vfs.c
fs/xfs/linux-2.6/xfs_vfs.h
fs/xfs/linux-2.6/xfs_vnode.c
fs/xfs/linux-2.6/xfs_vnode.h
fs/xfs/quota/xfs_dquot.c
fs/xfs/quota/xfs_dquot.h
fs/xfs/quota/xfs_dquot_item.c
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm_bhv.c
fs/xfs/quota/xfs_qm_stats.c
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/quota/xfs_trans_dquot.c
fs/xfs/support/debug.c
fs/xfs/support/debug.h
fs/xfs/xfs_acl.c
fs/xfs/xfs_acl.h
fs/xfs/xfs_alloc.c
fs/xfs/xfs_alloc.h
fs/xfs/xfs_alloc_btree.c
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr.h
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap.h
fs/xfs/xfs_bmap_btree.c
fs/xfs/xfs_btree.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_cap.h
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_da_btree.h
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_dfrag.h
fs/xfs/xfs_dinode.h
fs/xfs/xfs_dir.c [deleted file]
fs/xfs/xfs_dir.h [deleted file]
fs/xfs/xfs_dir2.c
fs/xfs/xfs_dir2.h
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_data.c
fs/xfs/xfs_dir2_data.h
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_dir2_sf.c
fs/xfs/xfs_dir2_trace.c
fs/xfs/xfs_dir_leaf.c [deleted file]
fs/xfs/xfs_dir_leaf.h [deleted file]
fs/xfs/xfs_dir_sf.h [deleted file]
fs/xfs/xfs_dmapi.h
fs/xfs/xfs_dmops.c
fs/xfs/xfs_error.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_extfree_item.h
fs/xfs/xfs_fs.h
fs/xfs/xfs_fsops.c
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_ialloc_btree.c
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_inode_item.h
fs/xfs/xfs_iocore.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_itable.c
fs/xfs/xfs_itable.h
fs/xfs/xfs_log.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_qmops.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_rename.c
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_rw.c
fs/xfs/xfs_rw.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_ail.c
fs/xfs/xfs_trans_buf.c
fs/xfs/xfs_trans_extfree.c
fs/xfs/xfs_trans_inode.c
fs/xfs/xfs_trans_item.c
fs/xfs/xfs_trans_space.h
fs/xfs/xfs_utils.c
fs/xfs/xfs_utils.h
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c

index 0692c33d13cd340bafa6f224fa2aa18358ae010f..d10e629db5630de18fe9df492fa0df644a8ec78b 100644 (file)
@@ -3191,7 +3191,7 @@ XFS FILESYSTEM
 P:     Silicon Graphics Inc
 M:     xfs-masters@oss.sgi.com
 M:     nathans@sgi.com
-L:     linux-xfs@oss.sgi.com
+L:     xfs@oss.sgi.com
 W:     http://oss.sgi.com/projects/xfs
 S:     Supported
 
index bac27d66151dc18562be4c83ed7b75ff43803d72..26b364c9d62c67226de54101ae6f7faa31f33251 100644 (file)
@@ -1,6 +1,5 @@
 config XFS_FS
        tristate "XFS filesystem support"
-       select EXPORTFS if NFSD!=n
        help
          XFS is a high performance journaling filesystem which originated
          on the SGI IRIX platform.  It is completely multi-threaded, can
@@ -18,11 +17,6 @@ config XFS_FS
          system of your root partition is compiled as a module, you'll need
          to use an initial ramdisk (initrd) to boot.
 
-config XFS_EXPORT
-       bool
-       depends on XFS_FS && EXPORTFS
-       default y
-
 config XFS_QUOTA
        bool "XFS Quota support"
        depends on XFS_FS
@@ -65,18 +59,19 @@ config XFS_POSIX_ACL
          If you don't know what Access Control Lists are, say N.
 
 config XFS_RT
-       bool "XFS Realtime support (EXPERIMENTAL)"
-       depends on XFS_FS && EXPERIMENTAL
+       bool "XFS Realtime subvolume support"
+       depends on XFS_FS
        help
          If you say Y here you will be able to mount and use XFS filesystems
-         which contain a realtime subvolume. The realtime subvolume is a
-         separate area of disk space where only file data is stored. The
-         realtime subvolume is designed to provide very deterministic
-         data rates suitable for media streaming applications.
-
-         See the xfs man page in section 5 for a bit more information.
+         which contain a realtime subvolume.  The realtime subvolume is a
+         separate area of disk space where only file data is stored.  It was
+         originally designed to provide deterministic data rates suitable
+         for media streaming applications, but is also useful as a generic
+         mechanism for ensuring data and metadata/log I/Os are completely
+         separated.  Regular file I/Os are isolated to a separate device
+         from all other requests, and this can be done quite transparently
+         to applications via the inherit-realtime directory inode flag.
 
-         This feature is unsupported at this time, is not yet fully
-         functional, and may cause serious problems.
+         See the xfs man page in section 5 for additional information.
 
          If unsure, say N.
index 5d73eaa1971fbb3679f480cda5d0e616e723d27b..9e7f85986d0de3d766a6cc5ee783bb7cd5a9bdb9 100644 (file)
@@ -59,7 +59,6 @@ xfs-$(CONFIG_XFS_POSIX_ACL)   += xfs_acl.o
 xfs-$(CONFIG_PROC_FS)          += $(XFS_LINUX)/xfs_stats.o
 xfs-$(CONFIG_SYSCTL)           += $(XFS_LINUX)/xfs_sysctl.o
 xfs-$(CONFIG_COMPAT)           += $(XFS_LINUX)/xfs_ioctl32.o
-xfs-$(CONFIG_XFS_EXPORT)       += $(XFS_LINUX)/xfs_export.o
 
 
 xfs-y                          += xfs_alloc.o \
@@ -73,14 +72,12 @@ xfs-y                               += xfs_alloc.o \
                                   xfs_btree.o \
                                   xfs_buf_item.o \
                                   xfs_da_btree.o \
-                                  xfs_dir.o \
                                   xfs_dir2.o \
                                   xfs_dir2_block.o \
                                   xfs_dir2_data.o \
                                   xfs_dir2_leaf.o \
                                   xfs_dir2_node.o \
                                   xfs_dir2_sf.o \
-                                  xfs_dir_leaf.o \
                                   xfs_error.o \
                                   xfs_extfree_item.o \
                                   xfs_fsops.o \
@@ -117,6 +114,7 @@ xfs-y                               += $(addprefix $(XFS_LINUX)/, \
                                   kmem.o \
                                   xfs_aops.o \
                                   xfs_buf.o \
+                                  xfs_export.o \
                                   xfs_file.o \
                                   xfs_fs_subr.o \
                                   xfs_globals.o \
index 2cfd33d4d8aa8af49ca03c0afd9ead31c96a71c3..939bd84bc7ee3c0b137ad10a0353883e03f82946 100644 (file)
 #include <linux/sched.h>
 #include <linux/mm.h>
 
-/*
- * Process flags handling
- */
-
-#define PFLAGS_TEST_NOIO()              (current->flags & PF_NOIO)
-#define PFLAGS_TEST_FSTRANS()           (current->flags & PF_FSTRANS)
-
-#define PFLAGS_SET_NOIO() do {         \
-       current->flags |= PF_NOIO;      \
-} while (0)
-
-#define PFLAGS_CLEAR_NOIO() do {       \
-       current->flags &= ~PF_NOIO;     \
-} while (0)
-
-/* these could be nested, so we save state */
-#define PFLAGS_SET_FSTRANS(STATEP) do {        \
-       *(STATEP) = current->flags;     \
-       current->flags |= PF_FSTRANS;   \
-} while (0)
-
-#define PFLAGS_CLEAR_FSTRANS(STATEP) do { \
-       *(STATEP) = current->flags;     \
-       current->flags &= ~PF_FSTRANS;  \
-} while (0)
-
-/* Restore the PF_FSTRANS state to what was saved in STATEP */
-#define PFLAGS_RESTORE_FSTRANS(STATEP) do {                    \
-       current->flags = ((current->flags & ~PF_FSTRANS) |      \
-                         (*(STATEP) & PF_FSTRANS));            \
-} while (0)
-
-#define PFLAGS_DUP(OSTATEP, NSTATEP) do { \
-       *(NSTATEP) = *(OSTATEP);        \
-} while (0)
-
 /*
  * General memory allocation interfaces
  */
@@ -83,7 +47,7 @@ kmem_flags_convert(unsigned int __nocast flags)
                lflags = GFP_ATOMIC | __GFP_NOWARN;
        } else {
                lflags = GFP_KERNEL | __GFP_NOWARN;
-               if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
+               if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS))
                        lflags &= ~__GFP_FS;
        }
        return lflags;
index 1b262b790d9c2d04880b32219752b7357c4bcd5d..32e1ce0f04c94b0d7b130c2fc94360f667cb1e89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ typedef struct {
 } mrlock_t;
 
 #define mrinit(mrp, name)      \
-       ( (mrp)->mr_writer = 0, init_rwsem(&(mrp)->mr_lock) )
+       do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
 #define mrlock_init(mrp, t,n,s)        mrinit(mrp, n)
 #define mrfree(mrp)            do { } while (0)
 #define mraccess(mrp)          mraccessf(mrp, 0)
index 194a84490bd1f33e2931de317101f565f0333228..b25090094cca73d97a350b141f12114327fc3405 100644 (file)
@@ -34,20 +34,21 @@ typedef struct semaphore sema_t;
 #define initnsema(sp, val, name)       sema_init(sp, val)
 #define psema(sp, b)                   down(sp)
 #define vsema(sp)                      up(sp)
-#define valusema(sp)                   (atomic_read(&(sp)->count))
-#define freesema(sema)
+#define freesema(sema)                 do { } while (0)
+
+static inline int issemalocked(sema_t *sp)
+{
+       return down_trylock(sp) || (up(sp), 0);
+}
 
 /*
  * Map cpsema (try to get the sema) to down_trylock. We need to switch
  * the return values since cpsema returns 1 (acquired) 0 (failed) and
  * down_trylock returns the reverse 0 (acquired) 1 (failed).
  */
-
-#define cpsema(sp)                     (down_trylock(sp) ? 0 : 1)
-
-/*
- * Didn't do cvsema(sp). Not sure how to map this to up/down/...
- * It does a vsema if the values is < 0 other wise nothing.
- */
+static inline int cpsema(sema_t *sp)
+{
+       return down_trylock(sp) ? 0 : 1;
+}
 
 #endif /* __XFS_SUPPORT_SEMA_H__ */
index 4d191ef39b67a62abd3171ec5499f8868727b37f..3e807b828e221464131d088367496f86f54bb033 100644 (file)
@@ -21,7 +21,6 @@
 #include "xfs_inum.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_trans.h"
 #include "xfs_dmapi.h"
@@ -29,7 +28,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -76,7 +74,7 @@ xfs_page_trace(
        int             mask)
 {
        xfs_inode_t     *ip;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        loff_t          isize = i_size_read(inode);
        loff_t          offset = page_offset(page);
        int             delalloc = -1, unmapped = -1, unwritten = -1;
@@ -136,9 +134,10 @@ xfs_destroy_ioend(
 
        for (bh = ioend->io_buffer_head; bh; bh = next) {
                next = bh->b_private;
-               bh->b_end_io(bh, ioend->io_uptodate);
+               bh->b_end_io(bh, !ioend->io_error);
        }
-
+       if (unlikely(ioend->io_error))
+               vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
        vn_iowake(ioend->io_vnode);
        mempool_free(ioend, xfs_ioend_pool);
 }
@@ -180,13 +179,12 @@ xfs_end_bio_unwritten(
        void                    *data)
 {
        xfs_ioend_t             *ioend = data;
-       vnode_t                 *vp = ioend->io_vnode;
+       bhv_vnode_t             *vp = ioend->io_vnode;
        xfs_off_t               offset = ioend->io_offset;
        size_t                  size = ioend->io_size;
-       int                     error;
 
-       if (ioend->io_uptodate)
-               VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
+       if (likely(!ioend->io_error))
+               bhv_vop_bmap(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL);
        xfs_destroy_ioend(ioend);
 }
 
@@ -211,7 +209,7 @@ xfs_alloc_ioend(
         * all the I/O from calling the completion routine too early.
         */
        atomic_set(&ioend->io_remaining, 1);
-       ioend->io_uptodate = 1; /* cleared if any I/O fails */
+       ioend->io_error = 0;
        ioend->io_list = NULL;
        ioend->io_type = type;
        ioend->io_vnode = vn_from_inode(inode);
@@ -239,10 +237,10 @@ xfs_map_blocks(
        xfs_iomap_t             *mapp,
        int                     flags)
 {
-       vnode_t                 *vp = vn_from_inode(inode);
+       bhv_vnode_t             *vp = vn_from_inode(inode);
        int                     error, nmaps = 1;
 
-       VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
+       error = bhv_vop_bmap(vp, offset, count, flags, mapp, &nmaps);
        if (!error && (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)))
                VMODIFY(vp);
        return -error;
@@ -271,16 +269,14 @@ xfs_end_bio(
        if (bio->bi_size)
                return 1;
 
-       ASSERT(ioend);
        ASSERT(atomic_read(&bio->bi_cnt) >= 1);
+       ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
 
        /* Toss bio and pass work off to an xfsdatad thread */
-       if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
-               ioend->io_uptodate = 0;
        bio->bi_private = NULL;
        bio->bi_end_io = NULL;
-
        bio_put(bio);
+
        xfs_finish_ioend(ioend);
        return 0;
 }
@@ -1127,7 +1123,7 @@ xfs_vm_writepage(
         * then mark the page dirty again and leave the page
         * as is.
         */
-       if (PFLAGS_TEST_FSTRANS() && need_trans)
+       if (current_test_flags(PF_FSTRANS) && need_trans)
                goto out_fail;
 
        /*
@@ -1158,6 +1154,18 @@ out_unlock:
        return error;
 }
 
+STATIC int
+xfs_vm_writepages(
+       struct address_space    *mapping,
+       struct writeback_control *wbc)
+{
+       struct bhv_vnode        *vp = vn_from_inode(mapping->host);
+
+       if (VN_TRUNC(vp))
+               VUNTRUNCATE(vp);
+       return generic_writepages(mapping, wbc);
+}
+
 /*
  * Called to move a page into cleanable state - and from there
  * to be released. Possibly the page is already clean. We always
@@ -1204,7 +1212,7 @@ xfs_vm_releasepage(
        /* If we are already inside a transaction or the thread cannot
         * do I/O, we cannot release this page.
         */
-       if (PFLAGS_TEST_FSTRANS())
+       if (current_test_flags(PF_FSTRANS))
                return 0;
 
        /*
@@ -1231,7 +1239,7 @@ __xfs_get_blocks(
        int                     direct,
        bmapi_flags_t           flags)
 {
-       vnode_t                 *vp = vn_from_inode(inode);
+       bhv_vnode_t             *vp = vn_from_inode(inode);
        xfs_iomap_t             iomap;
        xfs_off_t               offset;
        ssize_t                 size;
@@ -1241,8 +1249,8 @@ __xfs_get_blocks(
        offset = (xfs_off_t)iblock << inode->i_blkbits;
        ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
        size = bh_result->b_size;
-       VOP_BMAP(vp, offset, size,
-               create ? flags : BMAPI_READ, &iomap, &niomap, error);
+       error = bhv_vop_bmap(vp, offset, size,
+                            create ? flags : BMAPI_READ, &iomap, &niomap);
        if (error)
                return -error;
        if (niomap == 0)
@@ -1370,13 +1378,13 @@ xfs_vm_direct_IO(
 {
        struct file     *file = iocb->ki_filp;
        struct inode    *inode = file->f_mapping->host;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        xfs_iomap_t     iomap;
        int             maps = 1;
        int             error;
        ssize_t         ret;
 
-       VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
+       error = bhv_vop_bmap(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps);
        if (error)
                return -error;
 
@@ -1409,14 +1417,12 @@ xfs_vm_bmap(
        sector_t                block)
 {
        struct inode            *inode = (struct inode *)mapping->host;
-       vnode_t                 *vp = vn_from_inode(inode);
-       int                     error;
+       bhv_vnode_t             *vp = vn_from_inode(inode);
 
        vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
-
-       VOP_RWLOCK(vp, VRWLOCK_READ);
-       VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
-       VOP_RWUNLOCK(vp, VRWLOCK_READ);
+       bhv_vop_rwlock(vp, VRWLOCK_READ);
+       bhv_vop_flush_pages(vp, (xfs_off_t)0, -1, 0, FI_REMAPF);
+       bhv_vop_rwunlock(vp, VRWLOCK_READ);
        return generic_block_bmap(mapping, block, xfs_get_blocks);
 }
 
@@ -1452,6 +1458,7 @@ struct address_space_operations xfs_address_space_operations = {
        .readpage               = xfs_vm_readpage,
        .readpages              = xfs_vm_readpages,
        .writepage              = xfs_vm_writepage,
+       .writepages             = xfs_vm_writepages,
        .sync_page              = block_sync_page,
        .releasepage            = xfs_vm_releasepage,
        .invalidatepage         = xfs_vm_invalidatepage,
index 60716543c68b2b793f8146b4a099b2345f41069c..706d8c781b8a54b474f7a3d5ecb23a42bf8e8352 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005 Silicon Graphics, Inc.
+ * Copyright (c) 2005-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -30,9 +30,9 @@ typedef void (*xfs_ioend_func_t)(void *);
 typedef struct xfs_ioend {
        struct xfs_ioend        *io_list;       /* next ioend in chain */
        unsigned int            io_type;        /* delalloc / unwritten */
-       unsigned int            io_uptodate;    /* I/O status register */
+       int                     io_error;       /* I/O error code */
        atomic_t                io_remaining;   /* hold count */
-       struct vnode            *io_vnode;      /* file being written to */
+       struct bhv_vnode        *io_vnode;      /* file being written to */
        struct buffer_head      *io_buffer_head;/* buffer linked list head */
        struct buffer_head      *io_buffer_tail;/* buffer linked list tail */
        size_t                  io_size;        /* size of the extent */
@@ -43,4 +43,4 @@ typedef struct xfs_ioend {
 extern struct address_space_operations xfs_address_space_operations;
 extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
 
-#endif /* __XFS_IOPS_H__ */
+#endif /* __XFS_AOPS_H__ */
index b768ea910bbe00e3741ca9cec61b21cb06a3d9e5..5fb75d9151f20899f69c1608728f393843a0371d 100644 (file)
@@ -21,7 +21,6 @@
 #include "xfs_log.h"
 #include "xfs_trans.h"
 #include "xfs_sb.h"
-#include "xfs_dir.h"
 #include "xfs_mount.h"
 #include "xfs_export.h"
 
@@ -97,7 +96,7 @@ xfs_fs_encode_fh(
        int                     len;
        int                     is64 = 0;
 #if XFS_BIG_INUMS
-       vfs_t                   *vfs = vfs_from_sb(inode->i_sb);
+       bhv_vfs_t               *vfs = vfs_from_sb(inode->i_sb);
 
        if (!(vfs->vfs_flag & VFS_32BITINODES)) {
                /* filesystem may contain 64bit inode numbers */
@@ -136,13 +135,13 @@ xfs_fs_get_dentry(
        struct super_block      *sb,
        void                    *data)
 {
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        struct inode            *inode;
        struct dentry           *result;
-       vfs_t                   *vfsp = vfs_from_sb(sb);
+       bhv_vfs_t               *vfsp = vfs_from_sb(sb);
        int                     error;
 
-       VFS_VGET(vfsp, &vp, (fid_t *)data, error);
+       error = bhv_vfs_vget(vfsp, &vp, (fid_t *)data);
        if (error || vp == NULL)
                return ERR_PTR(-ESTALE) ;
 
@@ -160,12 +159,12 @@ xfs_fs_get_parent(
        struct dentry           *child)
 {
        int                     error;
-       vnode_t                 *vp, *cvp;
+       bhv_vnode_t             *vp, *cvp;
        struct dentry           *parent;
 
        cvp = NULL;
        vp = vn_from_inode(child->d_inode);
-       VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
+       error = bhv_vop_lookup(vp, &dotdot, &cvp, 0, NULL, NULL);
        if (unlikely(error))
                return ERR_PTR(-error);
 
index c847416f6d1010ac9ffea5ad764661662472632a..70662371bb11fda80e1be225a9bf32b159595491 100644 (file)
@@ -21,7 +21,6 @@
 #include "xfs_inum.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_trans.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_alloc.h"
 #include "xfs_btree.h"
 #include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
@@ -58,15 +56,12 @@ __xfs_file_read(
 {
        struct iovec            iov = {buf, count};
        struct file             *file = iocb->ki_filp;
-       vnode_t                 *vp = vn_from_inode(file->f_dentry->d_inode);
-       ssize_t                 rval;
+       bhv_vnode_t             *vp = vn_from_inode(file->f_dentry->d_inode);
 
        BUG_ON(iocb->ki_pos != pos);
-
        if (unlikely(file->f_flags & O_DIRECT))
                ioflags |= IO_ISDIRECT;
-       VOP_READ(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
-       return rval;
+       return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
 }
 
 STATIC ssize_t
@@ -100,15 +95,12 @@ __xfs_file_write(
        struct iovec    iov = {(void __user *)buf, count};
        struct file     *file = iocb->ki_filp;
        struct inode    *inode = file->f_mapping->host;
-       vnode_t         *vp = vn_from_inode(inode);
-       ssize_t         rval;
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
        BUG_ON(iocb->ki_pos != pos);
        if (unlikely(file->f_flags & O_DIRECT))
                ioflags |= IO_ISDIRECT;
-
-       VOP_WRITE(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL, rval);
-       return rval;
+       return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL);
 }
 
 STATIC ssize_t
@@ -140,7 +132,7 @@ __xfs_file_readv(
        loff_t                  *ppos)
 {
        struct inode    *inode = file->f_mapping->host;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        struct kiocb    kiocb;
        ssize_t         rval;
 
@@ -149,7 +141,8 @@ __xfs_file_readv(
 
        if (unlikely(file->f_flags & O_DIRECT))
                ioflags |= IO_ISDIRECT;
-       VOP_READ(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
+       rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
+                               &kiocb.ki_pos, ioflags, NULL);
 
        *ppos = kiocb.ki_pos;
        return rval;
@@ -184,7 +177,7 @@ __xfs_file_writev(
        loff_t                  *ppos)
 {
        struct inode    *inode = file->f_mapping->host;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        struct kiocb    kiocb;
        ssize_t         rval;
 
@@ -193,7 +186,8 @@ __xfs_file_writev(
        if (unlikely(file->f_flags & O_DIRECT))
                ioflags |= IO_ISDIRECT;
 
-       VOP_WRITE(vp, &kiocb, iov, nr_segs, &kiocb.ki_pos, ioflags, NULL, rval);
+       rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
+                                &kiocb.ki_pos, ioflags, NULL);
 
        *ppos = kiocb.ki_pos;
        return rval;
@@ -227,11 +221,8 @@ xfs_file_sendfile(
        read_actor_t            actor,
        void                    *target)
 {
-       vnode_t                 *vp = vn_from_inode(filp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
-       return rval;
+       return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
+                               filp, pos, 0, count, actor, target, NULL);
 }
 
 STATIC ssize_t
@@ -242,11 +233,8 @@ xfs_file_sendfile_invis(
        read_actor_t            actor,
        void                    *target)
 {
-       vnode_t                 *vp = vn_from_inode(filp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
-       return rval;
+       return bhv_vop_sendfile(vn_from_inode(filp->f_dentry->d_inode),
+                               filp, pos, IO_INVIS, count, actor, target, NULL);
 }
 
 STATIC ssize_t
@@ -257,11 +245,8 @@ xfs_file_splice_read(
        size_t                  len,
        unsigned int            flags)
 {
-       vnode_t                 *vp = vn_from_inode(infilp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, 0, NULL, rval);
-       return rval;
+       return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
+                                  infilp, ppos, pipe, len, flags, 0, NULL);
 }
 
 STATIC ssize_t
@@ -272,11 +257,9 @@ xfs_file_splice_read_invis(
        size_t                  len,
        unsigned int            flags)
 {
-       vnode_t                 *vp = vn_from_inode(infilp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SPLICE_READ(vp, infilp, ppos, pipe, len, flags, IO_INVIS, NULL, rval);
-       return rval;
+       return bhv_vop_splice_read(vn_from_inode(infilp->f_dentry->d_inode),
+                                  infilp, ppos, pipe, len, flags, IO_INVIS,
+                                  NULL);
 }
 
 STATIC ssize_t
@@ -287,11 +270,8 @@ xfs_file_splice_write(
        size_t                  len,
        unsigned int            flags)
 {
-       vnode_t                 *vp = vn_from_inode(outfilp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, 0, NULL, rval);
-       return rval;
+       return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
+                                   pipe, outfilp, ppos, len, flags, 0, NULL);
 }
 
 STATIC ssize_t
@@ -302,11 +282,9 @@ xfs_file_splice_write_invis(
        size_t                  len,
        unsigned int            flags)
 {
-       vnode_t                 *vp = vn_from_inode(outfilp->f_dentry->d_inode);
-       ssize_t                 rval;
-
-       VOP_SPLICE_WRITE(vp, pipe, outfilp, ppos, len, flags, IO_INVIS, NULL, rval);
-       return rval;
+       return bhv_vop_splice_write(vn_from_inode(outfilp->f_dentry->d_inode),
+                                   pipe, outfilp, ppos, len, flags, IO_INVIS,
+                                   NULL);
 }
 
 STATIC int
@@ -314,13 +292,17 @@ xfs_file_open(
        struct inode    *inode,
        struct file     *filp)
 {
-       vnode_t         *vp = vn_from_inode(inode);
-       int             error;
-
        if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
                return -EFBIG;
-       VOP_OPEN(vp, NULL, error);
-       return -error;
+       return -bhv_vop_open(vn_from_inode(inode), NULL);
+}
+
+STATIC int
+xfs_file_close(
+       struct file     *filp)
+{
+       return -bhv_vop_close(vn_from_inode(filp->f_dentry->d_inode), 0,
+                               file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
 }
 
 STATIC int
@@ -328,12 +310,11 @@ xfs_file_release(
        struct inode    *inode,
        struct file     *filp)
 {
-       vnode_t         *vp = vn_from_inode(inode);
-       int             error = 0;
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
        if (vp)
-               VOP_RELEASE(vp, error);
-       return -error;
+               return -bhv_vop_release(vp);
+       return 0;
 }
 
 STATIC int
@@ -342,15 +323,14 @@ xfs_file_fsync(
        struct dentry   *dentry,
        int             datasync)
 {
-       struct inode    *inode = dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
-       int             error;
+       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
        int             flags = FSYNC_WAIT;
 
        if (datasync)
                flags |= FSYNC_DATA;
-       VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
-       return -error;
+       if (VN_TRUNC(vp))
+               VUNTRUNCATE(vp);
+       return -bhv_vop_fsync(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1);
 }
 
 #ifdef CONFIG_XFS_DMAPI
@@ -361,16 +341,11 @@ xfs_vm_nopage(
        int                     *type)
 {
        struct inode    *inode = area->vm_file->f_dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
-       xfs_mount_t     *mp = XFS_VFSTOM(vp->v_vfsp);
-       int             error;
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
        ASSERT_ALWAYS(vp->v_vfsp->vfs_flag & VFS_DMI);
-
-       error = XFS_SEND_MMAP(mp, area, 0);
-       if (error)
+       if (XFS_SEND_MMAP(XFS_VFSTOM(vp->v_vfsp), area, 0))
                return NULL;
-
        return filemap_nopage(area, address, type);
 }
 #endif /* CONFIG_XFS_DMAPI */
@@ -382,7 +357,7 @@ xfs_file_readdir(
        filldir_t       filldir)
 {
        int             error = 0;
-       vnode_t         *vp = vn_from_inode(filp->f_dentry->d_inode);
+       bhv_vnode_t     *vp = vn_from_inode(filp->f_dentry->d_inode);
        uio_t           uio;
        iovec_t         iov;
        int             eof = 0;
@@ -417,7 +392,7 @@ xfs_file_readdir(
 
                start_offset = uio.uio_offset;
 
-               VOP_READDIR(vp, &uio, NULL, &eof, error);
+               error = bhv_vop_readdir(vp, &uio, NULL, &eof);
                if ((uio.uio_offset == start_offset) || error) {
                        size = 0;
                        break;
@@ -456,38 +431,28 @@ xfs_file_mmap(
        struct file     *filp,
        struct vm_area_struct *vma)
 {
-       struct inode    *ip = filp->f_dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(ip);
-       vattr_t         vattr;
-       int             error;
-
        vma->vm_ops = &xfs_file_vm_ops;
 
 #ifdef CONFIG_XFS_DMAPI
-       if (vp->v_vfsp->vfs_flag & VFS_DMI) {
+       if (vn_from_inode(filp->f_dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
                vma->vm_ops = &xfs_dmapi_file_vm_ops;
-       }
 #endif /* CONFIG_XFS_DMAPI */
 
-       vattr.va_mask = XFS_AT_UPDATIME;
-       VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
-       if (likely(!error))
-               __vn_revalidate(vp, &vattr);    /* update flags */
+       file_accessed(filp);
        return 0;
 }
 
-
 STATIC long
 xfs_file_ioctl(
        struct file     *filp,
        unsigned int    cmd,
-       unsigned long   arg)
+       unsigned long   p)
 {
        int             error;
        struct inode    *inode = filp->f_dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
-       VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
+       error = bhv_vop_ioctl(vp, inode, filp, 0, cmd, (void __user *)p);
        VMODIFY(vp);
 
        /* NOTE:  some of the ioctl's return positive #'s as a
@@ -503,13 +468,13 @@ STATIC long
 xfs_file_ioctl_invis(
        struct file     *filp,
        unsigned int    cmd,
-       unsigned long   arg)
+       unsigned long   p)
 {
-       struct inode    *inode = filp->f_dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
        int             error;
+       struct inode    *inode = filp->f_dentry->d_inode;
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
-       VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
+       error = bhv_vop_ioctl(vp, inode, filp, IO_INVIS, cmd, (void __user *)p);
        VMODIFY(vp);
 
        /* NOTE:  some of the ioctl's return positive #'s as a
@@ -528,7 +493,7 @@ xfs_vm_mprotect(
        struct vm_area_struct *vma,
        unsigned int    newflags)
 {
-       vnode_t         *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
+       bhv_vnode_t     *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
        int             error = 0;
 
        if (vp->v_vfsp->vfs_flag & VFS_DMI) {
@@ -554,24 +519,19 @@ STATIC int
 xfs_file_open_exec(
        struct inode    *inode)
 {
-       vnode_t         *vp = vn_from_inode(inode);
-       xfs_mount_t     *mp = XFS_VFSTOM(vp->v_vfsp);
-       int             error = 0;
-       xfs_inode_t     *ip;
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
-       if (vp->v_vfsp->vfs_flag & VFS_DMI) {
-               ip = xfs_vtoi(vp);
-               if (!ip) {
-                       error = -EINVAL;
-                       goto open_exec_out;
-               }
-               if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ)) {
-                       error = -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
+       if (unlikely(vp->v_vfsp->vfs_flag & VFS_DMI)) {
+               xfs_mount_t     *mp = XFS_VFSTOM(vp->v_vfsp);
+               xfs_inode_t     *ip = xfs_vtoi(vp);
+
+               if (!ip)
+                       return -EINVAL;
+               if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ))
+                       return -XFS_SEND_DATA(mp, DM_EVENT_READ, vp,
                                               0, 0, 0, NULL);
-               }
        }
-open_exec_out:
-       return error;
+       return 0;
 }
 #endif /* HAVE_FOP_OPEN_EXEC */
 
@@ -592,6 +552,7 @@ const struct file_operations xfs_file_operations = {
 #endif
        .mmap           = xfs_file_mmap,
        .open           = xfs_file_open,
+       .flush          = xfs_file_close,
        .release        = xfs_file_release,
        .fsync          = xfs_file_fsync,
 #ifdef HAVE_FOP_OPEN_EXEC
@@ -616,6 +577,7 @@ const struct file_operations xfs_invis_file_operations = {
 #endif
        .mmap           = xfs_file_mmap,
        .open           = xfs_file_open,
+       .flush          = xfs_file_close,
        .release        = xfs_file_release,
        .fsync          = xfs_file_fsync,
 };
index 575f2a790f315e9ff84530ea39d4659c1135756e..dc0562828e760958b22242153111e928f317dbd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2002,2005-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
 #include "xfs.h"
 
-/*
- * Stub for no-op vnode operations that return error status.
- */
-int
-fs_noerr(void)
-{
-       return 0;
-}
+int  fs_noerr(void) { return 0; }
+int  fs_nosys(void) { return ENOSYS; }
+void fs_noval(void) { return; }
 
-/*
- * Operation unsupported under this file system.
- */
-int
-fs_nosys(void)
-{
-       return ENOSYS;
-}
-
-/*
- * Stub for inactive, strategy, and read/write lock/unlock.  Does nothing.
- */
-/* ARGSUSED */
-void
-fs_noval(void)
-{
-}
-
-/*
- * vnode pcache layer for vnode_tosspages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
 void
 fs_tosspages(
        bhv_desc_t      *bdp,
@@ -56,18 +28,13 @@ fs_tosspages(
        xfs_off_t       last,
        int             fiopt)
 {
-       vnode_t         *vp = BHV_TO_VNODE(bdp);
+       bhv_vnode_t     *vp = BHV_TO_VNODE(bdp);
        struct inode    *ip = vn_to_inode(vp);
 
        if (VN_CACHED(vp))
                truncate_inode_pages(ip->i_mapping, first);
 }
 
-
-/*
- * vnode pcache layer for vnode_flushinval_pages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
 void
 fs_flushinval_pages(
        bhv_desc_t      *bdp,
@@ -75,20 +42,17 @@ fs_flushinval_pages(
        xfs_off_t       last,
        int             fiopt)
 {
-       vnode_t         *vp = BHV_TO_VNODE(bdp);
+       bhv_vnode_t     *vp = BHV_TO_VNODE(bdp);
        struct inode    *ip = vn_to_inode(vp);
 
        if (VN_CACHED(vp)) {
+               if (VN_TRUNC(vp))
+                       VUNTRUNCATE(vp);
                filemap_write_and_wait(ip->i_mapping);
-
                truncate_inode_pages(ip->i_mapping, first);
        }
 }
 
-/*
- * vnode pcache layer for vnode_flush_pages.
- * 'last' parameter unused but left in for IRIX compatibility
- */
 int
 fs_flush_pages(
        bhv_desc_t      *bdp,
@@ -97,15 +61,16 @@ fs_flush_pages(
        uint64_t        flags,
        int             fiopt)
 {
-       vnode_t         *vp = BHV_TO_VNODE(bdp);
+       bhv_vnode_t     *vp = BHV_TO_VNODE(bdp);
        struct inode    *ip = vn_to_inode(vp);
 
-       if (VN_CACHED(vp)) {
+       if (VN_DIRTY(vp)) {
+               if (VN_TRUNC(vp))
+                       VUNTRUNCATE(vp);
                filemap_fdatawrite(ip->i_mapping);
                if (flags & XFS_B_ASYNC)
                        return 0;
                filemap_fdatawait(ip->i_mapping);
        }
-
        return 0;
 }
index 6e8085f346357679a89e3c2292ced09ed61e8fa7..6c162c3dde7efb44ee4f1abbb430591974244b82 100644 (file)
@@ -45,6 +45,7 @@ xfs_param_t xfs_params = {
        .xfs_buf_age    = {     1*100,          15*100,         7200*100},
        .inherit_nosym  = {     0,              0,              1       },
        .rotorstep      = {     1,              1,              255     },
+       .inherit_nodfrg = {     0,              1,              1       },
 };
 
 /*
index 84478491609b8e8566cbab3779cd38c1306f7130..6e52a5dd38d86333cd50ede6dfbe4a9c74e9c2f1 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -31,7 +30,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_dinode.h"
@@ -78,7 +76,7 @@ xfs_find_handle(
        xfs_handle_t            handle;
        xfs_fsop_handlereq_t    hreq;
        struct inode            *inode;
-       struct vnode            *vp;
+       bhv_vnode_t             *vp;
 
        if (copy_from_user(&hreq, arg, sizeof(hreq)))
                return -XFS_ERROR(EFAULT);
@@ -192,7 +190,7 @@ xfs_vget_fsop_handlereq(
        xfs_mount_t             *mp,
        struct inode            *parinode,      /* parent inode pointer    */
        xfs_fsop_handlereq_t    *hreq,
-       vnode_t                 **vp,
+       bhv_vnode_t             **vp,
        struct inode            **inode)
 {
        void                    __user *hanp;
@@ -202,7 +200,7 @@ xfs_vget_fsop_handlereq(
        xfs_handle_t            handle;
        xfs_inode_t             *ip;
        struct inode            *inodep;
-       vnode_t                 *vpp;
+       bhv_vnode_t             *vpp;
        xfs_ino_t               ino;
        __u32                   igen;
        int                     error;
@@ -277,7 +275,7 @@ xfs_open_by_handle(
        struct file             *filp;
        struct inode            *inode;
        struct dentry           *dentry;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        xfs_fsop_handlereq_t    hreq;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -362,7 +360,7 @@ xfs_readlink_by_handle(
        struct uio              auio;
        struct inode            *inode;
        xfs_fsop_handlereq_t    hreq;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        __u32                   olen;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -393,9 +391,11 @@ xfs_readlink_by_handle(
        auio.uio_segflg = UIO_USERSPACE;
        auio.uio_resid  = olen;
 
-       VOP_READLINK(vp, &auio, IO_INVIS, NULL, error);
-
+       error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
        VN_RELE(vp);
+       if (error)
+               return -error;
+
        return (olen - auio.uio_resid);
 }
 
@@ -411,7 +411,7 @@ xfs_fssetdm_by_handle(
        xfs_fsop_setdm_handlereq_t dmhreq;
        struct inode            *inode;
        bhv_desc_t              *bdp;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
 
        if (!capable(CAP_MKNOD))
                return -XFS_ERROR(EPERM);
@@ -452,7 +452,7 @@ xfs_attrlist_by_handle(
        attrlist_cursor_kern_t  *cursor;
        xfs_fsop_attrlist_handlereq_t al_hreq;
        struct inode            *inode;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        char                    *kbuf;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -472,8 +472,8 @@ xfs_attrlist_by_handle(
                goto out_vn_rele;
 
        cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-       VOP_ATTR_LIST(vp, kbuf, al_hreq.buflen, al_hreq.flags,
-                       cursor, NULL, error);
+       error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
+                                       cursor, NULL);
        if (error)
                goto out_kfree;
 
@@ -490,7 +490,7 @@ xfs_attrlist_by_handle(
 
 STATIC int
 xfs_attrmulti_attr_get(
-       struct vnode            *vp,
+       bhv_vnode_t             *vp,
        char                    *name,
        char                    __user *ubuf,
        __uint32_t              *len,
@@ -505,7 +505,7 @@ xfs_attrmulti_attr_get(
        if (!kbuf)
                return ENOMEM;
 
-       VOP_ATTR_GET(vp, name, kbuf, len, flags, NULL, error);
+       error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
        if (error)
                goto out_kfree;
 
@@ -519,7 +519,7 @@ xfs_attrmulti_attr_get(
 
 STATIC int
 xfs_attrmulti_attr_set(
-       struct vnode            *vp,
+       bhv_vnode_t             *vp,
        char                    *name,
        const char              __user *ubuf,
        __uint32_t              len,
@@ -542,7 +542,7 @@ xfs_attrmulti_attr_set(
        if (copy_from_user(kbuf, ubuf, len))
                goto out_kfree;
                        
-       VOP_ATTR_SET(vp, name, kbuf, len, flags, NULL, error);
+       error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
 
  out_kfree:
        kfree(kbuf);
@@ -551,20 +551,15 @@ xfs_attrmulti_attr_set(
 
 STATIC int
 xfs_attrmulti_attr_remove(
-       struct vnode            *vp,
+       bhv_vnode_t             *vp,
        char                    *name,
        __uint32_t              flags)
 {
-       int                     error;
-
-
        if (IS_RDONLY(&vp->v_inode))
                return -EROFS;
        if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
                return EPERM;
-
-       VOP_ATTR_REMOVE(vp, name, flags, NULL, error);
-       return error;
+       return bhv_vop_attr_remove(vp, name, flags, NULL);
 }
 
 STATIC int
@@ -578,7 +573,7 @@ xfs_attrmulti_by_handle(
        xfs_attr_multiop_t      *ops;
        xfs_fsop_attrmulti_handlereq_t am_hreq;
        struct inode            *inode;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        unsigned int            i, size;
        char                    *attr_name;
 
@@ -658,7 +653,7 @@ xfs_attrmulti_by_handle(
 STATIC int
 xfs_ioc_space(
        bhv_desc_t              *bdp,
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        struct file             *filp,
        int                     flags,
        unsigned int            cmd,
@@ -682,7 +677,7 @@ xfs_ioc_fsgeometry(
 
 STATIC int
 xfs_ioc_xattr(
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        xfs_inode_t             *ip,
        struct file             *filp,
        unsigned int            cmd,
@@ -711,7 +706,7 @@ xfs_ioctl(
        void                    __user *arg)
 {
        int                     error;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        xfs_inode_t             *ip;
        xfs_mount_t             *mp;
 
@@ -962,7 +957,7 @@ xfs_ioctl(
 STATIC int
 xfs_ioc_space(
        bhv_desc_t              *bdp,
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        struct file             *filp,
        int                     ioflags,
        unsigned int            cmd,
@@ -1153,14 +1148,14 @@ xfs_di2lxflags(
 
 STATIC int
 xfs_ioc_xattr(
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        xfs_inode_t             *ip,
        struct file             *filp,
        unsigned int            cmd,
        void                    __user *arg)
 {
        struct fsxattr          fa;
-       struct vattr            *vattr;
+       struct bhv_vattr        *vattr;
        int                     error = 0;
        int                     attr_flags;
        unsigned int            flags;
@@ -1173,7 +1168,7 @@ xfs_ioc_xattr(
        case XFS_IOC_FSGETXATTR: {
                vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
                                 XFS_AT_NEXTENTS | XFS_AT_PROJID;
-               VOP_GETATTR(vp, vattr, 0, NULL, error);
+               error = bhv_vop_getattr(vp, vattr, 0, NULL);
                if (unlikely(error)) {
                        error = -error;
                        break;
@@ -1206,7 +1201,7 @@ xfs_ioc_xattr(
                vattr->va_extsize = fa.fsx_extsize;
                vattr->va_projid  = fa.fsx_projid;
 
-               VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
+               error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
                if (likely(!error))
                        __vn_revalidate(vp, vattr);     /* update flags */
                error = -error;
@@ -1216,7 +1211,7 @@ xfs_ioc_xattr(
        case XFS_IOC_FSGETXATTRA: {
                vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
                                 XFS_AT_ANEXTENTS | XFS_AT_PROJID;
-               VOP_GETATTR(vp, vattr, 0, NULL, error);
+               error = bhv_vop_getattr(vp, vattr, 0, NULL);
                if (unlikely(error)) {
                        error = -error;
                        break;
@@ -1262,7 +1257,7 @@ xfs_ioc_xattr(
                vattr->va_xflags = xfs_merge_ioc_xflags(flags,
                                                        xfs_ip2xflags(ip));
 
-               VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
+               error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
                if (likely(!error))
                        __vn_revalidate(vp, vattr);     /* update flags */
                error = -error;
index 251bfe451a3f696fc89be210eac27ac7cf04e19b..601f01c92f7f49afb49ce30f506571c5a126f2ca 100644 (file)
@@ -114,7 +114,7 @@ xfs_compat_ioctl(
        unsigned long   arg)
 {
        struct inode    *inode = file->f_dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        int             error;
 
        switch (cmd) {
@@ -193,7 +193,7 @@ xfs_compat_ioctl(
                return -ENOIOCTLCMD;
        }
 
-       VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error);
+       error = bhv_vop_ioctl(vp, inode, file, mode, cmd, (void __user *)arg);
        VMODIFY(vp);
 
        return error;
index 2e2e275c786f2e98f617ef7d720e1b0b617a4643..12810baeb5d4ad7e4c54c7690b08d2fa3fe9de1c 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -61,7 +59,7 @@
  */
 xfs_inode_t *
 xfs_vtoi(
-       struct vnode    *vp)
+       bhv_vnode_t     *vp)
 {
        bhv_desc_t      *bdp;
 
@@ -80,7 +78,7 @@ void
 xfs_synchronize_atime(
        xfs_inode_t     *ip)
 {
-       vnode_t         *vp;
+       bhv_vnode_t     *vp;
 
        vp = XFS_ITOV_NULL(ip);
        if (vp) {
@@ -200,14 +198,10 @@ xfs_ichgtime_fast(
 STATIC void
 xfs_validate_fields(
        struct inode    *ip,
-       struct vattr    *vattr)
+       bhv_vattr_t     *vattr)
 {
-       vnode_t         *vp = vn_from_inode(ip);
-       int             error;
-
        vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
-       VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error);
-       if (likely(!error)) {
+       if (!bhv_vop_getattr(vn_from_inode(ip), vattr, ATTR_LAZY, NULL)) {
                ip->i_nlink = vattr->va_nlink;
                ip->i_blocks = vattr->va_nblocks;
 
@@ -225,7 +219,7 @@ xfs_validate_fields(
  */
 STATIC int
 xfs_init_security(
-       struct vnode    *vp,
+       bhv_vnode_t     *vp,
        struct inode    *dir)
 {
        struct inode    *ip = vn_to_inode(vp);
@@ -241,7 +235,7 @@ xfs_init_security(
                return -error;
        }
 
-       VOP_ATTR_SET(vp, name, value, length, ATTR_SECURE, NULL, error);
+       error = bhv_vop_attr_set(vp, name, value, length, ATTR_SECURE, NULL);
        if (!error)
                VMODIFY(vp);
 
@@ -264,13 +258,12 @@ xfs_has_fs_struct(struct task_struct *task)
 
 STATIC inline void
 xfs_cleanup_inode(
-       vnode_t         *dvp,
-       vnode_t         *vp,
+       bhv_vnode_t     *dvp,
+       bhv_vnode_t     *vp,
        struct dentry   *dentry,
        int             mode)
 {
        struct dentry   teardown = {};
-       int             error;
 
        /* Oh, the horror.
         * If we can't add the ACL or we fail in
@@ -281,9 +274,9 @@ xfs_cleanup_inode(
        teardown.d_name = dentry->d_name;
 
        if (S_ISDIR(mode))
-               VOP_RMDIR(dvp, &teardown, NULL, error);
+               bhv_vop_rmdir(dvp, &teardown, NULL);
        else
-               VOP_REMOVE(dvp, &teardown, NULL, error);
+               bhv_vop_remove(dvp, &teardown, NULL);
        VN_RELE(vp);
 }
 
@@ -295,8 +288,8 @@ xfs_vn_mknod(
        dev_t           rdev)
 {
        struct inode    *ip;
-       vattr_t         vattr = { 0 };
-       vnode_t         *vp = NULL, *dvp = vn_from_inode(dir);
+       bhv_vattr_t     vattr = { 0 };
+       bhv_vnode_t     *vp = NULL, *dvp = vn_from_inode(dir);
        xfs_acl_t       *default_acl = NULL;
        attrexists_t    test_default_acl = _ACL_DEFAULT_EXISTS;
        int             error;
@@ -330,10 +323,10 @@ xfs_vn_mknod(
                vattr.va_mask |= XFS_AT_RDEV;
                /*FALLTHROUGH*/
        case S_IFREG:
-               VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error);
+               error = bhv_vop_create(dvp, dentry, &vattr, &vp, NULL);
                break;
        case S_IFDIR:
-               VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error);
+               error = bhv_vop_mkdir(dvp, dentry, &vattr, &vp, NULL);
                break;
        default:
                error = EINVAL;
@@ -396,14 +389,14 @@ xfs_vn_lookup(
        struct dentry   *dentry,
        struct nameidata *nd)
 {
-       struct vnode    *vp = vn_from_inode(dir), *cvp;
+       bhv_vnode_t     *vp = vn_from_inode(dir), *cvp;
        int             error;
 
        if (dentry->d_name.len >= MAXNAMELEN)
                return ERR_PTR(-ENAMETOOLONG);
 
-       VOP_LOOKUP(vp, dentry, &cvp, 0, NULL, NULL, error);
-       if (error) {
+       error = bhv_vop_lookup(vp, dentry, &cvp, 0, NULL, NULL);
+       if (unlikely(error)) {
                if (unlikely(error != ENOENT))
                        return ERR_PTR(-error);
                d_add(dentry, NULL);
@@ -420,9 +413,9 @@ xfs_vn_link(
        struct dentry   *dentry)
 {
        struct inode    *ip;    /* inode of guy being linked to */
-       vnode_t         *tdvp;  /* target directory for new name/link */
-       vnode_t         *vp;    /* vp of name being linked */
-       vattr_t         vattr;
+       bhv_vnode_t     *tdvp;  /* target directory for new name/link */
+       bhv_vnode_t     *vp;    /* vp of name being linked */
+       bhv_vattr_t     vattr;
        int             error;
 
        ip = old_dentry->d_inode;       /* inode being linked to */
@@ -432,7 +425,7 @@ xfs_vn_link(
        tdvp = vn_from_inode(dir);
        vp = vn_from_inode(ip);
 
-       VOP_LINK(tdvp, vp, dentry, NULL, error);
+       error = bhv_vop_link(tdvp, vp, dentry, NULL);
        if (likely(!error)) {
                VMODIFY(tdvp);
                VN_HOLD(vp);
@@ -448,14 +441,14 @@ xfs_vn_unlink(
        struct dentry   *dentry)
 {
        struct inode    *inode;
-       vnode_t         *dvp;   /* directory containing name to remove */
-       vattr_t         vattr;
+       bhv_vnode_t     *dvp;   /* directory containing name to remove */
+       bhv_vattr_t     vattr;
        int             error;
 
        inode = dentry->d_inode;
        dvp = vn_from_inode(dir);
 
-       VOP_REMOVE(dvp, dentry, NULL, error);
+       error = bhv_vop_remove(dvp, dentry, NULL);
        if (likely(!error)) {
                xfs_validate_fields(dir, &vattr);       /* size needs update */
                xfs_validate_fields(inode, &vattr);
@@ -470,27 +463,26 @@ xfs_vn_symlink(
        const char      *symname)
 {
        struct inode    *ip;
-       vattr_t         vattr = { 0 };
-       vnode_t         *dvp;   /* directory containing name of symlink */
-       vnode_t         *cvp;   /* used to lookup symlink to put in dentry */
+       bhv_vattr_t     va = { 0 };
+       bhv_vnode_t     *dvp;   /* directory containing name of symlink */
+       bhv_vnode_t     *cvp;   /* used to lookup symlink to put in dentry */
        int             error;
 
        dvp = vn_from_inode(dir);
        cvp = NULL;
 
-       vattr.va_mode = S_IFLNK |
+       va.va_mode = S_IFLNK |
                (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
-       vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
+       va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
 
-       error = 0;
-       VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
+       error = bhv_vop_symlink(dvp, dentry, &va, (char *)symname, &cvp, NULL);
        if (likely(!error && cvp)) {
                error = xfs_init_security(cvp, dir);
                if (likely(!error)) {
                        ip = vn_to_inode(cvp);
                        d_instantiate(dentry, ip);
-                       xfs_validate_fields(dir, &vattr);
-                       xfs_validate_fields(ip, &vattr);
+                       xfs_validate_fields(dir, &va);
+                       xfs_validate_fields(ip, &va);
                } else {
                        xfs_cleanup_inode(dvp, cvp, dentry, 0);
                }
@@ -504,11 +496,11 @@ xfs_vn_rmdir(
        struct dentry   *dentry)
 {
        struct inode    *inode = dentry->d_inode;
-       vnode_t         *dvp = vn_from_inode(dir);
-       vattr_t         vattr;
+       bhv_vnode_t     *dvp = vn_from_inode(dir);
+       bhv_vattr_t     vattr;
        int             error;
 
-       VOP_RMDIR(dvp, dentry, NULL, error);
+       error = bhv_vop_rmdir(dvp, dentry, NULL);
        if (likely(!error)) {
                xfs_validate_fields(inode, &vattr);
                xfs_validate_fields(dir, &vattr);
@@ -524,15 +516,15 @@ xfs_vn_rename(
        struct dentry   *ndentry)
 {
        struct inode    *new_inode = ndentry->d_inode;
-       vnode_t         *fvp;   /* from directory */
-       vnode_t         *tvp;   /* target directory */
-       vattr_t         vattr;
+       bhv_vnode_t     *fvp;   /* from directory */
+       bhv_vnode_t     *tvp;   /* target directory */
+       bhv_vattr_t     vattr;
        int             error;
 
        fvp = vn_from_inode(odir);
        tvp = vn_from_inode(ndir);
 
-       VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
+       error = bhv_vop_rename(fvp, odentry, tvp, ndentry, NULL);
        if (likely(!error)) {
                if (new_inode)
                        xfs_validate_fields(new_inode, &vattr);
@@ -553,7 +545,7 @@ xfs_vn_follow_link(
        struct dentry           *dentry,
        struct nameidata        *nd)
 {
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        uio_t                   *uio;
        iovec_t                 iov;
        int                     error;
@@ -586,8 +578,8 @@ xfs_vn_follow_link(
        uio->uio_resid = MAXPATHLEN;
        uio->uio_iovcnt = 1;
 
-       VOP_READLINK(vp, uio, 0, NULL, error);
-       if (error) {
+       error = bhv_vop_readlink(vp, uio, 0, NULL);
+       if (unlikely(error)) {
                kfree(link);
                link = ERR_PTR(-error);
        } else {
@@ -618,12 +610,7 @@ xfs_vn_permission(
        int             mode,
        struct nameidata *nd)
 {
-       vnode_t         *vp = vn_from_inode(inode);
-       int             error;
-
-       mode <<= 6;             /* convert from linux to vnode access bits */
-       VOP_ACCESS(vp, mode, NULL, error);
-       return -error;
+       return -bhv_vop_access(vn_from_inode(inode), mode << 6, NULL);
 }
 #else
 #define xfs_vn_permission NULL
@@ -636,14 +623,14 @@ xfs_vn_getattr(
        struct kstat    *stat)
 {
        struct inode    *inode = dentry->d_inode;
-       vnode_t         *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
        int             error = 0;
 
        if (unlikely(vp->v_flag & VMODIFIED))
                error = vn_revalidate(vp);
        if (!error)
                generic_fillattr(inode, stat);
-       return 0;
+       return -error;
 }
 
 STATIC int
@@ -653,8 +640,8 @@ xfs_vn_setattr(
 {
        struct inode    *inode = dentry->d_inode;
        unsigned int    ia_valid = attr->ia_valid;
-       vnode_t         *vp = vn_from_inode(inode);
-       vattr_t         vattr = { 0 };
+       bhv_vnode_t     *vp = vn_from_inode(inode);
+       bhv_vattr_t     vattr = { 0 };
        int             flags = 0;
        int             error;
 
@@ -697,7 +684,7 @@ xfs_vn_setattr(
                flags |= ATTR_NONBLOCK;
 #endif
 
-       VOP_SETATTR(vp, &vattr, flags, NULL, error);
+       error = bhv_vop_setattr(vp, &vattr, flags, NULL);
        if (likely(!error))
                __vn_revalidate(vp, &vattr);
        return -error;
@@ -718,7 +705,7 @@ xfs_vn_setxattr(
        size_t          size,
        int             flags)
 {
-       vnode_t         *vp = vn_from_inode(dentry->d_inode);
+       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
        char            *attr = (char *)name;
        attrnames_t     *namesp;
        int             xflags = 0;
@@ -748,7 +735,7 @@ xfs_vn_getxattr(
        void            *data,
        size_t          size)
 {
-       vnode_t         *vp = vn_from_inode(dentry->d_inode);
+       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
        char            *attr = (char *)name;
        attrnames_t     *namesp;
        int             xflags = 0;
@@ -777,7 +764,7 @@ xfs_vn_listxattr(
        char                    *data,
        size_t                  size)
 {
-       vnode_t                 *vp = vn_from_inode(dentry->d_inode);
+       bhv_vnode_t             *vp = vn_from_inode(dentry->d_inode);
        int                     error, xflags = ATTR_KERNAMELS;
        ssize_t                 result;
 
@@ -796,7 +783,7 @@ xfs_vn_removexattr(
        struct dentry   *dentry,
        const char      *name)
 {
-       vnode_t         *vp = vn_from_inode(dentry->d_inode);
+       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
        char            *attr = (char *)name;
        attrnames_t     *namesp;
        int             xflags = 0;
index e9fe43d74768a965f95a72c82741198bd9a65a15..aa26ab906c88cda071d9a2ca54cc79ee2cea6317 100644 (file)
@@ -134,14 +134,21 @@ BUFFER_FNS(PrivateStart, unwritten);
 #define xfs_buf_age_centisecs  xfs_params.xfs_buf_age.val
 #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
 #define xfs_rotorstep          xfs_params.rotorstep.val
+#define xfs_inherit_nodefrag   xfs_params.inherit_nodfrg.val
 
-#ifndef raw_smp_processor_id
-#define raw_smp_processor_id() smp_processor_id()
-#endif
-#define current_cpu()          raw_smp_processor_id()
+#define current_cpu()          (raw_smp_processor_id())
 #define current_pid()          (current->pid)
 #define current_fsuid(cred)    (current->fsuid)
 #define current_fsgid(cred)    (current->fsgid)
+#define current_set_flags(f)   (current->flags |= (f))
+#define current_test_flags(f)  (current->flags & (f))
+#define current_clear_flags(f) (current->flags & ~(f))
+#define current_set_flags_nested(sp, f)                \
+               (*(sp) = current->flags, current->flags |= (f))
+#define current_clear_flags_nested(sp, f)      \
+               (*(sp) = current->flags, current->flags &= ~(f))
+#define current_restore_flags_nested(sp, f)    \
+               (current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
 
 #define NBPP           PAGE_SIZE
 #define DPPSHFT                (PAGE_SHIFT - 9)
@@ -187,25 +194,9 @@ BUFFER_FNS(PrivateStart, unwritten);
 /* bytes to clicks */
 #define btoc(x)         (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
 
-#ifndef ENOATTR
 #define ENOATTR                ENODATA         /* Attribute not found */
-#endif
-
-/* Note: EWRONGFS never visible outside the kernel */
-#define        EWRONGFS        EINVAL          /* Mount with wrong filesystem type */
-
-/*
- * XXX EFSCORRUPTED needs a real value in errno.h. asm-i386/errno.h won't
- *     return codes out of its known range in errno.
- * XXX Also note: needs to be < 1000 and fairly unique on Linux (mustn't
- *     conflict with any code we use already or any code a driver may use)
- * XXX Some options (currently we do #2):
- *     1/ New error code ["Filesystem is corrupted", _after_ glibc updated]
- *     2/ 990 ["Unknown error 990"]
- *     3/ EUCLEAN ["Structure needs cleaning"]
- *     4/ Convert EFSCORRUPTED to EIO [just prior to return into userspace]
- */
-#define EFSCORRUPTED    990            /* Filesystem is corrupted */
+#define EWRONGFS       EINVAL          /* Mount with wrong filesystem type */
+#define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
 
 #define SYNCHRONIZE()  barrier()
 #define __return_address __builtin_return_address(0)
index 67efe3308980a0110030b58cbfca276a230ee32e..5d9cfd91ad08638012b8365d7d46b4c27959e936 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -206,7 +204,7 @@ xfs_read(
        xfs_fsize_t             n;
        xfs_inode_t             *ip;
        xfs_mount_t             *mp;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        unsigned long           seg;
 
        ip = XFS_BHVTOI(bdp);
@@ -258,7 +256,7 @@ xfs_read(
 
        if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
            !(ioflags & IO_INVIS)) {
-               vrwlock_t locktype = VRWLOCK_READ;
+               bhv_vrwlock_t locktype = VRWLOCK_READ;
                int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
 
                ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
@@ -271,7 +269,7 @@ xfs_read(
        }
 
        if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
-               VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)),
+               bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
                                                -1, FI_REMAPF_LOCKED);
 
        xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
@@ -313,7 +311,7 @@ xfs_sendfile(
 
        if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
            (!(ioflags & IO_INVIS))) {
-               vrwlock_t locktype = VRWLOCK_READ;
+               bhv_vrwlock_t locktype = VRWLOCK_READ;
                int error;
 
                error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -357,7 +355,7 @@ xfs_splice_read(
 
        if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
            (!(ioflags & IO_INVIS))) {
-               vrwlock_t locktype = VRWLOCK_READ;
+               bhv_vrwlock_t locktype = VRWLOCK_READ;
                int error;
 
                error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
@@ -401,7 +399,7 @@ xfs_splice_write(
 
        if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
            (!(ioflags & IO_INVIS))) {
-               vrwlock_t locktype = VRWLOCK_WRITE;
+               bhv_vrwlock_t locktype = VRWLOCK_WRITE;
                int error;
 
                error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
@@ -458,7 +456,7 @@ xfs_zero_last_block(
        last_fsb = XFS_B_TO_FSBT(mp, isize);
        nimaps = 1;
        error = XFS_BMAPI(mp, NULL, io, last_fsb, 1, 0, NULL, 0, &imap,
-                         &nimaps, NULL);
+                         &nimaps, NULL, NULL);
        if (error) {
                return error;
        }
@@ -499,7 +497,7 @@ xfs_zero_last_block(
 
 int                                    /* error (positive) */
 xfs_zero_eof(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_iocore_t    *io,
        xfs_off_t       offset,         /* starting I/O offset */
        xfs_fsize_t     isize,          /* current inode size */
@@ -510,7 +508,6 @@ xfs_zero_eof(
        xfs_fileoff_t   end_zero_fsb;
        xfs_fileoff_t   zero_count_fsb;
        xfs_fileoff_t   last_fsb;
-       xfs_extlen_t    buf_len_fsb;
        xfs_mount_t     *mp = io->io_mount;
        int             nimaps;
        int             error = 0;
@@ -556,7 +553,7 @@ xfs_zero_eof(
                nimaps = 1;
                zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
                error = XFS_BMAPI(mp, NULL, io, start_zero_fsb, zero_count_fsb,
-                                 0, NULL, 0, &imap, &nimaps, NULL);
+                                 0, NULL, 0, &imap, &nimaps, NULL, NULL);
                if (error) {
                        ASSERT(ismrlocked(io->io_lock, MR_UPDATE));
                        ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
@@ -579,16 +576,7 @@ xfs_zero_eof(
                }
 
                /*
-                * There are blocks in the range requested.
-                * Zero them a single write at a time.  We actually
-                * don't zero the entire range returned if it is
-                * too big and simply loop around to get the rest.
-                * That is not the most efficient thing to do, but it
-                * is simple and this path should not be exercised often.
-                */
-               buf_len_fsb = XFS_FILBLKS_MIN(imap.br_blockcount,
-                                             mp->m_writeio_blocks << 8);
-               /*
+                * There are blocks we need to zero.
                 * Drop the inode lock while we're doing the I/O.
                 * We'll still have the iolock to protect us.
                 */
@@ -596,14 +584,13 @@ xfs_zero_eof(
 
                error = xfs_iozero(ip,
                                   XFS_FSB_TO_B(mp, start_zero_fsb),
-                                  XFS_FSB_TO_B(mp, buf_len_fsb),
+                                  XFS_FSB_TO_B(mp, imap.br_blockcount),
                                   end_size);
-
                if (error) {
                        goto out_lock;
                }
 
-               start_zero_fsb = imap.br_startoff + buf_len_fsb;
+               start_zero_fsb = imap.br_startoff + imap.br_blockcount;
                ASSERT(start_zero_fsb <= (end_zero_fsb + 1));
 
                XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -637,11 +624,11 @@ xfs_write(
        ssize_t                 ret = 0, error = 0;
        xfs_fsize_t             isize, new_size;
        xfs_iocore_t            *io;
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
        unsigned long           seg;
        int                     iolock;
        int                     eventsent = 0;
-       vrwlock_t               locktype;
+       bhv_vrwlock_t           locktype;
        size_t                  ocount = 0, count;
        loff_t                  pos;
        int                     need_i_mutex = 1, need_flush = 0;
@@ -679,11 +666,11 @@ xfs_write(
        io = &xip->i_iocore;
        mp = io->io_mount;
 
+       vfs_wait_for_freeze(vp->v_vfsp, SB_FREEZE_WRITE);
+
        if (XFS_FORCED_SHUTDOWN(mp))
                return -EIO;
 
-       fs_check_frozen(vp->v_vfsp, SB_FREEZE_WRITE);
-
        if (ioflags & IO_ISDIRECT) {
                xfs_buftarg_t   *target =
                        (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
@@ -814,7 +801,7 @@ retry:
                if (need_flush) {
                        xfs_inval_cached_trace(io, pos, -1,
                                        ctooff(offtoct(pos)), -1);
-                       VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(pos)),
+                       bhv_vop_flushinval_pages(vp, ctooff(offtoct(pos)),
                                        -1, FI_REMAPF_LOCKED);
                }
 
@@ -903,79 +890,9 @@ retry:
 
        /* Handle various SYNC-type writes */
        if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
-               /*
-                * If we're treating this as O_DSYNC and we have not updated the
-                * size, force the log.
-                */
-               if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
-                   !(xip->i_update_size)) {
-                       xfs_inode_log_item_t    *iip = xip->i_itemp;
-
-                       /*
-                        * If an allocation transaction occurred
-                        * without extending the size, then we have to force
-                        * the log up the proper point to ensure that the
-                        * allocation is permanent.  We can't count on
-                        * the fact that buffered writes lock out direct I/O
-                        * writes - the direct I/O write could have extended
-                        * the size nontransactionally, then finished before
-                        * we started.  xfs_write_file will think that the file
-                        * didn't grow but the update isn't safe unless the
-                        * size change is logged.
-                        *
-                        * Force the log if we've committed a transaction
-                        * against the inode or if someone else has and
-                        * the commit record hasn't gone to disk (e.g.
-                        * the inode is pinned).  This guarantees that
-                        * all changes affecting the inode are permanent
-                        * when we return.
-                        */
-                       if (iip && iip->ili_last_lsn) {
-                               xfs_log_force(mp, iip->ili_last_lsn,
-                                               XFS_LOG_FORCE | XFS_LOG_SYNC);
-                       } else if (xfs_ipincount(xip) > 0) {
-                               xfs_log_force(mp, (xfs_lsn_t)0,
-                                               XFS_LOG_FORCE | XFS_LOG_SYNC);
-                       }
-
-               } else {
-                       xfs_trans_t     *tp;
-
-                       /*
-                        * O_SYNC or O_DSYNC _with_ a size update are handled
-                        * the same way.
-                        *
-                        * If the write was synchronous then we need to make
-                        * sure that the inode modification time is permanent.
-                        * We'll have updated the timestamp above, so here
-                        * we use a synchronous transaction to log the inode.
-                        * It's not fast, but it's necessary.
-                        *
-                        * If this a dsync write and the size got changed
-                        * non-transactionally, then we need to ensure that
-                        * the size change gets logged in a synchronous
-                        * transaction.
-                        */
-
-                       tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
-                       if ((error = xfs_trans_reserve(tp, 0,
-                                                     XFS_SWRITE_LOG_RES(mp),
-                                                     0, 0, 0))) {
-                               /* Transaction reserve failed */
-                               xfs_trans_cancel(tp, 0);
-                       } else {
-                               /* Transaction reserve successful */
-                               xfs_ilock(xip, XFS_ILOCK_EXCL);
-                               xfs_trans_ijoin(tp, xip, XFS_ILOCK_EXCL);
-                               xfs_trans_ihold(tp, xip);
-                               xfs_trans_log_inode(tp, xip, XFS_ILOG_CORE);
-                               xfs_trans_set_sync(tp);
-                               error = xfs_trans_commit(tp, 0, NULL);
-                               xfs_iunlock(xip, XFS_ILOCK_EXCL);
-                       }
-                       if (error)
-                               goto out_unlock_internal;
-               }
+               error = xfs_write_sync_logforce(mp, xip);
+               if (error)
+                       goto out_unlock_internal;
 
                xfs_rwunlock(bdp, locktype);
                if (need_i_mutex)
index 8f4539952350e235991e857cdf97548e230f7632..c77e62efb7420d1bebd3445e55409d426d72fb20 100644 (file)
@@ -18,8 +18,8 @@
 #ifndef __XFS_LRW_H__
 #define __XFS_LRW_H__
 
-struct vnode;
 struct bhv_desc;
+struct bhv_vnode;
 struct xfs_mount;
 struct xfs_iocore;
 struct xfs_inode;
@@ -49,7 +49,7 @@ struct xfs_iomap;
 #define        XFS_CTRUNC4             14
 #define        XFS_CTRUNC5             15
 #define        XFS_CTRUNC6             16
-#define        XFS_BUNMAPI             17
+#define        XFS_BUNMAP              17
 #define        XFS_INVAL_CACHED        18
 #define        XFS_DIORD_ENTER         19
 #define        XFS_DIOWR_ENTER         20
@@ -82,7 +82,7 @@ extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
 extern int xfs_bdstrat_cb(struct xfs_buf *);
 extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
 
-extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
+extern int xfs_zero_eof(struct bhv_vnode *, struct xfs_iocore *, xfs_off_t,
                                xfs_fsize_t, xfs_fsize_t);
 extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
                                const struct iovec *, unsigned int,
index 68f4793e8a11f27588a3d211ec00a07303f3bca3..f2a0778536f4bb9e7d609c5c0f6a2b3b724f1ac6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -151,7 +149,7 @@ xfs_set_inodeops(
 STATIC __inline__ void
 xfs_revalidate_inode(
        xfs_mount_t             *mp,
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        xfs_inode_t             *ip)
 {
        struct inode            *inode = vn_to_inode(vp);
@@ -206,7 +204,7 @@ xfs_revalidate_inode(
 void
 xfs_initialize_vnode(
        bhv_desc_t              *bdp,
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        bhv_desc_t              *inode_bhv,
        int                     unlock)
 {
@@ -336,7 +334,7 @@ STATIC struct inode *
 xfs_fs_alloc_inode(
        struct super_block      *sb)
 {
-       vnode_t                 *vp;
+       bhv_vnode_t             *vp;
 
        vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
        if (unlikely(!vp))
@@ -359,13 +357,13 @@ xfs_fs_inode_init_once(
 {
        if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
                      SLAB_CTOR_CONSTRUCTOR)
-               inode_init_once(vn_to_inode((vnode_t *)vnode));
+               inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
 }
 
 STATIC int
 xfs_init_zones(void)
 {
-       xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t",
+       xfs_vnode_zone = kmem_zone_init_flags(sizeof(bhv_vnode_t), "xfs_vnode",
                                        KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
                                        KM_ZONE_SPREAD,
                                        xfs_fs_inode_init_once);
@@ -409,22 +407,17 @@ xfs_fs_write_inode(
        struct inode            *inode,
        int                     sync)
 {
-       vnode_t                 *vp = vn_from_inode(inode);
+       bhv_vnode_t             *vp = vn_from_inode(inode);
        int                     error = 0, flags = FLUSH_INODE;
 
        if (vp) {
                vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
                if (sync)
                        flags |= FLUSH_SYNC;
-               VOP_IFLUSH(vp, flags, error);
-               if (error == EAGAIN) {
-                       if (sync)
-                               VOP_IFLUSH(vp, flags | FLUSH_LOG, error);
-                       else
-                               error = 0;
-               }
+               error = bhv_vop_iflush(vp, flags);
+               if (error == EAGAIN)
+                       error = sync? bhv_vop_iflush(vp, flags | FLUSH_LOG) : 0;
        }
-
        return -error;
 }
 
@@ -432,8 +425,7 @@ STATIC void
 xfs_fs_clear_inode(
        struct inode            *inode)
 {
-       vnode_t                 *vp = vn_from_inode(inode);
-       int                     error, cache;
+       bhv_vnode_t             *vp = vn_from_inode(inode);
 
        vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
@@ -446,20 +438,18 @@ xfs_fs_clear_inode(
         * This can happen because xfs_iget_core calls xfs_idestroy if we
         * find an inode with di_mode == 0 but without IGET_CREATE set.
         */
-       if (vp->v_fbhv)
-               VOP_INACTIVE(vp, NULL, cache);
+       if (VNHEAD(vp))
+               bhv_vop_inactive(vp, NULL);
 
        VN_LOCK(vp);
        vp->v_flag &= ~VMODIFIED;
        VN_UNLOCK(vp, 0);
 
-       if (vp->v_fbhv) {
-               VOP_RECLAIM(vp, error);
-               if (error)
-                       panic("vn_purge: cannot reclaim");
-       }
+       if (VNHEAD(vp))
+               if (bhv_vop_reclaim(vp))
+                       panic("%s: cannot reclaim 0x%p\n", __FUNCTION__, vp);
 
-       ASSERT(vp->v_fbhv == NULL);
+       ASSERT(VNHEAD(vp) == NULL);
 
 #ifdef XFS_VNODE_TRACE
        ktrace_free(vp->v_trace);
@@ -475,13 +465,13 @@ xfs_fs_clear_inode(
  */
 STATIC void
 xfs_syncd_queue_work(
-       struct vfs      *vfs,
+       struct bhv_vfs  *vfs,
        void            *data,
-       void            (*syncer)(vfs_t *, void *))
+       void            (*syncer)(bhv_vfs_t *, void *))
 {
-       vfs_sync_work_t *work;
+       struct bhv_vfs_sync_work *work;
 
-       work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP);
+       work = kmem_alloc(sizeof(struct bhv_vfs_sync_work), KM_SLEEP);
        INIT_LIST_HEAD(&work->w_list);
        work->w_syncer = syncer;
        work->w_data = data;
@@ -500,7 +490,7 @@ xfs_syncd_queue_work(
  */
 STATIC void
 xfs_flush_inode_work(
-       vfs_t           *vfs,
+       bhv_vfs_t       *vfs,
        void            *inode)
 {
        filemap_flush(((struct inode *)inode)->i_mapping);
@@ -512,7 +502,7 @@ xfs_flush_inode(
        xfs_inode_t     *ip)
 {
        struct inode    *inode = vn_to_inode(XFS_ITOV(ip));
-       struct vfs      *vfs = XFS_MTOVFS(ip->i_mount);
+       struct bhv_vfs  *vfs = XFS_MTOVFS(ip->i_mount);
 
        igrab(inode);
        xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
@@ -525,7 +515,7 @@ xfs_flush_inode(
  */
 STATIC void
 xfs_flush_device_work(
-       vfs_t           *vfs,
+       bhv_vfs_t       *vfs,
        void            *inode)
 {
        sync_blockdev(vfs->vfs_super->s_bdev);
@@ -537,7 +527,7 @@ xfs_flush_device(
        xfs_inode_t     *ip)
 {
        struct inode    *inode = vn_to_inode(XFS_ITOV(ip));
-       struct vfs      *vfs = XFS_MTOVFS(ip->i_mount);
+       struct bhv_vfs  *vfs = XFS_MTOVFS(ip->i_mount);
 
        igrab(inode);
        xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
@@ -545,16 +535,16 @@ xfs_flush_device(
        xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
 }
 
-#define SYNCD_FLAGS    (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
 STATIC void
 vfs_sync_worker(
-       vfs_t           *vfsp,
+       bhv_vfs_t       *vfsp,
        void            *unused)
 {
        int             error;
 
        if (!(vfsp->vfs_flag & VFS_RDONLY))
-               VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
+               error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
+                                       SYNC_ATTR | SYNC_REFCACHE, NULL);
        vfsp->vfs_sync_seq++;
        wmb();
        wake_up(&vfsp->vfs_wait_single_sync_task);
@@ -565,8 +555,8 @@ xfssyncd(
        void                    *arg)
 {
        long                    timeleft;
-       vfs_t                   *vfsp = (vfs_t *) arg;
-       struct vfs_sync_work    *work, *n;
+       bhv_vfs_t               *vfsp = (bhv_vfs_t *) arg;
+       bhv_vfs_sync_work_t     *work, *n;
        LIST_HEAD               (tmp);
 
        timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
@@ -600,7 +590,7 @@ xfssyncd(
                        list_del(&work->w_list);
                        if (work == &vfsp->vfs_sync_work)
                                continue;
-                       kmem_free(work, sizeof(struct vfs_sync_work));
+                       kmem_free(work, sizeof(struct bhv_vfs_sync_work));
                }
        }
 
@@ -609,7 +599,7 @@ xfssyncd(
 
 STATIC int
 xfs_fs_start_syncd(
-       vfs_t                   *vfsp)
+       bhv_vfs_t               *vfsp)
 {
        vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
        vfsp->vfs_sync_work.w_vfs = vfsp;
@@ -621,7 +611,7 @@ xfs_fs_start_syncd(
 
 STATIC void
 xfs_fs_stop_syncd(
-       vfs_t                   *vfsp)
+       bhv_vfs_t               *vfsp)
 {
        kthread_stop(vfsp->vfs_sync_task);
 }
@@ -630,35 +620,26 @@ STATIC void
 xfs_fs_put_super(
        struct super_block      *sb)
 {
-       vfs_t                   *vfsp = vfs_from_sb(sb);
+       bhv_vfs_t               *vfsp = vfs_from_sb(sb);
        int                     error;
 
        xfs_fs_stop_syncd(vfsp);
-       VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
-       if (!error)
-               VFS_UNMOUNT(vfsp, 0, NULL, error);
+       bhv_vfs_sync(vfsp, SYNC_ATTR | SYNC_DELWRI, NULL);
+       error = bhv_vfs_unmount(vfsp, 0, NULL);
        if (error) {
-               printk("XFS unmount got error %d\n", error);
-               printk("%s: vfsp/0x%p left dangling!\n", __FUNCTION__, vfsp);
-               return;
+               printk("XFS: unmount got error=%d\n", error);
+               printk("%s: vfs=0x%p left dangling!\n", __FUNCTION__, vfsp);
+       } else {
+               vfs_deallocate(vfsp);
        }
-
-       vfs_deallocate(vfsp);
 }
 
 STATIC void
 xfs_fs_write_super(
        struct super_block      *sb)
 {
-       vfs_t                   *vfsp = vfs_from_sb(sb);
-       int                     error;
-
-       if (sb->s_flags & MS_RDONLY) {
-               sb->s_dirt = 0; /* paranoia */
-               return;
-       }
-       /* Push the log and superblock a little */
-       VFS_SYNC(vfsp, SYNC_FSDATA, NULL, error);
+       if (!(sb->s_flags & MS_RDONLY))
+               bhv_vfs_sync(vfs_from_sb(sb), SYNC_FSDATA, NULL);
        sb->s_dirt = 0;
 }
 
@@ -667,16 +648,16 @@ xfs_fs_sync_super(
        struct super_block      *sb,
        int                     wait)
 {
-       vfs_t           *vfsp = vfs_from_sb(sb);
-       int             error;
-       int             flags = SYNC_FSDATA;
+       bhv_vfs_t               *vfsp = vfs_from_sb(sb);
+       int                     error;
+       int                     flags;
 
        if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
                flags = SYNC_QUIESCE;
        else
                flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
 
-       VFS_SYNC(vfsp, flags, NULL, error);
+       error = bhv_vfs_sync(vfsp, flags, NULL);
        sb->s_dirt = 0;
 
        if (unlikely(laptop_mode)) {
@@ -706,11 +687,7 @@ xfs_fs_statfs(
        struct super_block      *sb,
        struct kstatfs          *statp)
 {
-       vfs_t                   *vfsp = vfs_from_sb(sb);
-       int                     error;
-
-       VFS_STATVFS(vfsp, statp, NULL, error);
-       return -error;
+       return -bhv_vfs_statvfs(vfs_from_sb(sb), statp, NULL);
 }
 
 STATIC int
@@ -719,13 +696,13 @@ xfs_fs_remount(
        int                     *flags,
        char                    *options)
 {
-       vfs_t                   *vfsp = vfs_from_sb(sb);
+       bhv_vfs_t               *vfsp = vfs_from_sb(sb);
        struct xfs_mount_args   *args = xfs_args_allocate(sb, 0);
        int                     error;
 
-       VFS_PARSEARGS(vfsp, options, args, 1, error);
+       error = bhv_vfs_parseargs(vfsp, options, args, 1);
        if (!error)
-               VFS_MNTUPDATE(vfsp, flags, args, error);
+               error = bhv_vfs_mntupdate(vfsp, flags, args);
        kmem_free(args, sizeof(*args));
        return -error;
 }
@@ -734,7 +711,7 @@ STATIC void
 xfs_fs_lockfs(
        struct super_block      *sb)
 {
-       VFS_FREEZE(vfs_from_sb(sb));
+       bhv_vfs_freeze(vfs_from_sb(sb));
 }
 
 STATIC int
@@ -742,11 +719,7 @@ xfs_fs_show_options(
        struct seq_file         *m,
        struct vfsmount         *mnt)
 {
-       struct vfs              *vfsp = vfs_from_sb(mnt->mnt_sb);
-       int                     error;
-
-       VFS_SHOWARGS(vfsp, m, error);
-       return error;
+       return -bhv_vfs_showargs(vfs_from_sb(mnt->mnt_sb), m);
 }
 
 STATIC int
@@ -754,11 +727,7 @@ xfs_fs_quotasync(
        struct super_block      *sb,
        int                     type)
 {
-       struct vfs              *vfsp = vfs_from_sb(sb);
-       int                     error;
-
-       VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
-       return -error;
+       return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XQUOTASYNC, 0, NULL);
 }
 
 STATIC int
@@ -766,11 +735,7 @@ xfs_fs_getxstate(
        struct super_block      *sb,
        struct fs_quota_stat    *fqs)
 {
-       struct vfs              *vfsp = vfs_from_sb(sb);
-       int                     error;
-
-       VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
-       return -error;
+       return -bhv_vfs_quotactl(vfs_from_sb(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
 }
 
 STATIC int
@@ -779,11 +744,7 @@ xfs_fs_setxstate(
        unsigned int            flags,
        int                     op)
 {
-       struct vfs              *vfsp = vfs_from_sb(sb);
-       int                     error;
-
-       VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
-       return -error;
+       return -bhv_vfs_quotactl(vfs_from_sb(sb), op, 0, (caddr_t)&flags);
 }
 
 STATIC int
@@ -793,13 +754,10 @@ xfs_fs_getxquota(
        qid_t                   id,
        struct fs_disk_quota    *fdq)
 {
-       struct vfs              *vfsp = vfs_from_sb(sb);
-       int                     error, getmode;
-
-       getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
-                ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
-       VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
-       return -error;
+       return -bhv_vfs_quotactl(vfs_from_sb(sb),
+                                (type == USRQUOTA) ? Q_XGETQUOTA :
+                                 ((type == GRPQUOTA) ? Q_XGETGQUOTA :
+                                  Q_XGETPQUOTA), id, (caddr_t)fdq);
 }
 
 STATIC int
@@ -809,13 +767,10 @@ xfs_fs_setxquota(
        qid_t                   id,
        struct fs_disk_quota    *fdq)
 {
-       struct vfs              *vfsp = vfs_from_sb(sb);
-       int                     error, setmode;
-
-       setmode = (type == USRQUOTA) ? Q_XSETQLIM :
-                ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
-       VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
-       return -error;
+       return -bhv_vfs_quotactl(vfs_from_sb(sb),
+                                (type == USRQUOTA) ? Q_XSETQLIM :
+                                 ((type == GRPQUOTA) ? Q_XSETGQLIM :
+                                  Q_XSETPQLIM), id, (caddr_t)fdq);
 }
 
 STATIC int
@@ -824,34 +779,32 @@ xfs_fs_fill_super(
        void                    *data,
        int                     silent)
 {
-       vnode_t                 *rootvp;
-       struct vfs              *vfsp = vfs_allocate(sb);
+       struct bhv_vnode        *rootvp;
+       struct bhv_vfs          *vfsp = vfs_allocate(sb);
        struct xfs_mount_args   *args = xfs_args_allocate(sb, silent);
        struct kstatfs          statvfs;
-       int                     error, error2;
+       int                     error;
 
        bhv_insert_all_vfsops(vfsp);
 
-       VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
+       error = bhv_vfs_parseargs(vfsp, (char *)data, args, 0);
        if (error) {
                bhv_remove_all_vfsops(vfsp, 1);
                goto fail_vfsop;
        }
 
        sb_min_blocksize(sb, BBSIZE);
-#ifdef CONFIG_XFS_EXPORT
        sb->s_export_op = &xfs_export_operations;
-#endif
        sb->s_qcop = &xfs_quotactl_operations;
        sb->s_op = &xfs_super_operations;
 
-       VFS_MOUNT(vfsp, args, NULL, error);
+       error = bhv_vfs_mount(vfsp, args, NULL);
        if (error) {
                bhv_remove_all_vfsops(vfsp, 1);
                goto fail_vfsop;
        }
 
-       VFS_STATVFS(vfsp, &statvfs, NULL, error);
+       error = bhv_vfs_statvfs(vfsp, &statvfs, NULL);
        if (error)
                goto fail_unmount;
 
@@ -863,7 +816,7 @@ xfs_fs_fill_super(
        sb->s_time_gran = 1;
        set_posix_acl_flag(sb);
 
-       VFS_ROOT(vfsp, &rootvp, error);
+       error = bhv_vfs_root(vfsp, &rootvp);
        if (error)
                goto fail_unmount;
 
@@ -892,7 +845,7 @@ fail_vnrele:
        }
 
 fail_unmount:
-       VFS_UNMOUNT(vfsp, 0, NULL, error2);
+       bhv_vfs_unmount(vfsp, 0, NULL);
 
 fail_vfsop:
        vfs_deallocate(vfsp);
index 376b96cb513a782d413b096b1e7e0b0962d285f1..33dd1ca13245544b154e67bc2324b72ff5393571 100644 (file)
@@ -105,7 +105,7 @@ struct block_device;
 
 extern __uint64_t xfs_max_file_offset(unsigned int);
 
-extern void xfs_initialize_vnode(bhv_desc_t *, vnode_t *, bhv_desc_t *, int);
+extern void xfs_initialize_vnode(bhv_desc_t *, bhv_vnode_t *, bhv_desc_t *, int);
 
 extern void xfs_flush_inode(struct xfs_inode *);
 extern void xfs_flush_device(struct xfs_inode *);
index 7079cc8372100aa8b2f7a3c3bd95e708a9a11531..4af97682bec8e066a62e7207ac5440eaaaa0b37f 100644 (file)
@@ -120,6 +120,11 @@ STATIC ctl_table xfs_table[] = {
        &sysctl_intvec, NULL,
        &xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
 
+       {XFS_INHERIT_NODFRG, "inherit_nodefrag", &xfs_params.inherit_nodfrg.val,
+       sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+       &sysctl_intvec, NULL,
+       &xfs_params.inherit_nodfrg.min, &xfs_params.inherit_nodfrg.max},
+
        /* please keep this the last entry */
 #ifdef CONFIG_PROC_FS
        {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
index bc8c11f1372203b400dfd62c81bbe2a7b1636803..a631fb8cc5ac4c57ad04e9090184eef58fcec75a 100644 (file)
@@ -46,6 +46,7 @@ typedef struct xfs_param {
        xfs_sysctl_val_t xfs_buf_age;   /* Metadata buffer age before flush. */
        xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
        xfs_sysctl_val_t rotorstep;     /* inode32 AG rotoring control knob */
+       xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
 } xfs_param_t;
 
 /*
@@ -84,6 +85,7 @@ enum {
        /* XFS_IO_BYPASS = 18 */
        XFS_INHERIT_NOSYM = 19,
        XFS_ROTORSTEP = 20,
+       XFS_INHERIT_NODFRG = 21,
 };
 
 extern xfs_param_t     xfs_params;
index 6f7c9f7a86246ee1f3e822b5e706417718f77406..6145e8bd0be2f7a34bc95da993acae2ac2bfaa59 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_imap.h"
 #include "xfs_alloc.h"
@@ -104,7 +103,7 @@ vfs_mntupdate(
 int
 vfs_root(
        struct bhv_desc         *bdp,
-       struct vnode            **vpp)
+       struct bhv_vnode        **vpp)
 {
        struct bhv_desc         *next = bdp;
 
@@ -117,15 +116,15 @@ vfs_root(
 int
 vfs_statvfs(
        struct bhv_desc         *bdp,
-       xfs_statfs_t            *sp,
-       struct vnode            *vp)
+       bhv_statvfs_t           *statp,
+       struct bhv_vnode        *vp)
 {
        struct bhv_desc         *next = bdp;
 
        ASSERT(next);
        while (! (bhvtovfsops(next))->vfs_statvfs)
                next = BHV_NEXT(next);
-       return ((*bhvtovfsops(next)->vfs_statvfs)(next, sp, vp));
+       return ((*bhvtovfsops(next)->vfs_statvfs)(next, statp, vp));
 }
 
 int
@@ -145,7 +144,7 @@ vfs_sync(
 int
 vfs_vget(
        struct bhv_desc         *bdp,
-       struct vnode            **vpp,
+       struct bhv_vnode        **vpp,
        struct fid              *fidp)
 {
        struct bhv_desc         *next = bdp;
@@ -187,7 +186,7 @@ vfs_quotactl(
 void
 vfs_init_vnode(
        struct bhv_desc         *bdp,
-       struct vnode            *vp,
+       struct bhv_vnode        *vp,
        struct bhv_desc         *bp,
        int                     unlock)
 {
@@ -226,13 +225,13 @@ vfs_freeze(
        ((*bhvtovfsops(next)->vfs_freeze)(next));
 }
 
-vfs_t *
+bhv_vfs_t *
 vfs_allocate(
        struct super_block      *sb)
 {
-       struct vfs              *vfsp;
+       struct bhv_vfs          *vfsp;
 
-       vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
+       vfsp = kmem_zalloc(sizeof(bhv_vfs_t), KM_SLEEP);
        bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
        INIT_LIST_HEAD(&vfsp->vfs_sync_list);
        spin_lock_init(&vfsp->vfs_sync_lock);
@@ -247,25 +246,25 @@ vfs_allocate(
        return vfsp;
 }
 
-vfs_t *
+bhv_vfs_t *
 vfs_from_sb(
        struct super_block      *sb)
 {
-       return (vfs_t *)sb->s_fs_info;
+       return (bhv_vfs_t *)sb->s_fs_info;
 }
 
 void
 vfs_deallocate(
-       struct vfs              *vfsp)
+       struct bhv_vfs          *vfsp)
 {
        bhv_head_destroy(VFS_BHVHEAD(vfsp));
-       kmem_free(vfsp, sizeof(vfs_t));
+       kmem_free(vfsp, sizeof(bhv_vfs_t));
 }
 
 void
 vfs_insertops(
-       struct vfs              *vfsp,
-       struct bhv_vfsops       *vfsops)
+       struct bhv_vfs          *vfsp,
+       struct bhv_module_vfsops *vfsops)
 {
        struct bhv_desc         *bdp;
 
@@ -276,9 +275,9 @@ vfs_insertops(
 
 void
 vfs_insertbhv(
-       struct vfs              *vfsp,
+       struct bhv_vfs          *vfsp,
        struct bhv_desc         *bdp,
-       struct vfsops           *vfsops,
+       struct bhv_vfsops       *vfsops,
        void                    *mount)
 {
        bhv_desc_init(bdp, mount, vfsp, vfsops);
@@ -287,7 +286,7 @@ vfs_insertbhv(
 
 void
 bhv_remove_vfsops(
-       struct vfs              *vfsp,
+       struct bhv_vfs          *vfsp,
        int                     pos)
 {
        struct bhv_desc         *bhv;
@@ -301,7 +300,7 @@ bhv_remove_vfsops(
 
 void
 bhv_remove_all_vfsops(
-       struct vfs              *vfsp,
+       struct bhv_vfs          *vfsp,
        int                     freebase)
 {
        struct xfs_mount        *mp;
@@ -317,7 +316,7 @@ bhv_remove_all_vfsops(
 
 void
 bhv_insert_all_vfsops(
-       struct vfs              *vfsp)
+       struct bhv_vfs          *vfsp)
 {
        struct xfs_mount        *mp;
 
index 841200c030921ff38ac1535e0329c7ae0e69d3e7..91fc2c4b3353f1f4ea96ed51de25ade3f4304f76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
 #include <linux/vfs.h>
 #include "xfs_fs.h"
 
+struct bhv_vfs;
+struct bhv_vnode;
+
 struct fid;
-struct vfs;
 struct cred;
-struct vnode;
-struct kstatfs;
 struct seq_file;
 struct super_block;
 struct xfs_mount_args;
 
-typedef struct kstatfs xfs_statfs_t;
+typedef struct kstatfs bhv_statvfs_t;
 
-typedef struct vfs_sync_work {
+typedef struct bhv_vfs_sync_work {
        struct list_head        w_list;
-       struct vfs              *w_vfs;
+       struct bhv_vfs          *w_vfs;
        void                    *w_data;        /* syncer routine argument */
-       void                    (*w_syncer)(struct vfs *, void *);
-} vfs_sync_work_t;
+       void                    (*w_syncer)(struct bhv_vfs *, void *);
+} bhv_vfs_sync_work_t;
 
-typedef struct vfs {
+typedef struct bhv_vfs {
        u_int                   vfs_flag;       /* flags */
        xfs_fsid_t              vfs_fsid;       /* file system ID */
        xfs_fsid_t              *vfs_altfsid;   /* An ID fixed for life of FS */
        bhv_head_t              vfs_bh;         /* head of vfs behavior chain */
        struct super_block      *vfs_super;     /* generic superblock pointer */
        struct task_struct      *vfs_sync_task; /* generalised sync thread */
-       vfs_sync_work_t         vfs_sync_work;  /* work item for VFS_SYNC */
+       bhv_vfs_sync_work_t     vfs_sync_work;  /* work item for VFS_SYNC */
        struct list_head        vfs_sync_list;  /* sync thread work item list */
        spinlock_t              vfs_sync_lock;  /* work item list lock */
-       int                     vfs_sync_seq;   /* sync thread generation no. */
+       int                     vfs_sync_seq;   /* sync thread generation no. */
        wait_queue_head_t       vfs_wait_single_sync_task;
-} vfs_t;
-
-#define vfs_fbhv               vfs_bh.bh_first /* 1st on vfs behavior chain */
+} bhv_vfs_t;
 
-#define bhvtovfs(bdp)          ( (struct vfs *)BHV_VOBJ(bdp) )
-#define bhvtovfsops(bdp)       ( (struct vfsops *)BHV_OPS(bdp) )
+#define bhvtovfs(bdp)          ( (struct bhv_vfs *)BHV_VOBJ(bdp) )
+#define bhvtovfsops(bdp)       ( (struct bhv_vfsops *)BHV_OPS(bdp) )
 #define VFS_BHVHEAD(vfs)       ( &(vfs)->vfs_bh )
 #define VFS_REMOVEBHV(vfs, bdp)        ( bhv_remove(VFS_BHVHEAD(vfs), bdp) )
 
@@ -71,7 +69,7 @@ typedef enum {
        VFS_BHV_QM,             /* quota manager */
        VFS_BHV_IO,             /* IO path */
        VFS_BHV_END             /* housekeeping end-of-range */
-} vfs_bhv_t;
+} bhv_vfs_type_t;
 
 #define VFS_POSITION_XFS       (BHV_POSITION_BASE)
 #define VFS_POSITION_DM                (VFS_POSITION_BASE+10)
@@ -81,8 +79,9 @@ typedef enum {
 #define VFS_RDONLY             0x0001  /* read-only vfs */
 #define VFS_GRPID              0x0002  /* group-ID assigned from directory */
 #define VFS_DMI                        0x0004  /* filesystem has the DMI enabled */
-#define VFS_32BITINODES                0x0008  /* do not use inums above 32 bits */
-#define VFS_END                        0x0008  /* max flag */
+#define VFS_UMOUNT             0x0008  /* unmount in progress */
+#define VFS_32BITINODES                0x0010  /* do not use inums above 32 bits */
+#define VFS_END                        0x0010  /* max flag */
 
 #define SYNC_ATTR              0x0001  /* sync attributes */
 #define SYNC_CLOSE             0x0002  /* close file system down */
@@ -92,7 +91,14 @@ typedef enum {
 #define SYNC_FSDATA            0x0020  /* flush fs data (e.g. superblocks) */
 #define SYNC_REFCACHE          0x0040  /* prune some of the nfs ref cache */
 #define SYNC_REMOUNT           0x0080  /* remount readonly, no dummy LRs */
-#define SYNC_QUIESCE           0x0100  /* quiesce filesystem for a snapshot */
+#define SYNC_QUIESCE           0x0100  /* quiesce fileystem for a snapshot */
+
+#define SHUTDOWN_META_IO_ERROR 0x0001  /* write attempt to metadata failed */
+#define SHUTDOWN_LOG_IO_ERROR  0x0002  /* write attempt to the log failed */
+#define SHUTDOWN_FORCE_UMOUNT  0x0004  /* shutdown from a forced unmount */
+#define SHUTDOWN_CORRUPT_INCORE        0x0008  /* corrupt in-memory data structures */
+#define SHUTDOWN_REMOTE_REQ    0x0010  /* shutdown came from remote cell */
+#define SHUTDOWN_DEVICE_REQ    0x0020  /* failed all paths to the device */
 
 typedef int    (*vfs_mount_t)(bhv_desc_t *,
                                struct xfs_mount_args *, struct cred *);
@@ -102,18 +108,19 @@ typedef   int     (*vfs_showargs_t)(bhv_desc_t *, struct seq_file *);
 typedef int    (*vfs_unmount_t)(bhv_desc_t *, int, struct cred *);
 typedef int    (*vfs_mntupdate_t)(bhv_desc_t *, int *,
                                struct xfs_mount_args *);
-typedef int    (*vfs_root_t)(bhv_desc_t *, struct vnode **);
-typedef int    (*vfs_statvfs_t)(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
+typedef int    (*vfs_root_t)(bhv_desc_t *, struct bhv_vnode **);
+typedef int    (*vfs_statvfs_t)(bhv_desc_t *, bhv_statvfs_t *,
+                               struct bhv_vnode *);
 typedef int    (*vfs_sync_t)(bhv_desc_t *, int, struct cred *);
-typedef int    (*vfs_vget_t)(bhv_desc_t *, struct vnode **, struct fid *);
+typedef int    (*vfs_vget_t)(bhv_desc_t *, struct bhv_vnode **, struct fid *);
 typedef int    (*vfs_dmapiops_t)(bhv_desc_t *, caddr_t);
 typedef int    (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
 typedef void   (*vfs_init_vnode_t)(bhv_desc_t *,
-                               struct vnode *, bhv_desc_t *, int);
+                               struct bhv_vnode *, bhv_desc_t *, int);
 typedef void   (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
 typedef void   (*vfs_freeze_t)(bhv_desc_t *);
 
-typedef struct vfsops {
+typedef struct bhv_vfsops {
        bhv_position_t          vf_position;    /* behavior chain position */
        vfs_mount_t             vfs_mount;      /* mount file system */
        vfs_parseargs_t         vfs_parseargs;  /* parse mount options */
@@ -129,82 +136,82 @@ typedef struct vfsops {
        vfs_init_vnode_t        vfs_init_vnode; /* initialize a new vnode */
        vfs_force_shutdown_t    vfs_force_shutdown;     /* crash and burn */
        vfs_freeze_t            vfs_freeze;     /* freeze fs for snapshot */
-} vfsops_t;
+} bhv_vfsops_t;
 
 /*
- * VFS's.  Operates on vfs structure pointers (starts at bhv head).
+ * Virtual filesystem operations, operating from head bhv.
  */
-#define VHEAD(v)                       ((v)->vfs_fbhv)
-#define VFS_MOUNT(v, ma,cr, rv)                ((rv) = vfs_mount(VHEAD(v), ma,cr))
-#define VFS_PARSEARGS(v, o,ma,f, rv)   ((rv) = vfs_parseargs(VHEAD(v), o,ma,f))
-#define VFS_SHOWARGS(v, m, rv)         ((rv) = vfs_showargs(VHEAD(v), m))
-#define VFS_UNMOUNT(v, f, cr, rv)      ((rv) = vfs_unmount(VHEAD(v), f,cr))
-#define VFS_MNTUPDATE(v, fl, args, rv) ((rv) = vfs_mntupdate(VHEAD(v), fl, args))
-#define VFS_ROOT(v, vpp, rv)           ((rv) = vfs_root(VHEAD(v), vpp))
-#define VFS_STATVFS(v, sp,vp, rv)      ((rv) = vfs_statvfs(VHEAD(v), sp,vp))
-#define VFS_SYNC(v, flag,cr, rv)       ((rv) = vfs_sync(VHEAD(v), flag,cr))
-#define VFS_VGET(v, vpp,fidp, rv)      ((rv) = vfs_vget(VHEAD(v), vpp,fidp))
-#define VFS_DMAPIOPS(v, p, rv)         ((rv) = vfs_dmapiops(VHEAD(v), p))
-#define VFS_QUOTACTL(v, c,id,p, rv)    ((rv) = vfs_quotactl(VHEAD(v), c,id,p))
-#define VFS_INIT_VNODE(v, vp,b,ul)     ( vfs_init_vnode(VHEAD(v), vp,b,ul) )
-#define VFS_FORCE_SHUTDOWN(v, fl,f,l)  ( vfs_force_shutdown(VHEAD(v), fl,f,l) )
-#define VFS_FREEZE(v)                  ( vfs_freeze(VHEAD(v)) )
+#define VFSHEAD(v)                     ((v)->vfs_bh.bh_first)
+#define bhv_vfs_mount(v, ma,cr)                vfs_mount(VFSHEAD(v), ma,cr)
+#define bhv_vfs_parseargs(v, o,ma,f)   vfs_parseargs(VFSHEAD(v), o,ma,f)
+#define bhv_vfs_showargs(v, m)         vfs_showargs(VFSHEAD(v), m)
+#define bhv_vfs_unmount(v, f,cr)       vfs_unmount(VFSHEAD(v), f,cr)
+#define bhv_vfs_mntupdate(v, fl,args)  vfs_mntupdate(VFSHEAD(v), fl,args)
+#define bhv_vfs_root(v, vpp)           vfs_root(VFSHEAD(v), vpp)
+#define bhv_vfs_statvfs(v, sp,vp)      vfs_statvfs(VFSHEAD(v), sp,vp)
+#define bhv_vfs_sync(v, flag,cr)       vfs_sync(VFSHEAD(v), flag,cr)
+#define bhv_vfs_vget(v, vpp,fidp)      vfs_vget(VFSHEAD(v), vpp,fidp)
+#define bhv_vfs_dmapiops(v, p)         vfs_dmapiops(VFSHEAD(v), p)
+#define bhv_vfs_quotactl(v, c,id,p)    vfs_quotactl(VFSHEAD(v), c,id,p)
+#define bhv_vfs_init_vnode(v, vp,b,ul) vfs_init_vnode(VFSHEAD(v), vp,b,ul)
+#define bhv_vfs_force_shutdown(v,u,f,l)        vfs_force_shutdown(VFSHEAD(v), u,f,l)
+#define bhv_vfs_freeze(v)              vfs_freeze(VFSHEAD(v))
 
 /*
- * PVFS's.  Operates on behavior descriptor pointers.
+ * Virtual filesystem operations, operating from next bhv.
  */
-#define PVFS_MOUNT(b, ma,cr, rv)       ((rv) = vfs_mount(b, ma,cr))
-#define PVFS_PARSEARGS(b, o,ma,f, rv)  ((rv) = vfs_parseargs(b, o,ma,f))
-#define PVFS_SHOWARGS(b, m, rv)                ((rv) = vfs_showargs(b, m))
-#define PVFS_UNMOUNT(b, f,cr, rv)      ((rv) = vfs_unmount(b, f,cr))
-#define PVFS_MNTUPDATE(b, fl, args, rv)        ((rv) = vfs_mntupdate(b, fl, args))
-#define PVFS_ROOT(b, vpp, rv)          ((rv) = vfs_root(b, vpp))
-#define PVFS_STATVFS(b, sp,vp, rv)     ((rv) = vfs_statvfs(b, sp,vp))
-#define PVFS_SYNC(b, flag,cr, rv)      ((rv) = vfs_sync(b, flag,cr))
-#define PVFS_VGET(b, vpp,fidp, rv)     ((rv) = vfs_vget(b, vpp,fidp))
-#define PVFS_DMAPIOPS(b, p, rv)                ((rv) = vfs_dmapiops(b, p))
-#define PVFS_QUOTACTL(b, c,id,p, rv)   ((rv) = vfs_quotactl(b, c,id,p))
-#define PVFS_INIT_VNODE(b, vp,b2,ul)   ( vfs_init_vnode(b, vp,b2,ul) )
-#define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) )
-#define PVFS_FREEZE(b)                 ( vfs_freeze(b) )
+#define bhv_next_vfs_mount(b, ma,cr)           vfs_mount(b, ma,cr)
+#define bhv_next_vfs_parseargs(b, o,ma,f)      vfs_parseargs(b, o,ma,f)
+#define bhv_next_vfs_showargs(b, m)            vfs_showargs(b, m)
+#define bhv_next_vfs_unmount(b, f,cr)          vfs_unmount(b, f,cr)
+#define bhv_next_vfs_mntupdate(b, fl,args)     vfs_mntupdate(b, fl, args)
+#define bhv_next_vfs_root(b, vpp)              vfs_root(b, vpp)
+#define bhv_next_vfs_statvfs(b, sp,vp)         vfs_statvfs(b, sp,vp)
+#define bhv_next_vfs_sync(b, flag,cr)          vfs_sync(b, flag,cr)
+#define bhv_next_vfs_vget(b, vpp,fidp)         vfs_vget(b, vpp,fidp)
+#define bhv_next_vfs_dmapiops(b, p)            vfs_dmapiops(b, p)
+#define bhv_next_vfs_quotactl(b, c,id,p)       vfs_quotactl(b, c,id,p)
+#define bhv_next_vfs_init_vnode(b, vp,b2,ul)   vfs_init_vnode(b, vp,b2,ul)
+#define bhv_next_force_shutdown(b, fl,f,l)     vfs_force_shutdown(b, fl,f,l)
+#define bhv_next_vfs_freeze(b)                 vfs_freeze(b)
 
 extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
 extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
 extern int vfs_showargs(bhv_desc_t *, struct seq_file *);
 extern int vfs_unmount(bhv_desc_t *, int, struct cred *);
 extern int vfs_mntupdate(bhv_desc_t *, int *, struct xfs_mount_args *);
-extern int vfs_root(bhv_desc_t *, struct vnode **);
-extern int vfs_statvfs(bhv_desc_t *, xfs_statfs_t *, struct vnode *);
+extern int vfs_root(bhv_desc_t *, struct bhv_vnode **);
+extern int vfs_statvfs(bhv_desc_t *, bhv_statvfs_t *, struct bhv_vnode *);
 extern int vfs_sync(bhv_desc_t *, int, struct cred *);
-extern int vfs_vget(bhv_desc_t *, struct vnode **, struct fid *);
+extern int vfs_vget(bhv_desc_t *, struct bhv_vnode **, struct fid *);
 extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
 extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
-extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int);
+extern void vfs_init_vnode(bhv_desc_t *, struct bhv_vnode *, bhv_desc_t *, int);
 extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
 extern void vfs_freeze(bhv_desc_t *);
 
-typedef struct bhv_vfsops {
-       struct vfsops           bhv_common;
+#define vfs_test_for_freeze(vfs)       ((vfs)->vfs_super->s_frozen)
+#define vfs_wait_for_freeze(vfs,l)     vfs_check_frozen((vfs)->vfs_super, (l))
+typedef struct bhv_module_vfsops {
+       struct bhv_vfsops       bhv_common;
        void *                  bhv_custom;
-} bhv_vfsops_t;
+} bhv_module_vfsops_t;
 
-#define vfs_bhv_lookup(v, id)  ( bhv_lookup_range(&(v)->vfs_bh, (id), (id)) )
-#define vfs_bhv_custom(b)      ( ((bhv_vfsops_t *)BHV_OPS(b))->bhv_custom )
-#define vfs_bhv_set_custom(b,o)        ( (b)->bhv_custom = (void *)(o))
-#define vfs_bhv_clr_custom(b)  ( (b)->bhv_custom = NULL )
+#define vfs_bhv_lookup(v, id)  (bhv_lookup_range(&(v)->vfs_bh, (id), (id)))
+#define vfs_bhv_custom(b)      (((bhv_module_vfsops_t*)BHV_OPS(b))->bhv_custom)
+#define vfs_bhv_set_custom(b,o)        ((b)->bhv_custom = (void *)(o))
+#define vfs_bhv_clr_custom(b)  ((b)->bhv_custom = NULL)
 
-extern vfs_t *vfs_allocate(struct super_block *);
-extern vfs_t *vfs_from_sb(struct super_block *);
-extern void vfs_deallocate(vfs_t *);
-extern void vfs_insertops(vfs_t *, bhv_vfsops_t *);
-extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
+extern bhv_vfs_t *vfs_allocate(struct super_block *);
+extern bhv_vfs_t *vfs_from_sb(struct super_block *);
+extern void vfs_deallocate(bhv_vfs_t *);
+extern void vfs_insertbhv(bhv_vfs_t *, bhv_desc_t *, bhv_vfsops_t *, void *);
 
-extern void bhv_insert_all_vfsops(struct vfs *);
-extern void bhv_remove_all_vfsops(struct vfs *, int);
-extern void bhv_remove_vfsops(struct vfs *, int);
+extern void vfs_insertops(bhv_vfs_t *, bhv_module_vfsops_t *);
 
-#define fs_frozen(vfsp)                ((vfsp)->vfs_super->s_frozen)
-#define fs_check_frozen(vfsp, level) \
-       vfs_check_frozen(vfsp->vfs_super, level);
+extern void bhv_insert_all_vfsops(struct bhv_vfs *);
+extern void bhv_remove_all_vfsops(struct bhv_vfs *, int);
+extern void bhv_remove_vfsops(struct bhv_vfs *, int);
 
 #endif /* __XFS_VFS_H__ */
index d27c25b27ccd4aec1e4f8c8d235e7f41b07034dd..6628d96b6fd6a02cfba135c50976ff154def34bc 100644 (file)
@@ -39,7 +39,7 @@ vn_init(void)
 
 void
 vn_iowait(
-       struct vnode    *vp)
+       bhv_vnode_t     *vp)
 {
        wait_queue_head_t *wq = vptosync(vp);
 
@@ -48,17 +48,33 @@ vn_iowait(
 
 void
 vn_iowake(
-       struct vnode    *vp)
+       bhv_vnode_t     *vp)
 {
        if (atomic_dec_and_test(&vp->v_iocount))
                wake_up(vptosync(vp));
 }
 
-struct vnode *
+/*
+ * Volume managers supporting multiple paths can send back ENODEV when the
+ * final path disappears.  In this case continuing to fill the page cache
+ * with dirty data which cannot be written out is evil, so prevent that.
+ */
+void
+vn_ioerror(
+       bhv_vnode_t     *vp,
+       int             error,
+       char            *f,
+       int             l)
+{
+       if (unlikely(error == -ENODEV))
+               bhv_vfs_force_shutdown(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
+}
+
+bhv_vnode_t *
 vn_initialize(
        struct inode    *inode)
 {
-       struct vnode    *vp = vn_from_inode(inode);
+       bhv_vnode_t     *vp = vn_from_inode(inode);
 
        XFS_STATS_INC(vn_active);
        XFS_STATS_INC(vn_alloc);
@@ -94,8 +110,8 @@ vn_initialize(
  */
 void
 vn_revalidate_core(
-       struct vnode    *vp,
-       vattr_t         *vap)
+       bhv_vnode_t     *vp,
+       bhv_vattr_t     *vap)
 {
        struct inode    *inode = vn_to_inode(vp);
 
@@ -130,14 +146,14 @@ vn_revalidate_core(
  */
 int
 __vn_revalidate(
-       struct vnode    *vp,
-       struct vattr    *vattr)
+       bhv_vnode_t     *vp,
+       bhv_vattr_t     *vattr)
 {
        int             error;
 
        vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
        vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
-       VOP_GETATTR(vp, vattr, 0, NULL, error);
+       error = bhv_vop_getattr(vp, vattr, 0, NULL);
        if (likely(!error)) {
                vn_revalidate_core(vp, vattr);
                VUNMODIFY(vp);
@@ -147,9 +163,9 @@ __vn_revalidate(
 
 int
 vn_revalidate(
-       struct vnode    *vp)
+       bhv_vnode_t     *vp)
 {
-       vattr_t         vattr;
+       bhv_vattr_t     vattr;
 
        return __vn_revalidate(vp, &vattr);
 }
@@ -157,9 +173,9 @@ vn_revalidate(
 /*
  * Add a reference to a referenced vnode.
  */
-struct vnode *
+bhv_vnode_t *
 vn_hold(
-       struct vnode    *vp)
+       bhv_vnode_t     *vp)
 {
        struct inode    *inode;
 
@@ -192,31 +208,31 @@ vn_hold(
  * Vnode tracing code.
  */
 void
-vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra)
+vn_trace_entry(bhv_vnode_t *vp, const char *func, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra);
 }
 
 void
-vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra)
+vn_trace_exit(bhv_vnode_t *vp, const char *func, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra);
 }
 
 void
-vn_trace_hold(vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_hold(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_HOLD, file, line, ra);
 }
 
 void
-vn_trace_ref(vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_ref(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_REF, file, line, ra);
 }
 
 void
-vn_trace_rele(vnode_t *vp, char *file, int line, inst_t *ra)
+vn_trace_rele(bhv_vnode_t *vp, char *file, int line, inst_t *ra)
 {
        KTRACE_ENTER(vp, VNODE_KTRACE_RELE, file, line, ra);
 }
index 2a8e16c22353c98f44a12bc462130a43c2646555..35c6a01963a77c9c52af0ba70453926aab316f04 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write the Free Software Foundation,
  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Portions Copyright (c) 1989, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * 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.
  */
 #ifndef __XFS_VNODE_H__
 #define __XFS_VNODE_H__
 
 struct uio;
 struct file;
-struct vattr;
+struct bhv_vfs;
+struct bhv_vattr;
 struct xfs_iomap;
 struct attrlist_cursor_kern;
 
+typedef struct dentry  bhv_vname_t;
+typedef __u64          bhv_vnumber_t;
 
-typedef xfs_ino_t vnumber_t;
-typedef struct dentry vname_t;
-typedef bhv_head_t vn_bhv_head_t;
+typedef enum bhv_vflags {
+       VMODIFIED       = 0x08, /* XFS inode state possibly differs */
+                               /* to the Linux inode state. */
+       VTRUNCATED      = 0x40, /* truncated down so flush-on-close */
+} bhv_vflags_t;
 
 /*
  * MP locking protocols:
  *     v_flag, v_vfsp                          VN_LOCK/VN_UNLOCK
  */
-typedef struct vnode {
-       __u32           v_flag;                 /* vnode flags (see below) */
-       struct vfs      *v_vfsp;                /* ptr to containing VFS */
-       vnumber_t       v_number;               /* in-core vnode number */
-       vn_bhv_head_t   v_bh;                   /* behavior head */
+typedef struct bhv_vnode {
+       bhv_vflags_t    v_flag;                 /* vnode flags (see above) */
+       bhv_vfs_t       *v_vfsp;                /* ptr to containing VFS */
+       bhv_vnumber_t   v_number;               /* in-core vnode number */
+       bhv_head_t      v_bh;                   /* behavior head */
        spinlock_t      v_lock;                 /* VN_LOCK/VN_UNLOCK */
        atomic_t        v_iocount;              /* outstanding I/O count */
 #ifdef XFS_VNODE_TRACE
@@ -72,7 +50,7 @@ typedef struct vnode {
 #endif
        struct inode    v_inode;                /* Linux inode */
        /* inode MUST be last */
-} vnode_t;
+} bhv_vnode_t;
 
 #define VN_ISLNK(vp)   S_ISLNK((vp)->v_inode.i_mode)
 #define VN_ISREG(vp)   S_ISREG((vp)->v_inode.i_mode)
@@ -80,9 +58,6 @@ typedef struct vnode {
 #define VN_ISCHR(vp)   S_ISCHR((vp)->v_inode.i_mode)
 #define VN_ISBLK(vp)   S_ISBLK((vp)->v_inode.i_mode)
 
-#define v_fbhv                 v_bh.bh_first          /* first behavior */
-#define v_fops                 v_bh.bh_first->bd_ops  /* first behavior ops */
-
 #define VNODE_POSITION_BASE    BHV_POSITION_BASE       /* chain bottom */
 #define VNODE_POSITION_TOP     BHV_POSITION_TOP        /* chain top */
 #define VNODE_POSITION_INVALID BHV_POSITION_INVALID    /* invalid pos. num */
@@ -104,8 +79,8 @@ typedef enum {
 /*
  * Macros for dealing with the behavior descriptor inside of the vnode.
  */
-#define BHV_TO_VNODE(bdp)      ((vnode_t *)BHV_VOBJ(bdp))
-#define BHV_TO_VNODE_NULL(bdp) ((vnode_t *)BHV_VOBJNULL(bdp))
+#define BHV_TO_VNODE(bdp)      ((bhv_vnode_t *)BHV_VOBJ(bdp))
+#define BHV_TO_VNODE_NULL(bdp) ((bhv_vnode_t *)BHV_VOBJNULL(bdp))
 
 #define VN_BHV_HEAD(vp)                        ((bhv_head_t *)(&((vp)->v_bh)))
 #define vn_bhv_head_init(bhp,name)     bhv_head_init(bhp,name)
@@ -116,35 +91,29 @@ typedef enum {
 /*
  * Vnode to Linux inode mapping.
  */
-static inline struct vnode *vn_from_inode(struct inode *inode)
+static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
 {
-       return (vnode_t *)list_entry(inode, vnode_t, v_inode);
+       return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode);
 }
-static inline struct inode *vn_to_inode(struct vnode *vnode)
+static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
 {
        return &vnode->v_inode;
 }
 
 /*
- * Vnode flags.
- */
-#define VMODIFIED             0x8      /* XFS inode state possibly differs */
-                                       /* to the Linux inode state.    */
-
-/*
- * Values for the VOP_RWLOCK and VOP_RWUNLOCK flags parameter.
+ * Values for the vop_rwlock/rwunlock flags parameter.
  */
-typedef enum vrwlock {
+typedef enum bhv_vrwlock {
        VRWLOCK_NONE,
        VRWLOCK_READ,
        VRWLOCK_WRITE,
        VRWLOCK_WRITE_DIRECT,
        VRWLOCK_TRY_READ,
        VRWLOCK_TRY_WRITE
-} vrwlock_t;
+} bhv_vrwlock_t;
 
 /*
- * Return values for VOP_INACTIVE.  A return value of
+ * Return values for bhv_vop_inactive.  A return value of
  * VN_INACTIVE_NOCACHE implies that the file system behavior
  * has disassociated its state and bhv_desc_t from the vnode.
  */
@@ -152,18 +121,20 @@ typedef enum vrwlock {
 #define        VN_INACTIVE_NOCACHE     1
 
 /*
- * Values for the cmd code given to VOP_VNODE_CHANGE.
+ * Values for the cmd code given to vop_vnode_change.
  */
-typedef enum vchange {
+typedef enum bhv_vchange {
        VCHANGE_FLAGS_FRLOCKS           = 0,
        VCHANGE_FLAGS_ENF_LOCKING       = 1,
        VCHANGE_FLAGS_TRUNCATED         = 2,
        VCHANGE_FLAGS_PAGE_DIRTY        = 3,
        VCHANGE_FLAGS_IOEXCL_COUNT      = 4
-} vchange_t;
+} bhv_vchange_t;
 
+typedef enum { L_FALSE, L_TRUE } lastclose_t;
 
 typedef int    (*vop_open_t)(bhv_desc_t *, struct cred *);
+typedef int    (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
 typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
                                const struct iovec *, unsigned int,
                                loff_t *, int, struct cred *);
@@ -181,27 +152,27 @@ typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct pipe_inode_info *,
                                struct cred *);
 typedef int    (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
                                int, unsigned int, void __user *);
-typedef int    (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
+typedef int    (*vop_getattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
                                struct cred *);
-typedef int    (*vop_setattr_t)(bhv_desc_t *, struct vattr *, int,
+typedef int    (*vop_setattr_t)(bhv_desc_t *, struct bhv_vattr *, int,
                                struct cred *);
 typedef int    (*vop_access_t)(bhv_desc_t *, int, struct cred *);
-typedef int    (*vop_lookup_t)(bhv_desc_t *, vname_t *, vnode_t **,
-                               int, vnode_t *, struct cred *);
-typedef int    (*vop_create_t)(bhv_desc_t *, vname_t *, struct vattr *,
-                               vnode_t **, struct cred *);
-typedef int    (*vop_remove_t)(bhv_desc_t *, vname_t *, struct cred *);
-typedef int    (*vop_link_t)(bhv_desc_t *, vnode_t *, vname_t *,
-                               struct cred *);
-typedef int    (*vop_rename_t)(bhv_desc_t *, vname_t *, vnode_t *, vname_t *,
+typedef int    (*vop_lookup_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t **,
+                               int, bhv_vnode_t *, struct cred *);
+typedef int    (*vop_create_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
+                               bhv_vnode_t **, struct cred *);
+typedef int    (*vop_remove_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
+typedef int    (*vop_link_t)(bhv_desc_t *, bhv_vnode_t *, bhv_vname_t *,
                                struct cred *);
-typedef int    (*vop_mkdir_t)(bhv_desc_t *, vname_t *, struct vattr *,
-                               vnode_t **, struct cred *);
-typedef int    (*vop_rmdir_t)(bhv_desc_t *, vname_t *, struct cred *);
+typedef int    (*vop_rename_t)(bhv_desc_t *, bhv_vname_t *, bhv_vnode_t *,
+                               bhv_vname_t *, struct cred *);
+typedef int    (*vop_mkdir_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr *,
+                               bhv_vnode_t **, struct cred *);
+typedef int    (*vop_rmdir_t)(bhv_desc_t *, bhv_vname_t *, struct cred *);
 typedef int    (*vop_readdir_t)(bhv_desc_t *, struct uio *, struct cred *,
                                int *);
-typedef int    (*vop_symlink_t)(bhv_desc_t *, vname_t *, struct vattr *,
-                               char *, vnode_t **, struct cred *);
+typedef int    (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*,
+                               char *, bhv_vnode_t **, struct cred *);
 typedef int    (*vop_readlink_t)(bhv_desc_t *, struct uio *, int,
                                struct cred *);
 typedef int    (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
@@ -209,8 +180,8 @@ typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *,
 typedef int    (*vop_inactive_t)(bhv_desc_t *, struct cred *);
 typedef int    (*vop_fid2_t)(bhv_desc_t *, struct fid *);
 typedef int    (*vop_release_t)(bhv_desc_t *);
-typedef int    (*vop_rwlock_t)(bhv_desc_t *, vrwlock_t);
-typedef void   (*vop_rwunlock_t)(bhv_desc_t *, vrwlock_t);
+typedef int    (*vop_rwlock_t)(bhv_desc_t *, bhv_vrwlock_t);
+typedef void   (*vop_rwunlock_t)(bhv_desc_t *, bhv_vrwlock_t);
 typedef int    (*vop_bmap_t)(bhv_desc_t *, xfs_off_t, ssize_t, int,
                                struct xfs_iomap *, int *);
 typedef int    (*vop_reclaim_t)(bhv_desc_t *);
@@ -222,8 +193,8 @@ typedef     int     (*vop_attr_remove_t)(bhv_desc_t *, const char *,
                                int, struct cred *);
 typedef        int     (*vop_attr_list_t)(bhv_desc_t *, char *, int, int,
                                struct attrlist_cursor_kern *, struct cred *);
-typedef void   (*vop_link_removed_t)(bhv_desc_t *, vnode_t *, int);
-typedef void   (*vop_vnode_change_t)(bhv_desc_t *, vchange_t, __psint_t);
+typedef void   (*vop_link_removed_t)(bhv_desc_t *, bhv_vnode_t *, int);
+typedef void   (*vop_vnode_change_t)(bhv_desc_t *, bhv_vchange_t, __psint_t);
 typedef void   (*vop_ptossvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 typedef void   (*vop_pflushinvalvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 typedef int    (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
@@ -231,9 +202,10 @@ typedef int        (*vop_pflushvp_t)(bhv_desc_t *, xfs_off_t, xfs_off_t,
 typedef int    (*vop_iflush_t)(bhv_desc_t *, int);
 
 
-typedef struct vnodeops {
+typedef struct bhv_vnodeops {
        bhv_position_t  vn_position;    /* position within behavior chain */
        vop_open_t              vop_open;
+       vop_close_t             vop_close;
        vop_read_t              vop_read;
        vop_write_t             vop_write;
        vop_sendfile_t          vop_sendfile;
@@ -271,103 +243,80 @@ typedef struct vnodeops {
        vop_pflushvp_t          vop_flush_pages;
        vop_release_t           vop_release;
        vop_iflush_t            vop_iflush;
-} vnodeops_t;
+} bhv_vnodeops_t;
 
 /*
- * VOP's.
- */
-#define _VOP_(op, vp)  (*((vnodeops_t *)(vp)->v_fops)->op)
-
-#define VOP_READ(vp,file,iov,segs,offset,ioflags,cr,rv)                        \
-       rv = _VOP_(vop_read, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
-#define VOP_WRITE(vp,file,iov,segs,offset,ioflags,cr,rv)               \
-       rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
-#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv)              \
-       rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
-#define VOP_SPLICE_READ(vp,f,o,pipe,cnt,fl,iofl,cr,rv)                 \
-       rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
-#define VOP_SPLICE_WRITE(vp,f,o,pipe,cnt,fl,iofl,cr,rv)                        \
-       rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,o,pipe,cnt,fl,iofl,cr)
-#define VOP_BMAP(vp,of,sz,rw,b,n,rv)                                   \
-       rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
-#define VOP_OPEN(vp, cr, rv)                                           \
-       rv = _VOP_(vop_open, vp)((vp)->v_fbhv, cr)
-#define VOP_GETATTR(vp, vap, f, cr, rv)                                        \
-       rv = _VOP_(vop_getattr, vp)((vp)->v_fbhv, vap, f, cr)
-#define        VOP_SETATTR(vp, vap, f, cr, rv)                                 \
-       rv = _VOP_(vop_setattr, vp)((vp)->v_fbhv, vap, f, cr)
-#define        VOP_ACCESS(vp, mode, cr, rv)                                    \
-       rv = _VOP_(vop_access, vp)((vp)->v_fbhv, mode, cr)
-#define        VOP_LOOKUP(vp,d,vpp,f,rdir,cr,rv)                               \
-       rv = _VOP_(vop_lookup, vp)((vp)->v_fbhv,d,vpp,f,rdir,cr)
-#define VOP_CREATE(dvp,d,vap,vpp,cr,rv)                                        \
-       rv = _VOP_(vop_create, dvp)((dvp)->v_fbhv,d,vap,vpp,cr)
-#define VOP_REMOVE(dvp,d,cr,rv)                                                \
-       rv = _VOP_(vop_remove, dvp)((dvp)->v_fbhv,d,cr)
-#define        VOP_LINK(tdvp,fvp,d,cr,rv)                                      \
-       rv = _VOP_(vop_link, tdvp)((tdvp)->v_fbhv,fvp,d,cr)
-#define        VOP_RENAME(fvp,fnm,tdvp,tnm,cr,rv)                              \
-       rv = _VOP_(vop_rename, fvp)((fvp)->v_fbhv,fnm,tdvp,tnm,cr)
-#define        VOP_MKDIR(dp,d,vap,vpp,cr,rv)                                   \
-       rv = _VOP_(vop_mkdir, dp)((dp)->v_fbhv,d,vap,vpp,cr)
-#define        VOP_RMDIR(dp,d,cr,rv)                                           \
-       rv = _VOP_(vop_rmdir, dp)((dp)->v_fbhv,d,cr)
-#define        VOP_READDIR(vp,uiop,cr,eofp,rv)                                 \
-       rv = _VOP_(vop_readdir, vp)((vp)->v_fbhv,uiop,cr,eofp)
-#define        VOP_SYMLINK(dvp,d,vap,tnm,vpp,cr,rv)                            \
-       rv = _VOP_(vop_symlink, dvp) ((dvp)->v_fbhv,d,vap,tnm,vpp,cr)
-#define        VOP_READLINK(vp,uiop,fl,cr,rv)                                  \
-       rv = _VOP_(vop_readlink, vp)((vp)->v_fbhv,uiop,fl,cr)
-#define        VOP_FSYNC(vp,f,cr,b,e,rv)                                       \
-       rv = _VOP_(vop_fsync, vp)((vp)->v_fbhv,f,cr,b,e)
-#define VOP_INACTIVE(vp, cr, rv)                                       \
-       rv = _VOP_(vop_inactive, vp)((vp)->v_fbhv, cr)
-#define VOP_RELEASE(vp, rv)                                            \
-       rv = _VOP_(vop_release, vp)((vp)->v_fbhv)
-#define VOP_FID2(vp, fidp, rv)                                         \
-       rv = _VOP_(vop_fid2, vp)((vp)->v_fbhv, fidp)
-#define VOP_RWLOCK(vp,i)                                               \
-       (void)_VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
-#define VOP_RWLOCK_TRY(vp,i)                                           \
-       _VOP_(vop_rwlock, vp)((vp)->v_fbhv, i)
-#define VOP_RWUNLOCK(vp,i)                                             \
-       (void)_VOP_(vop_rwunlock, vp)((vp)->v_fbhv, i)
-#define VOP_FRLOCK(vp,c,fl,flags,offset,fr,rv)                         \
-       rv = _VOP_(vop_frlock, vp)((vp)->v_fbhv,c,fl,flags,offset,fr)
-#define VOP_RECLAIM(vp, rv)                                            \
-       rv = _VOP_(vop_reclaim, vp)((vp)->v_fbhv)
-#define VOP_ATTR_GET(vp, name, val, vallenp, fl, cred, rv)             \
-       rv = _VOP_(vop_attr_get, vp)((vp)->v_fbhv,name,val,vallenp,fl,cred)
-#define        VOP_ATTR_SET(vp, name, val, vallen, fl, cred, rv)               \
-       rv = _VOP_(vop_attr_set, vp)((vp)->v_fbhv,name,val,vallen,fl,cred)
-#define        VOP_ATTR_REMOVE(vp, name, flags, cred, rv)                      \
-       rv = _VOP_(vop_attr_remove, vp)((vp)->v_fbhv,name,flags,cred)
-#define        VOP_ATTR_LIST(vp, buf, buflen, fl, cursor, cred, rv)            \
-       rv = _VOP_(vop_attr_list, vp)((vp)->v_fbhv,buf,buflen,fl,cursor,cred)
-#define VOP_LINK_REMOVED(vp, dvp, linkzero)                            \
-       (void)_VOP_(vop_link_removed, vp)((vp)->v_fbhv, dvp, linkzero)
-#define VOP_VNODE_CHANGE(vp, cmd, val)                                 \
-       (void)_VOP_(vop_vnode_change, vp)((vp)->v_fbhv,cmd,val)
-/*
- * These are page cache functions that now go thru VOPs.
- * 'last' parameter is unused and left in for IRIX compatibility
+ * Virtual node operations, operating from head bhv.
  */
-#define VOP_TOSS_PAGES(vp, first, last, fiopt)                         \
-       _VOP_(vop_tosspages, vp)((vp)->v_fbhv,first, last, fiopt)
-/*
- * 'last' parameter is unused and left in for IRIX compatibility
- */
-#define VOP_FLUSHINVAL_PAGES(vp, first, last, fiopt)                   \
-       _VOP_(vop_flushinval_pages, vp)((vp)->v_fbhv,first,last,fiopt)
-/*
- * 'last' parameter is unused and left in for IRIX compatibility
- */
-#define VOP_FLUSH_PAGES(vp, first, last, flags, fiopt, rv)             \
-       rv = _VOP_(vop_flush_pages, vp)((vp)->v_fbhv,first,last,flags,fiopt)
-#define VOP_IOCTL(vp, inode, filp, fl, cmd, arg, rv)                   \
-       rv = _VOP_(vop_ioctl, vp)((vp)->v_fbhv,inode,filp,fl,cmd,arg)
-#define VOP_IFLUSH(vp, flags, rv)                                      \
-       rv = _VOP_(vop_iflush, vp)((vp)->v_fbhv, flags)
+#define VNHEAD(vp)     ((vp)->v_bh.bh_first)
+#define VOP(op, vp)    (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
+#define bhv_vop_open(vp, cr)           VOP(vop_open, vp)(VNHEAD(vp),cr)
+#define bhv_vop_close(vp, f,last,cr)   VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
+#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr)               \
+               VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
+#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr)              \
+               VOP(vop_write, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
+#define bhv_vop_sendfile(vp,f,off,ioflags,cnt,act,targ,cr)             \
+               VOP(vop_sendfile, vp)(VNHEAD(vp),f,off,ioflags,cnt,act,targ,cr)
+#define bhv_vop_splice_read(vp,f,o,pipe,cnt,fl,iofl,cr)                        \
+               VOP(vop_splice_read, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
+#define bhv_vop_splice_write(vp,f,o,pipe,cnt,fl,iofl,cr)               \
+               VOP(vop_splice_write, vp)(VNHEAD(vp),f,o,pipe,cnt,fl,iofl,cr)
+#define bhv_vop_bmap(vp,of,sz,rw,b,n)                                  \
+               VOP(vop_bmap, vp)(VNHEAD(vp),of,sz,rw,b,n)
+#define bhv_vop_getattr(vp, vap,f,cr)                                  \
+               VOP(vop_getattr, vp)(VNHEAD(vp), vap,f,cr)
+#define        bhv_vop_setattr(vp, vap,f,cr)                                   \
+               VOP(vop_setattr, vp)(VNHEAD(vp), vap,f,cr)
+#define        bhv_vop_access(vp, mode,cr)     VOP(vop_access, vp)(VNHEAD(vp), mode,cr)
+#define        bhv_vop_lookup(vp,d,vpp,f,rdir,cr)                              \
+               VOP(vop_lookup, vp)(VNHEAD(vp),d,vpp,f,rdir,cr)
+#define bhv_vop_create(dvp,d,vap,vpp,cr)                               \
+               VOP(vop_create, dvp)(VNHEAD(dvp),d,vap,vpp,cr)
+#define bhv_vop_remove(dvp,d,cr)       VOP(vop_remove, dvp)(VNHEAD(dvp),d,cr)
+#define        bhv_vop_link(dvp,fvp,d,cr)      VOP(vop_link, dvp)(VNHEAD(dvp),fvp,d,cr)
+#define        bhv_vop_rename(fvp,fnm,tdvp,tnm,cr)                             \
+               VOP(vop_rename, fvp)(VNHEAD(fvp),fnm,tdvp,tnm,cr)
+#define        bhv_vop_mkdir(dp,d,vap,vpp,cr)                                  \
+               VOP(vop_mkdir, dp)(VNHEAD(dp),d,vap,vpp,cr)
+#define        bhv_vop_rmdir(dp,d,cr)          VOP(vop_rmdir, dp)(VNHEAD(dp),d,cr)
+#define        bhv_vop_readdir(vp,uiop,cr,eofp)                                \
+               VOP(vop_readdir, vp)(VNHEAD(vp),uiop,cr,eofp)
+#define        bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr)                           \
+               VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr)
+#define        bhv_vop_readlink(vp,uiop,fl,cr)                                 \
+               VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr)
+#define        bhv_vop_fsync(vp,f,cr,b,e)      VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e)
+#define bhv_vop_inactive(vp,cr)                VOP(vop_inactive, vp)(VNHEAD(vp),cr)
+#define bhv_vop_release(vp)            VOP(vop_release, vp)(VNHEAD(vp))
+#define bhv_vop_fid2(vp,fidp)          VOP(vop_fid2, vp)(VNHEAD(vp),fidp)
+#define bhv_vop_rwlock(vp,i)           VOP(vop_rwlock, vp)(VNHEAD(vp),i)
+#define bhv_vop_rwlock_try(vp,i)       VOP(vop_rwlock, vp)(VNHEAD(vp),i)
+#define bhv_vop_rwunlock(vp,i)         VOP(vop_rwunlock, vp)(VNHEAD(vp),i)
+#define bhv_vop_frlock(vp,c,fl,flags,offset,fr)                                \
+               VOP(vop_frlock, vp)(VNHEAD(vp),c,fl,flags,offset,fr)
+#define bhv_vop_reclaim(vp)            VOP(vop_reclaim, vp)(VNHEAD(vp))
+#define bhv_vop_attr_get(vp, name, val, vallenp, fl, cred)             \
+               VOP(vop_attr_get, vp)(VNHEAD(vp),name,val,vallenp,fl,cred)
+#define        bhv_vop_attr_set(vp, name, val, vallen, fl, cred)               \
+               VOP(vop_attr_set, vp)(VNHEAD(vp),name,val,vallen,fl,cred)
+#define        bhv_vop_attr_remove(vp, name, flags, cred)                      \
+               VOP(vop_attr_remove, vp)(VNHEAD(vp),name,flags,cred)
+#define        bhv_vop_attr_list(vp, buf, buflen, fl, cursor, cred)            \
+               VOP(vop_attr_list, vp)(VNHEAD(vp),buf,buflen,fl,cursor,cred)
+#define bhv_vop_link_removed(vp, dvp, linkzero)                                \
+               VOP(vop_link_removed, vp)(VNHEAD(vp), dvp, linkzero)
+#define bhv_vop_vnode_change(vp, cmd, val)                             \
+               VOP(vop_vnode_change, vp)(VNHEAD(vp), cmd, val)
+#define bhv_vop_toss_pages(vp, first, last, fiopt)                     \
+               VOP(vop_tosspages, vp)(VNHEAD(vp), first, last, fiopt)
+#define bhv_vop_flushinval_pages(vp, first, last, fiopt)               \
+               VOP(vop_flushinval_pages, vp)(VNHEAD(vp),first,last,fiopt)
+#define bhv_vop_flush_pages(vp, first, last, flags, fiopt)             \
+               VOP(vop_flush_pages, vp)(VNHEAD(vp),first,last,flags,fiopt)
+#define bhv_vop_ioctl(vp, inode, filp, fl, cmd, arg)                   \
+               VOP(vop_ioctl, vp)(VNHEAD(vp),inode,filp,fl,cmd,arg)
+#define bhv_vop_iflush(vp, flags)      VOP(vop_iflush, vp)(VNHEAD(vp), flags)
 
 /*
  * Flags for read/write calls - same values as IRIX
@@ -377,7 +326,7 @@ typedef struct vnodeops {
 #define IO_INVIS       0x00020         /* don't update inode timestamps */
 
 /*
- * Flags for VOP_IFLUSH call
+ * Flags for vop_iflush call
  */
 #define FLUSH_SYNC             1       /* wait for flush to complete   */
 #define FLUSH_INODE            2       /* flush the inode itself       */
@@ -385,8 +334,7 @@ typedef struct vnodeops {
                                         * this inode out to disk       */
 
 /*
- * Flush/Invalidate options for VOP_TOSS_PAGES, VOP_FLUSHINVAL_PAGES and
- *     VOP_FLUSH_PAGES.
+ * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
  */
 #define FI_NONE                        0       /* none */
 #define FI_REMAPF              1       /* Do a remapf prior to the operation */
@@ -398,7 +346,7 @@ typedef struct vnodeops {
  * Vnode attributes.  va_mask indicates those attributes the caller
  * wants to set or extract.
  */
-typedef struct vattr {
+typedef struct bhv_vattr {
        int             va_mask;        /* bit-mask of attributes present */
        mode_t          va_mode;        /* file access mode and type */
        xfs_nlink_t     va_nlink;       /* number of references to file */
@@ -418,7 +366,7 @@ typedef struct vattr {
        u_long          va_nextents;    /* number of extents in file */
        u_long          va_anextents;   /* number of attr extents in file */
        prid_t          va_projid;      /* project id */
-} vattr_t;
+} bhv_vattr_t;
 
 /*
  * setattr or getattr attributes
@@ -492,29 +440,17 @@ typedef struct vattr {
        (VN_ISREG(vp) && ((mode) & (VSGID|(VEXEC>>3))) == VSGID)
 
 extern void    vn_init(void);
-extern vnode_t *vn_initialize(struct inode *);
-
-/*
- * vnode_map structures _must_ match vn_epoch and vnode structure sizes.
- */
-typedef struct vnode_map {
-       vfs_t           *v_vfsp;
-       vnumber_t       v_number;               /* in-core vnode number */
-       xfs_ino_t       v_ino;                  /* inode #      */
-} vmap_t;
-
-#define VMAP(vp, vmap) {(vmap).v_vfsp   = (vp)->v_vfsp,        \
-                        (vmap).v_number = (vp)->v_number,      \
-                        (vmap).v_ino    = (vp)->v_inode.i_ino; }
+extern bhv_vnode_t     *vn_initialize(struct inode *);
+extern int     vn_revalidate(struct bhv_vnode *);
+extern int     __vn_revalidate(struct bhv_vnode *, bhv_vattr_t *);
+extern void    vn_revalidate_core(struct bhv_vnode *, bhv_vattr_t *);
 
-extern int     vn_revalidate(struct vnode *);
-extern int     __vn_revalidate(struct vnode *, vattr_t *);
-extern void    vn_revalidate_core(struct vnode *, vattr_t *);
+extern void    vn_iowait(struct bhv_vnode *vp);
+extern void    vn_iowake(struct bhv_vnode *vp);
 
-extern void    vn_iowait(struct vnode *vp);
-extern void    vn_iowake(struct vnode *vp);
+extern void    vn_ioerror(struct bhv_vnode *vp, int error, char *f, int l);
 
-static inline int vn_count(struct vnode *vp)
+static inline int vn_count(struct bhv_vnode *vp)
 {
        return atomic_read(&vn_to_inode(vp)->i_count);
 }
@@ -522,7 +458,7 @@ static inline int vn_count(struct vnode *vp)
 /*
  * Vnode reference counting functions (and macros for compatibility).
  */
-extern vnode_t *vn_hold(struct vnode *);
+extern bhv_vnode_t     *vn_hold(struct bhv_vnode *);
 
 #if defined(XFS_VNODE_TRACE)
 #define VN_HOLD(vp)            \
@@ -536,7 +472,7 @@ extern vnode_t      *vn_hold(struct vnode *);
 #define VN_RELE(vp)            (iput(vn_to_inode(vp)))
 #endif
 
-static inline struct vnode *vn_grab(struct vnode *vp)
+static inline struct bhv_vnode *vn_grab(struct bhv_vnode *vp)
 {
        struct inode *inode = igrab(vn_to_inode(vp));
        return inode ? vn_from_inode(inode) : NULL;
@@ -554,32 +490,39 @@ static inline struct vnode *vn_grab(struct vnode *vp)
  */
 #define VN_LOCK(vp)            mutex_spinlock(&(vp)->v_lock)
 #define VN_UNLOCK(vp, s)       mutex_spinunlock(&(vp)->v_lock, s)
-#define VN_FLAGSET(vp,b)       vn_flagset(vp,b)
-#define VN_FLAGCLR(vp,b)       vn_flagclr(vp,b)
 
-static __inline__ void vn_flagset(struct vnode *vp, uint flag)
+static __inline__ void vn_flagset(struct bhv_vnode *vp, uint flag)
 {
        spin_lock(&vp->v_lock);
        vp->v_flag |= flag;
        spin_unlock(&vp->v_lock);
 }
 
-static __inline__ void vn_flagclr(struct vnode *vp, uint flag)
+static __inline__ uint vn_flagclr(struct bhv_vnode *vp, uint flag)
 {
+       uint    cleared;
+
        spin_lock(&vp->v_lock);
+       cleared = (vp->v_flag & flag);
        vp->v_flag &= ~flag;
        spin_unlock(&vp->v_lock);
+       return cleared;
 }
 
+#define VMODIFY(vp)    vn_flagset(vp, VMODIFIED)
+#define VUNMODIFY(vp)  vn_flagclr(vp, VMODIFIED)
+#define VTRUNCATE(vp)  vn_flagset(vp, VTRUNCATED)
+#define VUNTRUNCATE(vp)        vn_flagclr(vp, VTRUNCATED)
+
 /*
  * Dealing with bad inodes
  */
-static inline void vn_mark_bad(struct vnode *vp)
+static inline void vn_mark_bad(struct bhv_vnode *vp)
 {
        make_bad_inode(vn_to_inode(vp));
 }
 
-static inline int VN_BAD(struct vnode *vp)
+static inline int VN_BAD(struct bhv_vnode *vp)
 {
        return is_bad_inode(vn_to_inode(vp));
 }
@@ -587,18 +530,18 @@ static inline int VN_BAD(struct vnode *vp)
 /*
  * Extracting atime values in various formats
  */
-static inline void vn_atime_to_bstime(struct vnode *vp, xfs_bstime_t *bs_atime)
+static inline void vn_atime_to_bstime(bhv_vnode_t *vp, xfs_bstime_t *bs_atime)
 {
        bs_atime->tv_sec = vp->v_inode.i_atime.tv_sec;
        bs_atime->tv_nsec = vp->v_inode.i_atime.tv_nsec;
 }
 
-static inline void vn_atime_to_timespec(struct vnode *vp, struct timespec *ts)
+static inline void vn_atime_to_timespec(bhv_vnode_t *vp, struct timespec *ts)
 {
        *ts = vp->v_inode.i_atime;
 }
 
-static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
+static inline void vn_atime_to_time_t(bhv_vnode_t *vp, time_t *tt)
 {
        *tt = vp->v_inode.i_atime.tv_sec;
 }
@@ -610,11 +553,10 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
 #define VN_CACHED(vp)  (vn_to_inode(vp)->i_mapping->nrpages)
 #define VN_DIRTY(vp)   mapping_tagged(vn_to_inode(vp)->i_mapping, \
                                        PAGECACHE_TAG_DIRTY)
-#define VMODIFY(vp)    VN_FLAGSET(vp, VMODIFIED)
-#define VUNMODIFY(vp)  VN_FLAGCLR(vp, VMODIFIED)
+#define VN_TRUNC(vp)   ((vp)->v_flag & VTRUNCATED)
 
 /*
- * Flags to VOP_SETATTR/VOP_GETATTR.
+ * Flags to vop_setattr/getattr.
  */
 #define        ATTR_UTIME      0x01    /* non-default utime(2) request */
 #define        ATTR_DMI        0x08    /* invocation from a DMI function */
@@ -624,7 +566,7 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
 #define ATTR_NOSIZETOK 0x400   /* Don't get the SIZE token */
 
 /*
- * Flags to VOP_FSYNC and VOP_RECLAIM.
+ * Flags to vop_fsync/reclaim.
  */
 #define FSYNC_NOWAIT   0       /* asynchronous flush */
 #define FSYNC_WAIT     0x1     /* synchronous fsync or forced reclaim */
@@ -643,11 +585,11 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
 #define        VNODE_KTRACE_REF        4
 #define        VNODE_KTRACE_RELE       5
 
-extern void vn_trace_entry(struct vnode *, const char *, inst_t *);
-extern void vn_trace_exit(struct vnode *, const char *, inst_t *);
-extern void vn_trace_hold(struct vnode *, char *, int, inst_t *);
-extern void vn_trace_ref(struct vnode *, char *, int, inst_t *);
-extern void vn_trace_rele(struct vnode *, char *, int, inst_t *);
+extern void vn_trace_entry(struct bhv_vnode *, const char *, inst_t *);
+extern void vn_trace_exit(struct bhv_vnode *, const char *, inst_t *);
+extern void vn_trace_hold(struct bhv_vnode *, char *, int, inst_t *);
+extern void vn_trace_ref(struct bhv_vnode *, char *, int, inst_t *);
+extern void vn_trace_rele(struct bhv_vnode *, char *, int, inst_t *);
 
 #define        VN_TRACE(vp)            \
        vn_trace_ref(vp, __FILE__, __LINE__, (inst_t *)__return_address)
index 772ac48329ea04661193044f68fc417507db214e..3aa771531856219a47f936013c1fcf046ef09eaa 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -444,7 +442,7 @@ xfs_qm_dqalloc(
                              XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
                              &firstblock,
                              XFS_QM_DQALLOC_SPACE_RES(mp),
-                             &map, &nmaps, &flist))) {
+                             &map, &nmaps, &flist, NULL))) {
                goto error0;
        }
        ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -559,7 +557,7 @@ xfs_qm_dqtobp(
                error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
                                  XFS_DQUOT_CLUSTER_SIZE_FSB,
                                  XFS_BMAPI_METADATA,
-                                 NULL, 0, &map, &nmaps, NULL);
+                                 NULL, 0, &map, &nmaps, NULL, NULL);
 
                xfs_iunlock(quotip, XFS_ILOCK_SHARED);
                if (error)
@@ -1261,7 +1259,7 @@ xfs_qm_dqflush(
 
        if (xfs_qm_dqcheck(&dqp->q_core, be32_to_cpu(ddqp->d_id),
                           0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
-               xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
+               xfs_force_shutdown(dqp->q_mount, SHUTDOWN_CORRUPT_INCORE);
                return XFS_ERROR(EIO);
        }
 
index c0c629663a5c7206e3d115b81f24684799a6513d..78d3ab95c5fda9224c9927e3cb6816aac907d7b8 100644 (file)
@@ -119,7 +119,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
  */
 #define xfs_dqflock(dqp)        { psema(&((dqp)->q_flock), PINOD | PRECALC);\
                                   (dqp)->dq_flags |= XFS_DQ_FLOCKED; }
-#define xfs_dqfunlock(dqp)      { ASSERT(valusema(&((dqp)->q_flock)) <= 0); \
+#define xfs_dqfunlock(dqp)      { ASSERT(issemalocked(&((dqp)->q_flock))); \
                                   vsema(&((dqp)->q_flock)); \
                                   (dqp)->dq_flags &= ~(XFS_DQ_FLOCKED); }
 
@@ -128,7 +128,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
 #define XFS_DQ_PINUNLOCK(dqp, s)   mutex_spinunlock( \
                                     &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s)
 
-#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (valusema(&((dqp)->q_flock)) <= 0)
+#define XFS_DQ_IS_FLUSH_LOCKED(dqp) (issemalocked(&((dqp)->q_flock)))
 #define XFS_DQ_IS_ON_FREELIST(dqp)  ((dqp)->dq_flnext != (dqp))
 #define XFS_DQ_IS_DIRTY(dqp)   ((dqp)->dq_flags & XFS_DQ_DIRTY)
 #define XFS_QM_ISUDQ(dqp)      ((dqp)->dq_flags & XFS_DQ_USER)
index 546f48af882ae306cb2a5d52949db1e32bd1bf39..5b2dcc58b24430105bcca1860d7a589e811a3228 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -248,7 +246,7 @@ xfs_qm_dquot_logitem_pushbuf(
         * inode flush completed and the inode was taken off the AIL.
         * So, just get out.
         */
-       if ((valusema(&(dqp->q_flock)) > 0)  ||
+       if (!issemalocked(&(dqp->q_flock))  ||
            ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
                qip->qli_pushbuf_flag = 0;
                xfs_dqunlock(dqp);
@@ -261,7 +259,7 @@ xfs_qm_dquot_logitem_pushbuf(
        if (bp != NULL) {
                if (XFS_BUF_ISDELAYWRITE(bp)) {
                        dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
-                                 (valusema(&(dqp->q_flock)) <= 0));
+                                 issemalocked(&(dqp->q_flock)));
                        qip->qli_pushbuf_flag = 0;
                        xfs_dqunlock(dqp);
 
index 7fb5eca9bd5017df4ba44267ef496c7319b260f7..e23e45535c48219855daa75be9aa60d2f977c790 100644 (file)
@@ -24,7 +24,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -1603,7 +1601,7 @@ xfs_qm_dqiterate(
                                  maxlblkcnt - lblkno,
                                  XFS_BMAPI_METADATA,
                                  NULL,
-                                 0, map, &nmaps, NULL);
+                                 0, map, &nmaps, NULL, NULL);
                xfs_iunlock(qip, XFS_ILOCK_SHARED);
                if (error)
                        break;
@@ -1905,9 +1903,7 @@ xfs_qm_quotacheck(
                 */
                if ((error = xfs_bulkstat(mp, &lastino, &count,
                                     xfs_qm_dqusage_adjust, NULL,
-                                    structsz, NULL,
-                                    BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
-                                    &done)))
+                                    structsz, NULL, BULKSTAT_FG_IGET, &done)))
                        break;
 
        } while (! done);
index 6838b36d95a9bc283850aef2a12a1d680a8ea6f1..e95e99f7168fdb78f6f7b724fbc66a5acdf35aef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -129,7 +127,7 @@ xfs_qm_parseargs(
                return XFS_ERROR(EINVAL);
        }
 
-       PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
+       error = bhv_next_vfs_parseargs(BHV_NEXT(bhv), options, args, update);
        if (!error && !referenced)
                bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
        return error;
@@ -140,9 +138,8 @@ xfs_qm_showargs(
        struct bhv_desc         *bhv,
        struct seq_file         *m)
 {
-       struct vfs              *vfsp = bhvtovfs(bhv);
+       struct bhv_vfs          *vfsp = bhvtovfs(bhv);
        struct xfs_mount        *mp = XFS_VFSTOM(vfsp);
-       int                     error;
 
        if (mp->m_qflags & XFS_UQUOTA_ACCT) {
                (mp->m_qflags & XFS_UQUOTA_ENFD) ?
@@ -165,8 +162,7 @@ xfs_qm_showargs(
        if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
                seq_puts(m, "," MNTOPT_NOQUOTA);
 
-       PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
-       return error;
+       return bhv_next_vfs_showargs(BHV_NEXT(bhv), m);
 }
 
 STATIC int
@@ -175,14 +171,67 @@ xfs_qm_mount(
        struct xfs_mount_args   *args,
        struct cred             *cr)
 {
-       struct vfs              *vfsp = bhvtovfs(bhv);
+       struct bhv_vfs          *vfsp = bhvtovfs(bhv);
        struct xfs_mount        *mp = XFS_VFSTOM(vfsp);
-       int                     error;
 
        if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
                xfs_qm_mount_quotainit(mp, args->flags);
-       PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
-       return error;
+       return bhv_next_vfs_mount(BHV_NEXT(bhv), args, cr);
+}
+
+/*
+ * Directory tree accounting is implemented using project quotas, where
+ * the project identifier is inherited from parent directories.
+ * A statvfs (df, etc.) of a directory that is using project quota should
+ * return a statvfs of the project, not the entire filesystem.
+ * This makes such trees appear as if they are filesystems in themselves.
+ */
+STATIC int
+xfs_qm_statvfs(
+       struct bhv_desc         *bhv,
+       bhv_statvfs_t           *statp,
+       struct bhv_vnode        *vnode)
+{
+       xfs_mount_t             *mp;
+       xfs_inode_t             *ip;
+       xfs_dquot_t             *dqp;
+       xfs_disk_dquot_t        *dp;
+       __uint64_t              limit;
+       int                     error;
+
+       error = bhv_next_vfs_statvfs(BHV_NEXT(bhv), statp, vnode);
+       if (error || !vnode)
+               return error;
+
+       mp = XFS_BHVTOM(bhv);
+       ip = xfs_vtoi(vnode);
+
+       if (!(ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
+               return 0;
+       if (!(mp->m_qflags & XFS_PQUOTA_ACCT))
+               return 0;
+       if (!(mp->m_qflags & XFS_OQUOTA_ENFD))
+               return 0;
+
+       if (xfs_qm_dqget(mp, NULL, ip->i_d.di_projid, XFS_DQ_PROJ, 0, &dqp))
+               return 0;
+       dp = &dqp->q_core;
+
+       limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit;
+       if (limit && statp->f_blocks > limit) {
+               statp->f_blocks = limit;
+               statp->f_bfree = (statp->f_blocks > dp->d_bcount) ?
+                                       (statp->f_blocks - dp->d_bcount) : 0;
+       }
+       limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit;
+       if (limit && statp->f_files > limit) {
+               statp->f_files = limit;
+               statp->f_ffree = (statp->f_files > dp->d_icount) ?
+                                       (statp->f_ffree - dp->d_icount) : 0;
+       }
+
+       xfs_qm_dqput(dqp);
+       return 0;
 }
 
 STATIC int
@@ -191,7 +240,7 @@ xfs_qm_syncall(
        int                     flags,
        cred_t                  *credp)
 {
-       struct vfs              *vfsp = bhvtovfs(bhv);
+       struct bhv_vfs          *vfsp = bhvtovfs(bhv);
        struct xfs_mount        *mp = XFS_VFSTOM(vfsp);
        int                     error;
 
@@ -210,8 +259,7 @@ xfs_qm_syncall(
                        }
                }
        }
-       PVFS_SYNC(BHV_NEXT(bhv), flags, credp, error);
-       return error;
+       return bhv_next_vfs_sync(BHV_NEXT(bhv), flags, credp);
 }
 
 STATIC int
@@ -346,11 +394,12 @@ STATIC struct xfs_qmops xfs_qmcore_xfs = {
        .xfs_dqtrxops           = &xfs_trans_dquot_ops,
 };
 
-struct bhv_vfsops xfs_qmops = { {
+struct bhv_module_vfsops xfs_qmops = { {
        BHV_IDENTITY_INIT(VFS_BHV_QM, VFS_POSITION_QM),
        .vfs_parseargs          = xfs_qm_parseargs,
        .vfs_showargs           = xfs_qm_showargs,
        .vfs_mount              = xfs_qm_mount,
+       .vfs_statvfs            = xfs_qm_statvfs,
        .vfs_sync               = xfs_qm_syncall,
        .vfs_quotactl           = xfs_qm_quotactl, },
 };
index 0570f77335505b3ab52a2e46ea74b0ef17eaf049..6f858fb81a369edfdb99deee3f14e7d782806364 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
index c55db463bbf2b1b7895a461c1bb7cb18ae15f7bd..ed620c4d15941396e5bec0cc27cb0628a0b7dbc6 100644 (file)
@@ -26,7 +26,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -35,7 +34,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -91,8 +89,8 @@ xfs_qm_quotactl(
        xfs_caddr_t     addr)
 {
        xfs_mount_t     *mp;
+       bhv_vfs_t       *vfsp;
        int             error;
-       struct vfs      *vfsp;
 
        vfsp = bhvtovfs(bdp);
        mp = XFS_VFSTOM(vfsp);
@@ -1035,7 +1033,7 @@ xfs_qm_dqrele_all_inodes(
 {
        xfs_inode_t     *ip, *topino;
        uint            ireclaims;
-       vnode_t         *vp;
+       bhv_vnode_t     *vp;
        boolean_t       vnode_refd;
 
        ASSERT(mp->m_quotainfo);
index 9168918db252fa3c55087f173c0c418da70f7b9e..0242e9666e8e087b3180938aefca3f198df28724 100644 (file)
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -33,7 +32,6 @@
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
 #include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
index b08b3d9345b7660972cb341fb876ac1ba77cb52c..36fbeccdc722c27a5492076fad587b13f98d5e8c 100644 (file)
@@ -47,7 +47,7 @@ cmn_err(register int level, char *fmt, ...)
        va_start(ap, fmt);
        if (*fmt == '!') fp++;
        len = vsprintf(message, fp, ap);
-       if (message[len-1] != '\n')
+       if (level != CE_DEBUG && message[len-1] != '\n')
                strcat(message, "\n");
        printk("%s%s", err_level[level], message);
        va_end(ap);
@@ -68,7 +68,7 @@ icmn_err(register int level, char *fmt, va_list ap)
                level = XFS_MAX_ERR_LEVEL;
        spin_lock_irqsave(&xfs_err_lock,flags);
        len = vsprintf(message, fmt, ap);
-       if (message[len-1] != '\n')
+       if (level != CE_DEBUG && message[len-1] != '\n')
                strcat(message, "\n");
        spin_unlock_irqrestore(&xfs_err_lock,flags);
        printk("%s%s", err_level[level], message);
index e3bf58112e7ec3492cbe4be9fd546b39a59cbbff..4f54dca662a89ca646f9ff27a51d129a1c42a4de 100644 (file)
@@ -33,9 +33,6 @@ extern void cmn_err(int, char *, ...)
        __attribute__ ((format (printf, 2, 3)));
 extern void assfail(char *expr, char *f, int l);
 
-#define prdev(fmt,targ,args...) \
-       printk("Device %s - " fmt "\n", XFS_BUFTARG_NAME(targ), ## args)
-
 #define ASSERT_ALWAYS(expr)    \
        (unlikely((expr) != 0) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
 
index 2539af34eb6376cd48c948f84398d1b9d843b443..4b0cb474be4c3906c79fa6e997f8b2e1e3c15639 100644 (file)
 #include "xfs_bit.h"
 #include "xfs_inum.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
 #include <linux/capability.h>
 #include <linux/posix_acl_xattr.h>
 
-STATIC int     xfs_acl_setmode(vnode_t *, xfs_acl_t *, int *);
+STATIC int     xfs_acl_setmode(bhv_vnode_t *, xfs_acl_t *, int *);
 STATIC void     xfs_acl_filter_mode(mode_t, xfs_acl_t *);
 STATIC void    xfs_acl_get_endian(xfs_acl_t *);
 STATIC int     xfs_acl_access(uid_t, gid_t, xfs_acl_t *, mode_t, cred_t *);
 STATIC int     xfs_acl_invalid(xfs_acl_t *);
 STATIC void    xfs_acl_sync_mode(mode_t, xfs_acl_t *);
-STATIC void    xfs_acl_get_attr(vnode_t *, xfs_acl_t *, int, int, int *);
-STATIC void    xfs_acl_set_attr(vnode_t *, xfs_acl_t *, int, int *);
-STATIC int     xfs_acl_allow_set(vnode_t *, int);
+STATIC void    xfs_acl_get_attr(bhv_vnode_t *, xfs_acl_t *, int, int, int *);
+STATIC void    xfs_acl_set_attr(bhv_vnode_t *, xfs_acl_t *, int, int *);
+STATIC int     xfs_acl_allow_set(bhv_vnode_t *, int);
 
 kmem_zone_t *xfs_acl_zone;
 
@@ -57,7 +55,7 @@ kmem_zone_t *xfs_acl_zone;
  */
 int
 xfs_acl_vhasacl_access(
-       vnode_t         *vp)
+       bhv_vnode_t     *vp)
 {
        int             error;
 
@@ -70,7 +68,7 @@ xfs_acl_vhasacl_access(
  */
 int
 xfs_acl_vhasacl_default(
-       vnode_t         *vp)
+       bhv_vnode_t     *vp)
 {
        int             error;
 
@@ -209,7 +207,7 @@ posix_acl_xfs_to_xattr(
 
 int
 xfs_acl_vget(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        void            *acl,
        size_t          size,
        int             kind)
@@ -241,10 +239,10 @@ xfs_acl_vget(
                        goto out;
                }
                if (kind == _ACL_TYPE_ACCESS) {
-                       vattr_t va;
+                       bhv_vattr_t     va;
 
                        va.va_mask = XFS_AT_MODE;
-                       VOP_GETATTR(vp, &va, 0, sys_cred, error);
+                       error = bhv_vop_getattr(vp, &va, 0, sys_cred);
                        if (error)
                                goto out;
                        xfs_acl_sync_mode(va.va_mode, xfs_acl);
@@ -260,7 +258,7 @@ out:
 
 int
 xfs_acl_vremove(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        int             kind)
 {
        int             error;
@@ -268,9 +266,9 @@ xfs_acl_vremove(
        VN_HOLD(vp);
        error = xfs_acl_allow_set(vp, kind);
        if (!error) {
-               VOP_ATTR_REMOVE(vp, kind == _ACL_TYPE_DEFAULT?
-                               SGI_ACL_DEFAULT: SGI_ACL_FILE,
-                               ATTR_ROOT, sys_cred, error);
+               error = bhv_vop_attr_remove(vp, kind == _ACL_TYPE_DEFAULT?
+                                               SGI_ACL_DEFAULT: SGI_ACL_FILE,
+                                               ATTR_ROOT, sys_cred);
                if (error == ENOATTR)
                        error = 0;      /* 'scool */
        }
@@ -280,7 +278,7 @@ xfs_acl_vremove(
 
 int
 xfs_acl_vset(
-       vnode_t                 *vp,
+       bhv_vnode_t             *vp,
        void                    *acl,
        size_t                  size,
        int                     kind)
@@ -370,10 +368,10 @@ xfs_acl_iaccess(
 
 STATIC int
 xfs_acl_allow_set(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        int             kind)
 {
-       vattr_t         va;
+       bhv_vattr_t     va;
        int             error;
 
        if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
@@ -383,7 +381,7 @@ xfs_acl_allow_set(
        if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
                return EROFS;
        va.va_mask = XFS_AT_UID;
-       VOP_GETATTR(vp, &va, 0, NULL, error);
+       error = bhv_vop_getattr(vp, &va, 0, NULL);
        if (error)
                return error;
        if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
@@ -606,7 +604,7 @@ xfs_acl_get_endian(
  */
 STATIC void
 xfs_acl_get_attr(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_acl_t       *aclp,
        int             kind,
        int             flags,
@@ -616,9 +614,9 @@ xfs_acl_get_attr(
 
        ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1);
        flags |= ATTR_ROOT;
-       VOP_ATTR_GET(vp,
-               kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT,
-               (char *)aclp, &len, flags, sys_cred, *error);
+       *error = bhv_vop_attr_get(vp, kind == _ACL_TYPE_ACCESS ?
+                                       SGI_ACL_FILE : SGI_ACL_DEFAULT,
+                                       (char *)aclp, &len, flags, sys_cred);
        if (*error || (flags & ATTR_KERNOVAL))
                return;
        xfs_acl_get_endian(aclp);
@@ -629,7 +627,7 @@ xfs_acl_get_attr(
  */
 STATIC void
 xfs_acl_set_attr(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_acl_t       *aclp,
        int             kind,
        int             *error)
@@ -654,19 +652,19 @@ xfs_acl_set_attr(
                INT_SET(newace->ae_perm, ARCH_CONVERT, ace->ae_perm);
        }
        INT_SET(newacl->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
-       VOP_ATTR_SET(vp,
-               kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE: SGI_ACL_DEFAULT,
-               (char *)newacl, len, ATTR_ROOT, sys_cred, *error);
+       *error = bhv_vop_attr_set(vp, kind == _ACL_TYPE_ACCESS ?
+                               SGI_ACL_FILE: SGI_ACL_DEFAULT,
+                               (char *)newacl, len, ATTR_ROOT, sys_cred);
        _ACL_FREE(newacl);
 }
 
 int
 xfs_acl_vtoacl(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_acl_t       *access_acl,
        xfs_acl_t       *default_acl)
 {
-       vattr_t         va;
+       bhv_vattr_t     va;
        int             error = 0;
 
        if (access_acl) {
@@ -678,7 +676,7 @@ xfs_acl_vtoacl(
                if (!error) {
                        /* Got the ACL, need the mode... */
                        va.va_mask = XFS_AT_MODE;
-                       VOP_GETATTR(vp, &va, 0, sys_cred, error);
+                       error = bhv_vop_getattr(vp, &va, 0, sys_cred);
                }
 
                if (error)
@@ -701,8 +699,8 @@ xfs_acl_vtoacl(
  */
 int
 xfs_acl_inherit(
-       vnode_t         *vp,
-       vattr_t         *vap,
+       bhv_vnode_t     *vp,
+       bhv_vattr_t     *vap,
        xfs_acl_t       *pdaclp)
 {
        xfs_acl_t       *cacl;
@@ -757,11 +755,11 @@ xfs_acl_inherit(
  */
 STATIC int
 xfs_acl_setmode(
-       vnode_t         *vp,
+       bhv_vnode_t     *vp,
        xfs_acl_t       *acl,
        int             *basicperms)
 {
-       vattr_t         va;
+       bhv_vattr_t     va;
        xfs_acl_entry_t *ap;
        xfs_acl_entry_t *gap = NULL;
        int             i, error, nomask = 1;
@@ -776,7 +774,7 @@ xfs_acl_setmode(
         * mode.  The m:: bits take precedence over the g:: bits.
         */
        va.va_mask = XFS_AT_MODE;
-       VOP_GETATTR(vp, &va, 0, sys_cred, error);
+       error = bhv_vop_getattr(vp, &va, 0, sys_cred);
        if (error)
                return error;
 
@@ -810,8 +808,7 @@ xfs_acl_setmode(
        if (gap && nomask)
                va.va_mode |= gap->ae_perm << 3;
 
-       VOP_SETATTR(vp, &va, 0, sys_cred, error);
-       return error;
+       return bhv_vop_setattr(vp, &va, 0, sys_cred);
 }
 
 /*
index 538d0d65b04c720bf032ceee18a7ed485d517f6f..f853cf1a627058256fd88a43333e821d70c9ef19 100644 (file)
@@ -50,7 +50,7 @@ typedef struct xfs_acl {
 #ifdef CONFIG_XFS_POSIX_ACL
 
 struct vattr;
-struct vnode;
+struct bhv_vnode;
 struct xfs_inode;
 
 extern struct kmem_zone *xfs_acl_zone;
@@ -58,14 +58,14 @@ extern struct kmem_zone *xfs_acl_zone;
                (zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
 #define xfs_acl_zone_destroy(zone)     kmem_zone_destroy(zone)
 
-extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
+extern int xfs_acl_inherit(struct bhv_vnode *, struct bhv_vattr *, xfs_acl_t *);
 extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
-extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *);
-extern int xfs_acl_vhasacl_access(struct vnode *);
-extern int xfs_acl_vhasacl_default(struct vnode *);
-extern int xfs_acl_vset(struct vnode *, void *, size_t, int);
-extern int xfs_acl_vget(struct vnode *, void *, size_t, int);
-extern int xfs_acl_vremove(struct vnode *vp, int);
+extern int xfs_acl_vtoacl(struct bhv_vnode *, xfs_acl_t *, xfs_acl_t *);
+extern int xfs_acl_vhasacl_access(struct bhv_vnode *);
+extern int xfs_acl_vhasacl_default(struct bhv_vnode *);
+extern int xfs_acl_vset(struct bhv_vnode *, void *, size_t, int);
+extern int xfs_acl_vget(struct bhv_vnode *, void *, size_t, int);
+extern int xfs_acl_vremove(struct bhv_vnode *, int);
 
 #define _ACL_TYPE_ACCESS       1
 #define _ACL_TYPE_DEFAULT      2
index 8558226281c45a61d7a0bc056505246e705a372b..eef6763f3a6732084ede458d4a8b38b5e01e3fd4 100644 (file)
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -1862,7 +1860,7 @@ xfs_alloc_fix_freelist(
                (pag->pagf_longest - delta) :
                (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
        if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
-           (args->minleft &&
+           (!(flags & XFS_ALLOC_FLAG_FREEING) &&
             (int)(pag->pagf_freeblks + pag->pagf_flcount -
                   need - args->total) <
             (int)args->minleft)) {
@@ -1898,7 +1896,7 @@ xfs_alloc_fix_freelist(
        longest = (longest > delta) ? (longest - delta) :
                (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
        if (args->minlen + args->alignment + args->minalignslop - 1 > longest ||
-            (args->minleft &&
+            (!(flags & XFS_ALLOC_FLAG_FREEING) &&
                (int)(be32_to_cpu(agf->agf_freeblks) +
                   be32_to_cpu(agf->agf_flcount) - need - args->total) <
             (int)args->minleft)) {
@@ -1951,8 +1949,14 @@ xfs_alloc_fix_freelist(
                 * the restrictions correctly.  Can happen for free calls
                 * on a completely full ag.
                 */
-               if (targs.agbno == NULLAGBLOCK)
+               if (targs.agbno == NULLAGBLOCK) {
+                       if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
+                               xfs_trans_brelse(tp, agflbp);
+                               args->agbp = NULL;
+                               return 0;
+                       }
                        break;
+               }
                /*
                 * Put each allocated block on the list.
                 */
@@ -2360,8 +2364,19 @@ xfs_alloc_vextent(
                        if (args->agno == sagno &&
                            type == XFS_ALLOCTYPE_START_BNO)
                                args->type = XFS_ALLOCTYPE_THIS_AG;
-                       if (++(args->agno) == mp->m_sb.sb_agcount)
-                               args->agno = 0;
+                       /*
+                       * For the first allocation, we can try any AG to get
+                       * space.  However, if we already have allocated a
+                       * block, we don't want to try AGs whose number is below
+                       * sagno. Otherwise, we may end up with out-of-order
+                       * locking of AGF, which might cause deadlock.
+                       */
+                       if (++(args->agno) == mp->m_sb.sb_agcount) {
+                               if (args->firstblock != NULLFSBLOCK)
+                                       args->agno = sagno;
+                               else
+                                       args->agno = 0;
+                       }
                        /*
                         * Reached the starting a.g., must either be done
                         * or switch to non-trylock mode.
@@ -2443,7 +2458,7 @@ xfs_free_extent(
        args.minlen = args.minleft = args.minalignslop = 0;
        down_read(&args.mp->m_peraglock);
        args.pag = &args.mp->m_perag[args.agno];
-       if ((error = xfs_alloc_fix_freelist(&args, 0)))
+       if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING)))
                goto error0;
 #ifdef DEBUG
        ASSERT(args.agbp != NULL);
index 2d1f8928b2677dcb153cc8c9448ce41b3034fd83..650591f999ae4f1dd60eb575930246e7d3592758 100644 (file)
@@ -41,6 +41,7 @@ typedef enum xfs_alloctype
  * Flags for xfs_alloc_fix_freelist.
  */
 #define        XFS_ALLOC_FLAG_TRYLOCK  0x00000001  /* use trylock for buffer locking */
+#define        XFS_ALLOC_FLAG_FREEING  0x00000002  /* indicate caller is freeing extents*/
 
 /*
  * Argument structure for xfs_alloc routines.
@@ -70,6 +71,7 @@ typedef struct xfs_alloc_arg {
        char            wasfromfl;      /* set if allocation is from freelist */
        char            isfl;           /* set if is freelist blocks - !acctg */
        char            userdata;       /* set if this is user data */
+       xfs_fsblock_t   firstblock;     /* io first block allocated */
 } xfs_alloc_arg_t;
 
 /*
index a1d92da86ccd04e33c33e2dbb1752daea04c1430..7446556e8021092cecbba838bf9fa9214cf2ed01 100644 (file)
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
index b6e1e02bbb285bd5bda5c090f4a85d6e6789494e..1a210104327547b77768e6fd6cd58f7618bac090 100644 (file)
@@ -27,7 +27,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
@@ -35,7 +34,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -1910,7 +1908,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
                error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
                                  args->rmtblkcnt,
                                  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
-                                 NULL, 0, map, &nmap, NULL);
+                                 NULL, 0, map, &nmap, NULL, NULL);
                if (error)
                        return(error);
                ASSERT(nmap >= 1);
@@ -1988,7 +1986,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
                                  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
                                                        XFS_BMAPI_WRITE,
                                  args->firstblock, args->total, &map, &nmap,
-                                 args->flist);
+                                 args->flist, NULL);
                if (!error) {
                        error = xfs_bmap_finish(&args->trans, args->flist,
                                                *args->firstblock, &committed);
@@ -2039,7 +2037,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
                error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
                                  args->rmtblkcnt,
                                  XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
-                                 args->firstblock, 0, &map, &nmap, NULL);
+                                 args->firstblock, 0, &map, &nmap,
+                                 NULL, NULL);
                if (error) {
                        return(error);
                }
@@ -2104,7 +2103,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
                                        args->rmtblkcnt,
                                        XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
                                        args->firstblock, 0, &map, &nmap,
-                                       args->flist);
+                                       args->flist, NULL);
                if (error) {
                        return(error);
                }
@@ -2142,7 +2141,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
                XFS_BMAP_INIT(args->flist, args->firstblock);
                error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
                                    XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
-                                   1, args->firstblock, args->flist, &done);
+                                   1, args->firstblock, args->flist,
+                                   NULL, &done);
                if (!error) {
                        error = xfs_bmap_finish(&args->trans, args->flist,
                                                *args->firstblock, &committed);
@@ -2322,56 +2322,56 @@ xfs_attr_trace_enter(int type, char *where,
 
 STATIC int
 posix_acl_access_set(
-       vnode_t *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
 }
 
 STATIC int
 posix_acl_access_remove(
-       struct vnode *vp, char *name, int xflags)
+       bhv_vnode_t *vp, char *name, int xflags)
 {
        return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
 }
 
 STATIC int
 posix_acl_access_get(
-       vnode_t *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
 }
 
 STATIC int
 posix_acl_access_exists(
-       vnode_t *vp)
+       bhv_vnode_t *vp)
 {
        return xfs_acl_vhasacl_access(vp);
 }
 
 STATIC int
 posix_acl_default_set(
-       vnode_t *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
 }
 
 STATIC int
 posix_acl_default_get(
-       vnode_t *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
 }
 
 STATIC int
 posix_acl_default_remove(
-       struct vnode *vp, char *name, int xflags)
+       bhv_vnode_t *vp, char *name, int xflags)
 {
        return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
 }
 
 STATIC int
 posix_acl_default_exists(
-       vnode_t *vp)
+       bhv_vnode_t *vp)
 {
        return xfs_acl_vhasacl_default(vp);
 }
@@ -2404,21 +2404,18 @@ STATIC struct attrnames *attr_system_names[] =
 
 STATIC int
 attr_generic_set(
-       struct vnode *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
-       int     error;
-
-       VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
-       return -error;
+       return -bhv_vop_attr_set(vp, name, data, size, xflags, NULL);
 }
 
 STATIC int
 attr_generic_get(
-       struct vnode *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        int     error, asize = size;
 
-       VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error);
+       error = bhv_vop_attr_get(vp, name, data, &asize, xflags, NULL);
        if (!error)
                return asize;
        return -error;
@@ -2426,12 +2423,9 @@ attr_generic_get(
 
 STATIC int
 attr_generic_remove(
-       struct vnode *vp, char *name, int xflags)
+       bhv_vnode_t *vp, char *name, int xflags)
 {
-       int     error;
-
-       VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
-       return -error;
+       return -bhv_vop_attr_remove(vp, name, xflags, NULL);
 }
 
 STATIC int
@@ -2459,7 +2453,7 @@ attr_generic_listadd(
 
 STATIC int
 attr_system_list(
-       struct vnode            *vp,
+       bhv_vnode_t             *vp,
        void                    *data,
        size_t                  size,
        ssize_t                 *result)
@@ -2481,12 +2475,12 @@ attr_system_list(
 
 int
 attr_generic_list(
-       struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result)
+       bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
 {
        attrlist_cursor_kern_t  cursor = { 0 };
        int                     error;
 
-       VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
+       error = bhv_vop_attr_list(vp, data, size, xflags, &cursor, NULL);
        if (error > 0)
                return -error;
        *result = -error;
@@ -2514,7 +2508,7 @@ attr_lookup_namespace(
  */
 STATIC int
 attr_user_capable(
-       struct vnode    *vp,
+       bhv_vnode_t     *vp,
        cred_t          *cred)
 {
        struct inode    *inode = vn_to_inode(vp);
@@ -2532,7 +2526,7 @@ attr_user_capable(
 
 STATIC int
 attr_trusted_capable(
-       struct vnode    *vp,
+       bhv_vnode_t     *vp,
        cred_t          *cred)
 {
        struct inode    *inode = vn_to_inode(vp);
@@ -2546,7 +2540,7 @@ attr_trusted_capable(
 
 STATIC int
 attr_secure_capable(
-       struct vnode    *vp,
+       bhv_vnode_t     *vp,
        cred_t          *cred)
 {
        return -ENOSECURITY;
@@ -2554,7 +2548,7 @@ attr_secure_capable(
 
 STATIC int
 attr_system_set(
-       struct vnode *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        attrnames_t     *namesp;
        int             error;
@@ -2573,7 +2567,7 @@ attr_system_set(
 
 STATIC int
 attr_system_get(
-       struct vnode *vp, char *name, void *data, size_t size, int xflags)
+       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
 {
        attrnames_t     *namesp;
 
@@ -2585,7 +2579,7 @@ attr_system_get(
 
 STATIC int
 attr_system_remove(
-       struct vnode *vp, char *name, int xflags)
+       bhv_vnode_t *vp, char *name, int xflags)
 {
        attrnames_t     *namesp;
 
index b2c7b9fcded3a4f6eed106027e61d07f3618de0e..981633f6c077cb96128bbe730b3deb7809f16bc4 100644 (file)
  *========================================================================*/
 
 struct cred;
-struct vnode;
+struct bhv_vnode;
 
-typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int);
-typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int);
-typedef int (*attrremove_t)(struct vnode *, char *, int);
-typedef int (*attrexists_t)(struct vnode *);
-typedef int (*attrcapable_t)(struct vnode *, struct cred *);
+typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
+typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
+typedef int (*attrremove_t)(struct bhv_vnode *, char *, int);
+typedef int (*attrexists_t)(struct bhv_vnode *);
+typedef int (*attrcapable_t)(struct bhv_vnode *, struct cred *);
 
 typedef struct attrnames {
        char *          attr_name;
@@ -63,7 +63,7 @@ extern struct attrnames attr_trusted;
 extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
 
 extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
-extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
+extern int attr_generic_list(struct bhv_vnode *, void *, size_t, int, ssize_t *);
 
 #define ATTR_DONTFOLLOW        0x0001  /* -- unused, from IRIX -- */
 #define ATTR_ROOT      0x0002  /* use attrs in root (trusted) namespace */
index 9462be86aa1477c495b971463106900117f2ba39..9455051f01208e61ae7d32cf9ab2cbad858d5fe7 100644 (file)
@@ -24,7 +24,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
@@ -34,7 +33,6 @@
 #include "xfs_ialloc_btree.h"
 #include "xfs_alloc.h"
 #include "xfs_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -2990,7 +2988,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
                nmap = 1;
                error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
                                        XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
-                                       NULL, 0, &map, &nmap, NULL);
+                                       NULL, 0, &map, &nmap, NULL, NULL);
                if (error) {
                        return(error);
                }
index 26939d364bc47bbcff7d52bce28d06ac988939d1..3a61375390645f2bf6f2d5d54c5b4f988af97f0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_da_btree.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_mount.h"
 #include "xfs_ialloc.h"
 #include "xfs_itable.h"
+#include "xfs_dir2_data.h"
+#include "xfs_dir2_leaf.h"
+#include "xfs_dir2_block.h"
 #include "xfs_inode_item.h"
 #include "xfs_extfree_item.h"
 #include "xfs_alloc.h"
 #include "xfs_bmap.h"
 #include "xfs_rtalloc.h"
 #include "xfs_error.h"
-#include "xfs_dir_leaf.h"
 #include "xfs_attr_leaf.h"
 #include "xfs_rw.h"
 #include "xfs_quota.h"
@@ -101,6 +101,7 @@ xfs_bmap_add_extent(
        xfs_fsblock_t           *first, /* pointer to firstblock variable */
        xfs_bmap_free_t         *flist, /* list of extents to be freed */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork, /* data or attr fork */
        int                     rsvd);  /* OK to allocate reserved blocks */
 
@@ -118,6 +119,7 @@ xfs_bmap_add_extent_delay_real(
        xfs_fsblock_t           *first, /* pointer to firstblock variable */
        xfs_bmap_free_t         *flist, /* list of extents to be freed */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     rsvd);  /* OK to allocate reserved blocks */
 
 /*
@@ -131,6 +133,7 @@ xfs_bmap_add_extent_hole_delay(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
        int                     *logflagsp,/* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     rsvd);  /* OK to allocate reserved blocks */
 
 /*
@@ -144,6 +147,7 @@ xfs_bmap_add_extent_hole_real(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork); /* data or attr fork */
 
 /*
@@ -156,7 +160,8 @@ xfs_bmap_add_extent_unwritten_real(
        xfs_extnum_t            idx,    /* extent number to update/insert */
        xfs_btree_cur_t         **curp, /* if *curp is null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
-       int                     *logflagsp); /* inode logging flags */
+       int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta); /* Change made to incore extents */
 
 /*
  * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -203,6 +208,7 @@ xfs_bmap_del_extent(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
        int                     *logflagsp,/* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork, /* data or attr fork */
        int                     rsvd);   /* OK to allocate reserved blocks */
 
@@ -510,7 +516,7 @@ xfs_bmap_add_attrfork_local(
                dargs.total = mp->m_dirblkfsbs;
                dargs.whichfork = XFS_DATA_FORK;
                dargs.trans = tp;
-               error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs);
+               error = xfs_dir2_sf_to_block(&dargs);
        } else
                error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
                        XFS_DATA_FORK);
@@ -530,6 +536,7 @@ xfs_bmap_add_extent(
        xfs_fsblock_t           *first, /* pointer to firstblock variable */
        xfs_bmap_free_t         *flist, /* list of extents to be freed */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork, /* data or attr fork */
        int                     rsvd)   /* OK to use reserved data blocks */
 {
@@ -567,6 +574,15 @@ xfs_bmap_add_extent(
                        logflags = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
                } else
                        logflags = 0;
+               /* DELTA: single new extent */
+               if (delta) {
+                       if (delta->xed_startoff > new->br_startoff)
+                               delta->xed_startoff = new->br_startoff;
+                       if (delta->xed_blockcount <
+                                       new->br_startoff + new->br_blockcount)
+                               delta->xed_blockcount = new->br_startoff +
+                                               new->br_blockcount;
+               }
        }
        /*
         * Any kind of new delayed allocation goes here.
@@ -576,7 +592,7 @@ xfs_bmap_add_extent(
                        ASSERT((cur->bc_private.b.flags &
                                XFS_BTCUR_BPRV_WASDEL) == 0);
                if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, cur, new,
-                               &logflags, rsvd)))
+                               &logflags, delta, rsvd)))
                        goto done;
        }
        /*
@@ -587,7 +603,7 @@ xfs_bmap_add_extent(
                        ASSERT((cur->bc_private.b.flags &
                                XFS_BTCUR_BPRV_WASDEL) == 0);
                if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
-                               &logflags, whichfork)))
+                               &logflags, delta, whichfork)))
                        goto done;
        } else {
                xfs_bmbt_irec_t prev;   /* old extent at offset idx */
@@ -612,17 +628,17 @@ xfs_bmap_add_extent(
                                                XFS_BTCUR_BPRV_WASDEL);
                                if ((error = xfs_bmap_add_extent_delay_real(ip,
                                        idx, &cur, new, &da_new, first, flist,
-                                       &logflags, rsvd)))
+                                       &logflags, delta, rsvd)))
                                        goto done;
                        } else if (new->br_state == XFS_EXT_NORM) {
                                ASSERT(new->br_state == XFS_EXT_NORM);
                                if ((error = xfs_bmap_add_extent_unwritten_real(
-                                       ip, idx, &cur, new, &logflags)))
+                                       ip, idx, &cur, new, &logflags, delta)))
                                        goto done;
                        } else {
                                ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
                                if ((error = xfs_bmap_add_extent_unwritten_real(
-                                       ip, idx, &cur, new, &logflags)))
+                                       ip, idx, &cur, new, &logflags, delta)))
                                        goto done;
                        }
                        ASSERT(*curp == cur || *curp == NULL);
@@ -635,7 +651,7 @@ xfs_bmap_add_extent(
                                ASSERT((cur->bc_private.b.flags &
                                        XFS_BTCUR_BPRV_WASDEL) == 0);
                        if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
-                                       new, &logflags, whichfork)))
+                                       new, &logflags, delta, whichfork)))
                                goto done;
                }
        }
@@ -700,6 +716,7 @@ xfs_bmap_add_extent_delay_real(
        xfs_fsblock_t           *first, /* pointer to firstblock variable */
        xfs_bmap_free_t         *flist, /* list of extents to be freed */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     rsvd)   /* OK to use reserved data block allocation */
 {
        xfs_btree_cur_t         *cur;   /* btree cursor */
@@ -716,8 +733,8 @@ xfs_bmap_add_extent_delay_real(
                                        /* left is 0, right is 1, prev is 2 */
        int                     rval=0; /* return value (logging flags) */
        int                     state = 0;/* state bits, accessed thru macros */
-       xfs_filblks_t           temp;   /* value for dnew calculations */
-       xfs_filblks_t           temp2;  /* value for dnew calculations */
+       xfs_filblks_t           temp=0; /* value for dnew calculations */
+       xfs_filblks_t           temp2=0;/* value for dnew calculations */
        int                     tmp_rval;       /* partial logging flags */
        enum {                          /* bit number definitions for state */
                LEFT_CONTIG,    RIGHT_CONTIG,
@@ -839,6 +856,11 @@ xfs_bmap_add_extent_delay_real(
                                goto done;
                }
                *dnew = 0;
+               /* DELTA: Three in-core extents are replaced by one. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -872,6 +894,10 @@ xfs_bmap_add_extent_delay_real(
                                goto done;
                }
                *dnew = 0;
+               /* DELTA: Two in-core extents are replaced by one. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -906,6 +932,10 @@ xfs_bmap_add_extent_delay_real(
                                goto done;
                }
                *dnew = 0;
+               /* DELTA: Two in-core extents are replaced by one. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -936,6 +966,9 @@ xfs_bmap_add_extent_delay_real(
                        ASSERT(i == 1);
                }
                *dnew = 0;
+               /* DELTA: The in-core extent described by new changed type. */
+               temp = new->br_startoff;
+               temp2 = new->br_blockcount;
                break;
 
        case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -978,6 +1011,10 @@ xfs_bmap_add_extent_delay_real(
                xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx,
                        XFS_DATA_FORK);
                *dnew = temp;
+               /* DELTA: The boundary between two in-core extents moved. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount;
                break;
 
        case MASK(LEFT_FILLING):
@@ -1025,6 +1062,9 @@ xfs_bmap_add_extent_delay_real(
                xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1,
                        XFS_DATA_FORK);
                *dnew = temp;
+               /* DELTA: One in-core extent is split in two. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1067,6 +1107,10 @@ xfs_bmap_add_extent_delay_real(
                xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx,
                        XFS_DATA_FORK);
                *dnew = temp;
+               /* DELTA: The boundary between two in-core extents moved. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK(RIGHT_FILLING):
@@ -1112,6 +1156,9 @@ xfs_bmap_add_extent_delay_real(
                xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp));
                xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK);
                *dnew = temp;
+               /* DELTA: One in-core extent is split in two. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case 0:
@@ -1194,6 +1241,9 @@ xfs_bmap_add_extent_delay_real(
                xfs_bmap_trace_post_update(fname, "0", ip, idx + 2,
                        XFS_DATA_FORK);
                *dnew = temp + temp2;
+               /* DELTA: One in-core extent is split in three. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1209,6 +1259,13 @@ xfs_bmap_add_extent_delay_real(
                ASSERT(0);
        }
        *curp = cur;
+       if (delta) {
+               temp2 += temp;
+               if (delta->xed_startoff > temp)
+                       delta->xed_startoff = temp;
+               if (delta->xed_blockcount < temp2)
+                       delta->xed_blockcount = temp2;
+       }
 done:
        *logflagsp = rval;
        return error;
@@ -1235,7 +1292,8 @@ xfs_bmap_add_extent_unwritten_real(
        xfs_extnum_t            idx,    /* extent number to update/insert */
        xfs_btree_cur_t         **curp, /* if *curp is null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
-       int                     *logflagsp) /* inode logging flags */
+       int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta) /* Change made to incore extents */
 {
        xfs_btree_cur_t         *cur;   /* btree cursor */
        xfs_bmbt_rec_t          *ep;    /* extent entry for idx */
@@ -1252,6 +1310,8 @@ xfs_bmap_add_extent_unwritten_real(
                                        /* left is 0, right is 1, prev is 2 */
        int                     rval=0; /* return value (logging flags) */
        int                     state = 0;/* state bits, accessed thru macros */
+       xfs_filblks_t           temp=0;
+       xfs_filblks_t           temp2=0;
        enum {                          /* bit number definitions for state */
                LEFT_CONTIG,    RIGHT_CONTIG,
                LEFT_FILLING,   RIGHT_FILLING,
@@ -1380,6 +1440,11 @@ xfs_bmap_add_extent_unwritten_real(
                                RIGHT.br_blockcount, LEFT.br_state)))
                                goto done;
                }
+               /* DELTA: Three in-core extents are replaced by one. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, RIGHT_FILLING, LEFT_CONTIG):
@@ -1419,6 +1484,10 @@ xfs_bmap_add_extent_unwritten_real(
                                LEFT.br_state)))
                                goto done;
                }
+               /* DELTA: Two in-core extents are replaced by one. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, RIGHT_FILLING, RIGHT_CONTIG):
@@ -1459,6 +1528,10 @@ xfs_bmap_add_extent_unwritten_real(
                                newext)))
                                goto done;
                }
+               /* DELTA: Two in-core extents are replaced by one. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK2(LEFT_FILLING, RIGHT_FILLING):
@@ -1487,6 +1560,9 @@ xfs_bmap_add_extent_unwritten_real(
                                newext)))
                                goto done;
                }
+               /* DELTA: The in-core extent described by new changed type. */
+               temp = new->br_startoff;
+               temp2 = new->br_blockcount;
                break;
 
        case MASK2(LEFT_FILLING, LEFT_CONTIG):
@@ -1534,6 +1610,10 @@ xfs_bmap_add_extent_unwritten_real(
                                LEFT.br_state))
                                goto done;
                }
+               /* DELTA: The boundary between two in-core extents moved. */
+               temp = LEFT.br_startoff;
+               temp2 = LEFT.br_blockcount +
+                       PREV.br_blockcount;
                break;
 
        case MASK(LEFT_FILLING):
@@ -1574,6 +1654,9 @@ xfs_bmap_add_extent_unwritten_real(
                                goto done;
                        ASSERT(i == 1);
                }
+               /* DELTA: One in-core extent is split in two. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case MASK2(RIGHT_FILLING, RIGHT_CONTIG):
@@ -1617,6 +1700,10 @@ xfs_bmap_add_extent_unwritten_real(
                                newext)))
                                goto done;
                }
+               /* DELTA: The boundary between two in-core extents moved. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount +
+                       RIGHT.br_blockcount;
                break;
 
        case MASK(RIGHT_FILLING):
@@ -1657,6 +1744,9 @@ xfs_bmap_add_extent_unwritten_real(
                                goto done;
                        ASSERT(i == 1);
                }
+               /* DELTA: One in-core extent is split in two. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case 0:
@@ -1710,6 +1800,9 @@ xfs_bmap_add_extent_unwritten_real(
                                goto done;
                        ASSERT(i == 1);
                }
+               /* DELTA: One in-core extent is split in three. */
+               temp = PREV.br_startoff;
+               temp2 = PREV.br_blockcount;
                break;
 
        case MASK3(LEFT_FILLING, LEFT_CONTIG, RIGHT_CONTIG):
@@ -1725,6 +1818,13 @@ xfs_bmap_add_extent_unwritten_real(
                ASSERT(0);
        }
        *curp = cur;
+       if (delta) {
+               temp2 += temp;
+               if (delta->xed_startoff > temp)
+                       delta->xed_startoff = temp;
+               if (delta->xed_blockcount < temp2)
+                       delta->xed_blockcount = temp2;
+       }
 done:
        *logflagsp = rval;
        return error;
@@ -1753,6 +1853,7 @@ xfs_bmap_add_extent_hole_delay(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     rsvd)           /* OK to allocate reserved blocks */
 {
        xfs_bmbt_rec_t          *ep;    /* extent record for idx */
@@ -1765,7 +1866,8 @@ xfs_bmap_add_extent_hole_delay(
        xfs_filblks_t           oldlen=0;       /* old indirect size */
        xfs_bmbt_irec_t         right;  /* right neighbor extent entry */
        int                     state;  /* state bits, accessed thru macros */
-       xfs_filblks_t           temp;   /* temp for indirect calculations */
+       xfs_filblks_t           temp=0; /* temp for indirect calculations */
+       xfs_filblks_t           temp2=0;
        enum {                          /* bit number definitions for state */
                LEFT_CONTIG,    RIGHT_CONTIG,
                LEFT_DELAY,     RIGHT_DELAY,
@@ -1844,6 +1946,9 @@ xfs_bmap_add_extent_hole_delay(
                        XFS_DATA_FORK);
                xfs_iext_remove(ifp, idx, 1);
                ip->i_df.if_lastex = idx - 1;
+               /* DELTA: Two in-core extents were replaced by one. */
+               temp2 = temp;
+               temp = left.br_startoff;
                break;
 
        case MASK(LEFT_CONTIG):
@@ -1864,6 +1969,9 @@ xfs_bmap_add_extent_hole_delay(
                xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1,
                        XFS_DATA_FORK);
                ip->i_df.if_lastex = idx - 1;
+               /* DELTA: One in-core extent grew into a hole. */
+               temp2 = temp;
+               temp = left.br_startoff;
                break;
 
        case MASK(RIGHT_CONTIG):
@@ -1881,6 +1989,9 @@ xfs_bmap_add_extent_hole_delay(
                        NULLSTARTBLOCK((int)newlen), temp, right.br_state);
                xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK);
                ip->i_df.if_lastex = idx;
+               /* DELTA: One in-core extent grew into a hole. */
+               temp2 = temp;
+               temp = new->br_startoff;
                break;
 
        case 0:
@@ -1894,6 +2005,9 @@ xfs_bmap_add_extent_hole_delay(
                        XFS_DATA_FORK);
                xfs_iext_insert(ifp, idx, 1, new);
                ip->i_df.if_lastex = idx;
+               /* DELTA: A new in-core extent was added in a hole. */
+               temp2 = new->br_blockcount;
+               temp = new->br_startoff;
                break;
        }
        if (oldlen != newlen) {
@@ -1904,6 +2018,13 @@ xfs_bmap_add_extent_hole_delay(
                 * Nothing to do for disk quota accounting here.
                 */
        }
+       if (delta) {
+               temp2 += temp;
+               if (delta->xed_startoff > temp)
+                       delta->xed_startoff = temp;
+               if (delta->xed_blockcount < temp2)
+                       delta->xed_blockcount = temp2;
+       }
        *logflagsp = 0;
        return 0;
 #undef MASK
@@ -1925,6 +2046,7 @@ xfs_bmap_add_extent_hole_real(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *new,   /* new data to add to file extents */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork) /* data or attr fork */
 {
        xfs_bmbt_rec_t          *ep;    /* pointer to extent entry ins. point */
@@ -1936,7 +2058,10 @@ xfs_bmap_add_extent_hole_real(
        xfs_ifork_t             *ifp;   /* inode fork pointer */
        xfs_bmbt_irec_t         left;   /* left neighbor extent entry */
        xfs_bmbt_irec_t         right;  /* right neighbor extent entry */
+       int                     rval=0; /* return value (logging flags) */
        int                     state;  /* state bits, accessed thru macros */
+       xfs_filblks_t           temp=0;
+       xfs_filblks_t           temp2=0;
        enum {                          /* bit number definitions for state */
                LEFT_CONTIG,    RIGHT_CONTIG,
                LEFT_DELAY,     RIGHT_DELAY,
@@ -1993,6 +2118,7 @@ xfs_bmap_add_extent_hole_real(
                 left.br_blockcount + new->br_blockcount +
                     right.br_blockcount <= MAXEXTLEN));
 
+       error = 0;
        /*
         * Select which case we're in here, and implement it.
         */
@@ -2018,25 +2144,35 @@ xfs_bmap_add_extent_hole_real(
                XFS_IFORK_NEXT_SET(ip, whichfork,
                        XFS_IFORK_NEXTENTS(ip, whichfork) - 1);
                if (cur == NULL) {
-                       *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
-                       return 0;
+                       rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
+               } else {
+                       rval = XFS_ILOG_CORE;
+                       if ((error = xfs_bmbt_lookup_eq(cur,
+                                       right.br_startoff,
+                                       right.br_startblock,
+                                       right.br_blockcount, &i)))
+                               goto done;
+                       ASSERT(i == 1);
+                       if ((error = xfs_bmbt_delete(cur, &i)))
+                               goto done;
+                       ASSERT(i == 1);
+                       if ((error = xfs_bmbt_decrement(cur, 0, &i)))
+                               goto done;
+                       ASSERT(i == 1);
+                       if ((error = xfs_bmbt_update(cur, left.br_startoff,
+                                       left.br_startblock,
+                                       left.br_blockcount +
+                                               new->br_blockcount +
+                                               right.br_blockcount,
+                                       left.br_state)))
+                               goto done;
                }
-               *logflagsp = XFS_ILOG_CORE;
-               if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
-                               right.br_startblock, right.br_blockcount, &i)))
-                       return error;
-               ASSERT(i == 1);
-               if ((error = xfs_bmbt_delete(cur, &i)))
-                       return error;
-               ASSERT(i == 1);
-               if ((error = xfs_bmbt_decrement(cur, 0, &i)))
-                       return error;
-               ASSERT(i == 1);
-               error = xfs_bmbt_update(cur, left.br_startoff,
-                               left.br_startblock,
-                               left.br_blockcount + new->br_blockcount +
-                               right.br_blockcount, left.br_state);
-               return error;
+               /* DELTA: Two in-core extents were replaced by one. */
+               temp = left.br_startoff;
+               temp2 = left.br_blockcount +
+                       new->br_blockcount +
+                       right.br_blockcount;
+               break;
 
        case MASK(LEFT_CONTIG):
                /*
@@ -2050,19 +2186,27 @@ xfs_bmap_add_extent_hole_real(
                xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork);
                ifp->if_lastex = idx - 1;
                if (cur == NULL) {
-                       *logflagsp = XFS_ILOG_FEXT(whichfork);
-                       return 0;
+                       rval = XFS_ILOG_FEXT(whichfork);
+               } else {
+                       rval = 0;
+                       if ((error = xfs_bmbt_lookup_eq(cur,
+                                       left.br_startoff,
+                                       left.br_startblock,
+                                       left.br_blockcount, &i)))
+                               goto done;
+                       ASSERT(i == 1);
+                       if ((error = xfs_bmbt_update(cur, left.br_startoff,
+                                       left.br_startblock,
+                                       left.br_blockcount +
+                                               new->br_blockcount,
+                                       left.br_state)))
+                               goto done;
                }
-               *logflagsp = 0;
-               if ((error = xfs_bmbt_lookup_eq(cur, left.br_startoff,
-                               left.br_startblock, left.br_blockcount, &i)))
-                       return error;
-               ASSERT(i == 1);
-               error = xfs_bmbt_update(cur, left.br_startoff,
-                               left.br_startblock,
-                               left.br_blockcount + new->br_blockcount,
-                               left.br_state);
-               return error;
+               /* DELTA: One in-core extent grew. */
+               temp = left.br_startoff;
+               temp2 = left.br_blockcount +
+                       new->br_blockcount;
+               break;
 
        case MASK(RIGHT_CONTIG):
                /*
@@ -2077,19 +2221,27 @@ xfs_bmap_add_extent_hole_real(
                xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork);
                ifp->if_lastex = idx;
                if (cur == NULL) {
-                       *logflagsp = XFS_ILOG_FEXT(whichfork);
-                       return 0;
+                       rval = XFS_ILOG_FEXT(whichfork);
+               } else {
+                       rval = 0;
+                       if ((error = xfs_bmbt_lookup_eq(cur,
+                                       right.br_startoff,
+                                       right.br_startblock,
+                                       right.br_blockcount, &i)))
+                               goto done;
+                       ASSERT(i == 1);
+                       if ((error = xfs_bmbt_update(cur, new->br_startoff,
+                                       new->br_startblock,
+                                       new->br_blockcount +
+                                               right.br_blockcount,
+                                       right.br_state)))
+                               goto done;
                }
-               *logflagsp = 0;
-               if ((error = xfs_bmbt_lookup_eq(cur, right.br_startoff,
-                               right.br_startblock, right.br_blockcount, &i)))
-                       return error;
-               ASSERT(i == 1);
-               error = xfs_bmbt_update(cur, new->br_startoff,
-                               new->br_startblock,
-                               new->br_blockcount + right.br_blockcount,
-                               right.br_state);
-               return error;
+               /* DELTA: One in-core extent grew. */
+               temp = new->br_startoff;
+               temp2 = new->br_blockcount +
+                       right.br_blockcount;
+               break;
 
        case 0:
                /*
@@ -2104,29 +2256,41 @@ xfs_bmap_add_extent_hole_real(
                XFS_IFORK_NEXT_SET(ip, whichfork,
                        XFS_IFORK_NEXTENTS(ip, whichfork) + 1);
                if (cur == NULL) {
-                       *logflagsp = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
-                       return 0;
+                       rval = XFS_ILOG_CORE | XFS_ILOG_FEXT(whichfork);
+               } else {
+                       rval = XFS_ILOG_CORE;
+                       if ((error = xfs_bmbt_lookup_eq(cur,
+                                       new->br_startoff,
+                                       new->br_startblock,
+                                       new->br_blockcount, &i)))
+                               goto done;
+                       ASSERT(i == 0);
+                       cur->bc_rec.b.br_state = new->br_state;
+                       if ((error = xfs_bmbt_insert(cur, &i)))
+                               goto done;
+                       ASSERT(i == 1);
                }
-               *logflagsp = XFS_ILOG_CORE;
-               if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
-                               new->br_startblock, new->br_blockcount, &i)))
-                       return error;
-               ASSERT(i == 0);
-               cur->bc_rec.b.br_state = new->br_state;
-               if ((error = xfs_bmbt_insert(cur, &i)))
-                       return error;
-               ASSERT(i == 1);
-               return 0;
+               /* DELTA: A new extent was added in a hole. */
+               temp = new->br_startoff;
+               temp2 = new->br_blockcount;
+               break;
+       }
+       if (delta) {
+               temp2 += temp;
+               if (delta->xed_startoff > temp)
+                       delta->xed_startoff = temp;
+               if (delta->xed_blockcount < temp2)
+                       delta->xed_blockcount = temp2;
        }
+done:
+       *logflagsp = rval;
+       return error;
 #undef MASK
 #undef MASK2
 #undef STATE_SET
 #undef STATE_TEST
 #undef STATE_SET_TEST
 #undef SWITCH_STATE
-       /* NOTREACHED */
-       ASSERT(0);
-       return 0; /* keep gcc quite */
 }
 
 /*
@@ -2598,6 +2762,7 @@ xfs_bmap_btalloc(
        args.mp = mp;
        args.fsbno = ap->rval;
        args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
+       args.firstblock = ap->firstblock;
        blen = 0;
        if (nullfb) {
                args.type = XFS_ALLOCTYPE_START_BNO;
@@ -2657,7 +2822,7 @@ xfs_bmap_btalloc(
                else
                        args.minlen = ap->alen;
        } else if (ap->low) {
-               args.type = XFS_ALLOCTYPE_FIRST_AG;
+               args.type = XFS_ALLOCTYPE_START_BNO;
                args.total = args.minlen = ap->minlen;
        } else {
                args.type = XFS_ALLOCTYPE_NEAR_BNO;
@@ -2669,7 +2834,7 @@ xfs_bmap_btalloc(
                args.prod = ap->ip->i_d.di_extsize;
                if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod)))
                        args.mod = (xfs_extlen_t)(args.prod - args.mod);
-       } else if (unlikely(mp->m_sb.sb_blocksize >= NBPP)) {
+       } else if (mp->m_sb.sb_blocksize >= NBPP) {
                args.prod = 1;
                args.mod = 0;
        } else {
@@ -2885,6 +3050,7 @@ xfs_bmap_del_extent(
        xfs_btree_cur_t         *cur,   /* if null, not a btree */
        xfs_bmbt_irec_t         *del,   /* data to remove from extents */
        int                     *logflagsp, /* inode logging flags */
+       xfs_extdelta_t          *delta, /* Change made to incore extents */
        int                     whichfork, /* data or attr fork */
        int                     rsvd)   /* OK to allocate reserved blocks */
 {
@@ -3193,6 +3359,14 @@ xfs_bmap_del_extent(
        if (da_old > da_new)
                xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int)(da_old - da_new),
                        rsvd);
+       if (delta) {
+               /* DELTA: report the original extent. */
+               if (delta->xed_startoff > got.br_startoff)
+                       delta->xed_startoff = got.br_startoff;
+               if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
+                       delta->xed_blockcount = got.br_startoff +
+                                                       got.br_blockcount;
+       }
 done:
        *logflagsp = flags;
        return error;
@@ -3279,6 +3453,7 @@ xfs_bmap_extents_to_btree(
        XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_BTREE);
        args.tp = tp;
        args.mp = mp;
+       args.firstblock = *firstblock;
        if (*firstblock == NULLFSBLOCK) {
                args.type = XFS_ALLOCTYPE_START_BNO;
                args.fsbno = XFS_INO_TO_FSB(mp, ip->i_ino);
@@ -3414,6 +3589,7 @@ xfs_bmap_local_to_extents(
 
                args.tp = tp;
                args.mp = ip->i_mount;
+               args.firstblock = *firstblock;
                ASSERT((ifp->if_flags &
                        (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
                /*
@@ -3753,7 +3929,7 @@ xfs_bunmap_trace(
        if (ip->i_rwtrace == NULL)
                return;
        ktrace_enter(ip->i_rwtrace,
-               (void *)(__psint_t)XFS_BUNMAPI,
+               (void *)(__psint_t)XFS_BUNMAP,
                (void *)ip,
                (void *)(__psint_t)((ip->i_d.di_size >> 32) & 0xffffffff),
                (void *)(__psint_t)(ip->i_d.di_size & 0xffffffff),
@@ -4087,8 +4263,8 @@ xfs_bmap_finish(
                        if (!XFS_FORCED_SHUTDOWN(mp))
                                xfs_force_shutdown(mp,
                                                   (error == EFSCORRUPTED) ?
-                                                  XFS_CORRUPT_INCORE :
-                                                  XFS_METADATA_IO_ERROR);
+                                                  SHUTDOWN_CORRUPT_INCORE :
+                                                  SHUTDOWN_META_IO_ERROR);
                        return error;
                }
                xfs_trans_log_efd_extent(ntp, efd, free->xbfi_startblock,
@@ -4538,7 +4714,8 @@ xfs_bmapi(
        xfs_extlen_t    total,          /* total blocks needed */
        xfs_bmbt_irec_t *mval,          /* output: map values */
        int             *nmap,          /* i/o: mval size/count */
-       xfs_bmap_free_t *flist)         /* i/o: list extents to free */
+       xfs_bmap_free_t *flist,         /* i/o: list extents to free */
+       xfs_extdelta_t  *delta)         /* o: change made to incore extents */
 {
        xfs_fsblock_t   abno;           /* allocated block number */
        xfs_extlen_t    alen;           /* allocated extent length */
@@ -4650,6 +4827,10 @@ xfs_bmapi(
        end = bno + len;
        obno = bno;
        bma.ip = NULL;
+       if (delta) {
+               delta->xed_startoff = NULLFILEOFF;
+               delta->xed_blockcount = 0;
+       }
        while (bno < end && n < *nmap) {
                /*
                 * Reading past eof, act as though there's a hole
@@ -4886,8 +5067,8 @@ xfs_bmapi(
                                        got.br_state = XFS_EXT_UNWRITTEN;
                        }
                        error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
-                               firstblock, flist, &tmp_logflags, whichfork,
-                               (flags & XFS_BMAPI_RSVBLOCKS));
+                               firstblock, flist, &tmp_log