aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c37
-rw-r--r--fs/xfs/xfs_iget.c15
-rw-r--r--fs/xfs/xfs_inode.c111
-rw-r--r--fs/xfs/xfs_inode.h1
-rw-r--r--fs/xfs/xfs_itable.c14
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 */
899void
900xfs_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 */
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
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);
514int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); 514int xfs_iunlink(struct xfs_trans *, xfs_inode_t *);
515 515
516struct xfs_inode * xfs_inode_alloc(struct xfs_mount *, xfs_ino_t);
516void xfs_idestroy_fork(xfs_inode_t *, int); 517void xfs_idestroy_fork(xfs_inode_t *, int);
517void xfs_idestroy(xfs_inode_t *); 518void xfs_idestroy(xfs_inode_t *);
518void xfs_idata_realloc(xfs_inode_t *, int, int); 519void 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)) {