[XFS] move inode allocation out xfs_iread
authorChristoph Hellwig <hch@lst.de>
Fri, 28 Nov 2008 03:23:42 +0000 (14:23 +1100)
committerNiv Sardi <xaiki@sgi.com>
Mon, 1 Dec 2008 00:38:17 +0000 (11:38 +1100)
Allocate the inode in xfs_iget_cache_miss and pass it into xfs_iread.  This
simplifies the error handling and allows xfs_iread to be shared with userspace
which already uses these semantics.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
fs/xfs/xfs_iget.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h

index d60522a..27ec241 100644 (file)
 #include "xfs_utils.h"
 #include "xfs_trans_priv.h"
 #include "xfs_inode_item.h"
+#include "xfs_bmap.h"
+#include "xfs_btree_trace.h"
+#include "xfs_dir2_trace.h"
+
+
+/*
+ * Allocate and initialise an xfs_inode.
+ */
+STATIC struct xfs_inode *
+xfs_inode_alloc(
+       struct xfs_mount        *mp,
+       xfs_ino_t               ino)
+{
+       struct xfs_inode        *ip;
+
+       /*
+        * if this didn't occur in transactions, we could use
+        * KM_MAYFAIL and return NULL here on ENOMEM. Set the
+        * code up to do this anyway.
+        */
+       ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
+       if (!ip)
+               return NULL;
+
+       ASSERT(atomic_read(&ip->i_iocount) == 0);
+       ASSERT(atomic_read(&ip->i_pincount) == 0);
+       ASSERT(!spin_is_locked(&ip->i_flags_lock));
+       ASSERT(completion_done(&ip->i_flush));
+
+       /*
+        * initialise the VFS inode here to get failures
+        * out of the way early.
+        */
+       if (!inode_init_always(mp->m_super, VFS_I(ip))) {
+               kmem_zone_free(xfs_inode_zone, ip);
+               return NULL;
+       }
+
+       /* initialise the xfs inode */
+       ip->i_ino = ino;
+       ip->i_mount = mp;
+       memset(&ip->i_imap, 0, sizeof(struct xfs_imap));
+       ip->i_afp = NULL;
+       memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
+       ip->i_flags = 0;
+       ip->i_update_core = 0;
+       ip->i_update_size = 0;
+       ip->i_delayed_blks = 0;
+       memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
+       ip->i_size = 0;
+       ip->i_new_size = 0;
+
+       /*
+        * Initialize inode's trace buffers.
+        */
+#ifdef XFS_INODE_TRACE
+       ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
+#endif
+#ifdef XFS_BMAP_TRACE
+       ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
+#endif
+#ifdef XFS_BTREE_TRACE
+       ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
+#endif
+#ifdef XFS_RW_TRACE
+       ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
+#endif
+#ifdef XFS_ILOCK_TRACE
+       ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
+#endif
+#ifdef XFS_DIR2_TRACE
+       ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
+#endif
+
+       return ip;
+}
 
 /*
  * Check the validity of the inode we just found it the cache
@@ -155,13 +231,13 @@ xfs_iget_cache_miss(
        unsigned long           first_index, mask;
        xfs_agino_t             agino = XFS_INO_TO_AGINO(mp, ino);
 
-       /*
-        * Read the disk inode attributes into a new inode structure and get
-        * a new vnode for it. This should also initialize i_ino and i_mount.
-        */
-       error = xfs_iread(mp, tp, ino, &ip, bno, flags);
+       ip = xfs_inode_alloc(mp, ino);
+       if (!ip)
+               return ENOMEM;
+
+       error = xfs_iread(mp, tp, ip, bno, flags);
        if (error)
-               return error;
+               goto out_destroy;
 
        xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
 
