diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 37 | ||||
-rw-r--r-- | fs/xfs/xfs_iget.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 111 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_itable.c | 14 |
5 files changed, 119 insertions, 59 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 37ebe36056eb..d1c4dec51a3b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -887,6 +887,41 @@ xfs_fs_inode_init_once( | |||
887 | inode_init_once((struct inode *)vnode); | 887 | inode_init_once((struct inode *)vnode); |
888 | } | 888 | } |
889 | 889 | ||
890 | |||
891 | /* | ||
892 | * Slab object creation initialisation for the XFS inode. | ||
893 | * This covers only the idempotent fields in the XFS inode; | ||
894 | * all other fields need to be initialised on allocation | ||
895 | * from the slab. This avoids the need to repeatedly intialise | ||
896 | * fields in the xfs inode that left in the initialise state | ||
897 | * when freeing the inode. | ||
898 | */ | ||
899 | void | ||
900 | xfs_inode_init_once( | ||
901 | kmem_zone_t *zone, | ||
902 | void *inode) | ||
903 | { | ||
904 | struct xfs_inode *ip = inode; | ||
905 | |||
906 | memset(ip, 0, sizeof(struct xfs_inode)); | ||
907 | atomic_set(&ip->i_iocount, 0); | ||
908 | atomic_set(&ip->i_pincount, 0); | ||
909 | spin_lock_init(&ip->i_flags_lock); | ||
910 | INIT_LIST_HEAD(&ip->i_reclaim); | ||
911 | init_waitqueue_head(&ip->i_ipin_wait); | ||
912 | /* | ||
913 | * Because we want to use a counting completion, complete | ||
914 | * the flush completion once to allow a single access to | ||
915 | * the flush completion without blocking. | ||
916 | */ | ||
917 | init_completion(&ip->i_flush); | ||
918 | complete(&ip->i_flush); | ||
919 | |||
920 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | ||
921 | "xfsino", ip->i_ino); | ||
922 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
923 | } | ||
924 | |||
890 | /* | 925 | /* |
891 | * Attempt to flush the inode, this will actually fail | 926 | * Attempt to flush the inode, this will actually fail |
892 | * if the inode is pinned, but we dirty the inode again | 927 | * if the inode is pinned, but we dirty the inode again |
@@ -2018,7 +2053,7 @@ xfs_init_zones(void) | |||
2018 | xfs_inode_zone = | 2053 | xfs_inode_zone = |
2019 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", | 2054 | kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode", |
2020 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | | 2055 | KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | |
2021 | KM_ZONE_SPREAD, NULL); | 2056 | KM_ZONE_SPREAD, xfs_inode_init_once); |
2022 | if (!xfs_inode_zone) | 2057 | if (!xfs_inode_zone) |
2023 | goto out_destroy_efi_zone; | 2058 | goto out_destroy_efi_zone; |
2024 | 2059 | ||
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e229e9e001c2..5be89d760a9a 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -210,21 +210,6 @@ finish_inode: | |||
210 | 210 | ||
211 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); | 211 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
212 | 212 | ||
213 | |||
214 | mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | ||
215 | "xfsino", ip->i_ino); | ||
216 | mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | ||
217 | init_waitqueue_head(&ip->i_ipin_wait); | ||
218 | atomic_set(&ip->i_pincount, 0); | ||
219 | |||
220 | /* | ||
221 | * Because we want to use a counting completion, complete | ||
222 | * the flush completion once to allow a single access to | ||
223 | * the flush completion without blocking. | ||
224 | */ | ||
225 | init_completion(&ip->i_flush); | ||
226 | complete(&ip->i_flush); | ||
227 | |||
228 | if (lock_flags) | 213 | if (lock_flags) |
229 | xfs_ilock(ip, lock_flags); | 214 | xfs_ilock(ip, lock_flags); |
230 | 215 | ||
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 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 1420c49674d7..3af1f6dd1498 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -513,6 +513,7 @@ int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, | |||
513 | xfs_fsize_t, int, int); | 513 | xfs_fsize_t, int, int); |
514 | int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); | 514 | int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); |
515 | 515 | ||
516 | struct xfs_inode * xfs_inode_alloc(struct xfs_mount *, xfs_ino_t); | ||
516 | void xfs_idestroy_fork(xfs_inode_t *, int); | 517 | void xfs_idestroy_fork(xfs_inode_t *, int); |
517 | void xfs_idestroy(xfs_inode_t *); | 518 | void xfs_idestroy(xfs_inode_t *); |
518 | void xfs_idata_realloc(xfs_inode_t *, int, int); | 519 | void xfs_idata_realloc(xfs_inode_t *, int, int); |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index cf6754a3c5b3..4f4c93941067 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -594,21 +594,21 @@ xfs_bulkstat( | |||
594 | /* | 594 | /* |
595 | * Get the inode cluster buffer | 595 | * Get the inode cluster buffer |
596 | */ | 596 | */ |
597 | ASSERT(xfs_inode_zone != NULL); | ||
598 | ip = kmem_zone_zalloc(xfs_inode_zone, | ||
599 | KM_SLEEP); | ||
600 | ip->i_ino = ino; | ||
601 | ip->i_mount = mp; | ||
602 | spin_lock_init(&ip->i_flags_lock); | ||
603 | if (bp) | 597 | if (bp) |
604 | xfs_buf_relse(bp); | 598 | xfs_buf_relse(bp); |
599 | ip = xfs_inode_alloc(mp, ino); | ||
600 | if (!ip) { | ||
601 | bp = NULL; | ||
602 | rval = ENOMEM; | ||
603 | break; | ||
604 | } | ||
605 | error = xfs_itobp(mp, NULL, ip, | 605 | error = xfs_itobp(mp, NULL, ip, |
606 | &dip, &bp, bno, | 606 | &dip, &bp, bno, |
607 | XFS_IMAP_BULKSTAT, | 607 | XFS_IMAP_BULKSTAT, |
608 | XFS_BUF_LOCK); | 608 | XFS_BUF_LOCK); |
609 | if (!error) | 609 | if (!error) |
610 | clustidx = ip->i_boffset / mp->m_sb.sb_inodesize; | 610 | clustidx = ip->i_boffset / mp->m_sb.sb_inodesize; |
611 | kmem_zone_free(xfs_inode_zone, ip); | 611 | xfs_idestroy(ip); |
612 | if (XFS_TEST_ERROR(error != 0, | 612 | if (XFS_TEST_ERROR(error != 0, |
613 | mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, | 613 | mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, |
614 | XFS_RANDOM_BULKSTAT_READ_CHUNK)) { | 614 | XFS_RANDOM_BULKSTAT_READ_CHUNK)) { |