aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
authorDavid Chinner <david@fromorbit.com>2008-10-30 01:11:59 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:11:59 -0400
commit07c8f67587724b417f60bffb32c448dd94647b54 (patch)
tree01f6cf39be93dd5515481d09d282c503e05ef79f /fs/xfs/xfs_inode.c
parente946217e4fdaa67681bbabfa8e6b18641921f750 (diff)
[XFS] Make use of the init-once slab optimisation.
To avoid having to initialise some fields of the XFS inode on every allocation, we can use the slab init-once feature to initialise them. All we have to guarantee is that when we free the inode, all it's entries are in the initial state. Add asserts where possible to ensure debug kernels check this initial state before freeing and after allocation. SGI-PV: 981498 SGI-Modid: xfs-linux-melb:xfs-kern:31925a Signed-off-by: David Chinner <david@fromorbit.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c111
1 files changed, 75 insertions, 36 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index dbd9cef852ec..b0c604e1bd47 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -788,6 +788,70 @@ xfs_dic2xflags(
788} 788}
789 789
790/* 790/*
791 * Allocate and initialise an xfs_inode.
792 */
793struct xfs_inode *
794xfs_inode_alloc(
795 struct xfs_mount *mp,
796 xfs_ino_t ino)
797{
798 struct xfs_inode *ip;
799
800 /*
801 * if this didn't occur in transactions, we could use
802 * KM_MAYFAIL and return NULL here on ENOMEM. Set the
803 * code up to do this anyway.
804 */
805 ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
806 if (!ip)
807 return NULL;
808
809 ASSERT(atomic_read(&ip->i_iocount) == 0);
810 ASSERT(atomic_read(&ip->i_pincount) == 0);
811 ASSERT(!spin_is_locked(&ip->i_flags_lock));
812 ASSERT(list_empty(&ip->i_reclaim));
813
814 ip->i_ino = ino;
815 ip->i_mount = mp;
816 ip->i_blkno = 0;
817 ip->i_len = 0;
818 ip->i_boffset =0;
819 ip->i_afp = NULL;
820 memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
821 ip->i_flags = 0;
822 ip->i_update_core = 0;
823 ip->i_update_size = 0;
824 ip->i_delayed_blks = 0;
825 memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
826 ip->i_size = 0;
827 ip->i_new_size = 0;
828
829 /*
830 * Initialize inode's trace buffers.
831 */
832#ifdef XFS_INODE_TRACE
833 ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
834#endif
835#ifdef XFS_BMAP_TRACE
836 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
837#endif
838#ifdef XFS_BMBT_TRACE
839 ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
840#endif
841#ifdef XFS_RW_TRACE
842 ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
843#endif
844#ifdef XFS_ILOCK_TRACE
845 ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
846#endif
847#ifdef XFS_DIR2_TRACE
848 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
849#endif
850
851 return ip;
852}
853
854/*
791 * Given a mount structure and an inode number, return a pointer 855 * Given a mount structure and an inode number, return a pointer
792 * to a newly allocated in-core inode corresponding to the given 856 * to a newly allocated in-core inode corresponding to the given
793 * inode number. 857 * inode number.
@@ -809,13 +873,9 @@ xfs_iread(
809 xfs_inode_t *ip; 873 xfs_inode_t *ip;
810 int error; 874 int error;
811 875
812 ASSERT(xfs_inode_zone != NULL); 876 ip = xfs_inode_alloc(mp, ino);
813 877 if (!ip)
814 ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); 878 return ENOMEM;
815 ip->i_ino = ino;
816 ip->i_mount = mp;
817 atomic_set(&ip->i_iocount, 0);
818 spin_lock_init(&ip->i_flags_lock);
819 879
820 /* 880 /*
821 * Get pointer's to the on-disk inode and the buffer containing it. 881 * Get pointer's to the on-disk inode and the buffer containing it.
@@ -831,34 +891,11 @@ xfs_iread(
831 } 891 }
832 892
833 /* 893 /*
834 * Initialize inode's trace buffers.
835 * Do this before xfs_iformat in case it adds entries.
836 */
837#ifdef XFS_INODE_TRACE
838 ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
839#endif
840#ifdef XFS_BMAP_TRACE
841 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
842#endif
843#ifdef XFS_BMBT_TRACE
844 ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
845#endif
846#ifdef XFS_RW_TRACE
847 ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
848#endif
849#ifdef XFS_ILOCK_TRACE
850 ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
851#endif
852#ifdef XFS_DIR2_TRACE
853 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
854#endif
855
856 /*
857 * If we got something that isn't an inode it means someone 894 * If we got something that isn't an inode it means someone
858 * (nfs or dmi) has a stale handle. 895 * (nfs or dmi) has a stale handle.
859 */ 896 */
860 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { 897 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
861 kmem_zone_free(xfs_inode_zone, ip); 898 xfs_idestroy(ip);
862 xfs_trans_brelse(tp, bp); 899 xfs_trans_brelse(tp, bp);
863#ifdef DEBUG 900#ifdef DEBUG
864 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 901 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
@@ -881,7 +918,7 @@ xfs_iread(
881 xfs_dinode_from_disk(&ip->i_d, &dip->di_core); 918 xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
882 error = xfs_iformat(ip, dip); 919 error = xfs_iformat(ip, dip);
883 if (error) { 920 if (error) {
884 kmem_zone_free(xfs_inode_zone, ip); 921 xfs_idestroy(ip);
885 xfs_trans_brelse(tp, bp); 922 xfs_trans_brelse(tp, bp);
886#ifdef DEBUG 923#ifdef DEBUG
887 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 924 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
@@ -911,8 +948,6 @@ xfs_iread(
911 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); 948 XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
912 } 949 }
913 950
914 INIT_LIST_HEAD(&ip->i_reclaim);
915
916 /* 951 /*
917 * The inode format changed when we moved the link count and 952 * The inode format changed when we moved the link count and
918 * made it 32 bits long. If this is an old format inode, 953 * made it 32 bits long. If this is an old format inode,
@@ -2631,8 +2666,6 @@ xfs_idestroy(
2631 } 2666 }
2632 if (ip->i_afp) 2667 if (ip->i_afp)
2633 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 2668 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
2634 mrfree(&ip->i_lock);
2635 mrfree(&ip->i_iolock);
2636 2669
2637#ifdef XFS_INODE_TRACE 2670#ifdef XFS_INODE_TRACE
2638 ktrace_free(ip->i_trace); 2671 ktrace_free(ip->i_trace);
@@ -2671,7 +2704,13 @@ xfs_idestroy(
2671 spin_unlock(&mp->m_ail_lock); 2704 spin_unlock(&mp->m_ail_lock);
2672 } 2705 }
2673 xfs_inode_item_destroy(ip); 2706 xfs_inode_item_destroy(ip);
2707 ip->i_itemp = NULL;
2674 } 2708 }
2709 /* asserts to verify all state is correct here */
2710 ASSERT(atomic_read(&ip->i_iocount) == 0);
2711 ASSERT(atomic_read(&ip->i_pincount) == 0);
2712 ASSERT(!spin_is_locked(&ip->i_flags_lock));
2713 ASSERT(list_empty(&ip->i_reclaim));
2675 kmem_zone_free(xfs_inode_zone, ip); 2714 kmem_zone_free(xfs_inode_zone, ip);
2676} 2715}
2677 2716