index 4290760..872191b 100644 (file)
@@ -758,119 +758,36 @@ xfs_dic2xflags(
 }
 
 /*
- * Allocate and initialise an xfs_inode.
- */
-STATIC struct xfs_inode *
-xfs_inode_alloc(
-       struct xfs_mount        *mp,
-       xfs_ino_t               ino)
-{
-       struct xfs_inode        *ip;
-
-       /*
-        * if this didn't occur in transactions, we could use
-        * KM_MAYFAIL and return NULL here on ENOMEM. Set the
-        * code up to do this anyway.
-        */
-       ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
-       if (!ip)
-               return NULL;
-
-       ASSERT(atomic_read(&ip->i_iocount) == 0);
-       ASSERT(atomic_read(&ip->i_pincount) == 0);
-       ASSERT(!spin_is_locked(&ip->i_flags_lock));
-       ASSERT(completion_done(&ip->i_flush));
-
-       /*
-        * initialise the VFS inode here to get failures
-        * out of the way early.
-        */
-       if (!inode_init_always(mp->m_super, VFS_I(ip))) {
-               kmem_zone_free(xfs_inode_zone, ip);
-               return NULL;
-       }
-
-       /* initialise the xfs inode */
-       ip->i_ino = ino;
-       ip->i_mount = mp;
-       memset(&ip->i_imap, 0, sizeof(struct xfs_imap));
-       ip->i_afp = NULL;
-       memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
-       ip->i_flags = 0;
-       ip->i_update_core = 0;
-       ip->i_update_size = 0;
-       ip->i_delayed_blks = 0;
-       memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
-       ip->i_size = 0;
-       ip->i_new_size = 0;
-
-       /*
-        * Initialize inode's trace buffers.
-        */
-#ifdef XFS_INODE_TRACE
-       ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
-#endif
-#ifdef XFS_BMAP_TRACE
-       ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
-#endif
-#ifdef XFS_BTREE_TRACE
-       ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
-#endif
-#ifdef XFS_RW_TRACE
-       ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
-#endif
-#ifdef XFS_ILOCK_TRACE
-       ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
-#endif
-#ifdef XFS_DIR2_TRACE
-       ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
-#endif
-
-       return ip;
-}
-
-/*
- * Given a mount structure and an inode number, return a pointer
- * to a newly allocated in-core inode corresponding to the given
- * inode number.
- *
- * Initialize the inode's attributes and extent pointers if it
- * already has them (it will not if the inode has no links).
+ * Read the disk inode attributes into the in-core inode structure.
  */
 int
 xfs_iread(
        xfs_mount_t     *mp,
        xfs_trans_t     *tp,
-       xfs_ino_t       ino,
-       xfs_inode_t     **ipp,
+       xfs_inode_t     *ip,
        xfs_daddr_t     bno,
-       uint            imap_flags)
+       uint            iget_flags)
 {
        xfs_buf_t       *bp;
        xfs_dinode_t    *dip;
-       xfs_inode_t     *ip;
        int             error;
 
-       ip = xfs_inode_alloc(mp, ino);
-       if (!ip)
-               return ENOMEM;
-
        /*
         * Fill in the location information in the in-core inode.
         */
        ip->i_imap.im_blkno = bno;
-       error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, imap_flags);
+       error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags);
        if (error)
-               goto out_destroy_inode;
+               return error;
        ASSERT(bno == 0 || bno == ip->i_imap.im_blkno);
 
        /*
         * Get pointers to the on-disk inode and the buffer containing it.
         */
        error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp,
-                              XFS_BUF_LOCK, imap_flags);
+                              XFS_BUF_LOCK, iget_flags);
        if (error)
-               goto out_destroy_inode;
+               return error;
        dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset);
 
        /*
@@ -968,14 +885,8 @@ xfs_iread(
         * to worry about the inode being changed just because we released
         * the buffer.
         */
-       xfs_trans_brelse(tp, bp);
-       *ipp = ip;
-       return 0;
-
  out_brelse:
        xfs_trans_brelse(tp, bp);
- out_destroy_inode:
-       xfs_destroy_inode(ip);
        return error;
 }
 
index 49e609c..ae5800e 100644 (file)
@@ -516,8 +516,8 @@ void                xfs_ireclaim(xfs_inode_t *);
 /*
  * xfs_inode.c prototypes.
  */
-int            xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-                         xfs_inode_t **, xfs_daddr_t, uint);
+int            xfs_iread(struct xfs_mount *, struct xfs_trans *,
+                         struct xfs_inode *, xfs_daddr_t, uint);
 int            xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
                           xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
                           int, struct xfs_buf **, boolean_t *, xfs_inode_t **);