diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 111 |
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 | */ | ||
793 | struct xfs_inode * | ||
794 | xfs_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 | ||