aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
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