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 | ||
