diff options
author | Christoph Hellwig <hch@lst.de> | 2008-11-27 22:23:42 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:38:17 -0500 |
commit | 24f211bad09a31f19dda0c3faffe0244f4f235f5 (patch) | |
tree | 3554243712a41729df866e348a3925ffdf950b8c | |
parent | b48d8d64377f39913663a06f4757f3b8c6fc6d87 (diff) |
[XFS] move inode allocation out xfs_iread
Allocate the inode in xfs_iget_cache_miss and pass it into xfs_iread. This
simplifies the error handling and allows xfs_iread to be shared with userspace
which already uses these semantics.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
-rw-r--r-- | fs/xfs/xfs_iget.c | 88 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 103 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 4 |
3 files changed, 91 insertions, 104 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index d60522a73a17..27ec2417b852 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -40,6 +40,82 @@ | |||
40 | #include "xfs_utils.h" | 40 | #include "xfs_utils.h" |
41 | #include "xfs_trans_priv.h" | 41 | #include "xfs_trans_priv.h" |
42 | #include "xfs_inode_item.h" | 42 | #include "xfs_inode_item.h" |
43 | #include "xfs_bmap.h" | ||
44 | #include "xfs_btree_trace.h" | ||
45 | #include "xfs_dir2_trace.h" | ||
46 | |||
47 | |||
48 | /* | ||
49 | * Allocate and initialise an xfs_inode. | ||
50 | */ | ||
51 | STATIC struct xfs_inode * | ||
52 | xfs_inode_alloc( | ||
53 | struct xfs_mount *mp, | ||
54 | xfs_ino_t ino) | ||
55 | { | ||
56 | struct xfs_inode *ip; | ||
57 | |||
58 | /* | ||
59 | * if this didn't occur in transactions, we could use | ||
60 | * KM_MAYFAIL and return NULL here on ENOMEM. Set the | ||
61 | * code up to do this anyway. | ||
62 | */ | ||
63 | ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP); | ||
64 | if (!ip) | ||
65 | return NULL; | ||
66 | |||
67 | ASSERT(atomic_read(&ip->i_iocount) == 0); | ||
68 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
69 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | ||
70 | ASSERT(completion_done(&ip->i_flush)); | ||
71 | |||
72 | /* | ||
73 | * initialise the VFS inode here to get failures | ||
74 | * out of the way early. | ||
75 | */ | ||
76 | if (!inode_init_always(mp->m_super, VFS_I(ip))) { | ||
77 | kmem_zone_free(xfs_inode_zone, ip); | ||
78 | return NULL; | ||
79 | } | ||
80 | |||
81 | /* initialise the xfs inode */ | ||
82 | ip->i_ino = ino; | ||
83 | ip->i_mount = mp; | ||
84 | memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); | ||
85 | ip->i_afp = NULL; | ||
86 | memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); | ||
87 | ip->i_flags = 0; | ||
88 | ip->i_update_core = 0; | ||
89 | ip->i_update_size = 0; | ||
90 | ip->i_delayed_blks = 0; | ||
91 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); | ||
92 | ip->i_size = 0; | ||
93 | ip->i_new_size = 0; | ||
94 | |||
95 | /* | ||
96 | * Initialize inode's trace buffers. | ||
97 | */ | ||
98 | #ifdef XFS_INODE_TRACE | ||
99 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); | ||
100 | #endif | ||
101 | #ifdef XFS_BMAP_TRACE | ||
102 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); | ||
103 | #endif | ||
104 | #ifdef XFS_BTREE_TRACE | ||
105 | ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); | ||
106 | #endif | ||
107 | #ifdef XFS_RW_TRACE | ||
108 | ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); | ||
109 | #endif | ||
110 | #ifdef XFS_ILOCK_TRACE | ||
111 | ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); | ||
112 | #endif | ||
113 | #ifdef XFS_DIR2_TRACE | ||
114 | ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); | ||
115 | #endif | ||
116 | |||
117 | return ip; | ||
118 | } | ||
43 | 119 | ||
44 | /* | 120 | /* |
45 | * Check the validity of the inode we just found it the cache | 121 | * Check the validity of the inode we just found it the cache |
@@ -155,13 +231,13 @@ xfs_iget_cache_miss( | |||
155 | unsigned long first_index, mask; | 231 | unsigned long first_index, mask; |
156 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); | 232 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); |
157 | 233 | ||
158 | /* | 234 | ip = xfs_inode_alloc(mp, ino); |
159 | * Read the disk inode attributes into a new inode structure and get | 235 | if (!ip) |
160 | * a new vnode for it. This should also initialize i_ino and i_mount. | 236 | return ENOMEM; |
161 | */ | 237 | |
162 | error = xfs_iread(mp, tp, ino, &ip, bno, flags); | 238 | error = xfs_iread(mp, tp, ip, bno, flags); |
163 | if (error) | 239 | if (error) |
164 | return error; | 240 | goto out_destroy; |
165 | 241 | ||
166 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); | 242 | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
167 | 243 | ||
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 4290760473ff..872191b46784 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -758,119 +758,36 @@ xfs_dic2xflags( | |||
758 | } | 758 | } |
759 | 759 | ||
760 | /* | 760 | /* |
761 | * Allocate and initialise an xfs_inode. | 761 | * Read the disk inode attributes into the in-core inode structure. |
762 | */ | ||
763 | STATIC struct xfs_inode * | ||
764 | xfs_inode_alloc( | ||
765 | struct xfs_mount *mp, | ||
766 | xfs_ino_t ino) | ||
767 | { | ||
768 | struct xfs_inode *ip; | ||
769 | |||
770 | /* | ||
771 | * if this didn't occur in transactions, we could use | ||
772 | * KM_MAYFAIL and return NULL here on ENOMEM. Set the | ||
773 | * code up to do this anyway. | ||
774 | */ | ||
775 | ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP); | ||
776 | if (!ip) | ||
777 | return NULL; | ||
778 | |||
779 | ASSERT(atomic_read(&ip->i_iocount) == 0); | ||
780 | ASSERT(atomic_read(&ip->i_pincount) == 0); | ||
781 | ASSERT(!spin_is_locked(&ip->i_flags_lock)); | ||
782 | ASSERT(completion_done(&ip->i_flush)); | ||
783 | |||
784 | /* | ||
785 | * initialise the VFS inode here to get failures | ||
786 | * out of the way early. | ||
787 | */ | ||
788 | if (!inode_init_always(mp->m_super, VFS_I(ip))) { | ||
789 | kmem_zone_free(xfs_inode_zone, ip); | ||
790 | return NULL; | ||
791 | } | ||
792 | |||
793 | /* initialise the xfs inode */ | ||
794 | ip->i_ino = ino; | ||
795 | ip->i_mount = mp; | ||
796 | memset(&ip->i_imap, 0, sizeof(struct xfs_imap)); | ||
797 | ip->i_afp = NULL; | ||
798 | memset(&ip->i_df, 0, sizeof(xfs_ifork_t)); | ||
799 | ip->i_flags = 0; | ||
800 | ip->i_update_core = 0; | ||
801 | ip->i_update_size = 0; | ||
802 | ip->i_delayed_blks = 0; | ||
803 | memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); | ||
804 | ip->i_size = 0; | ||
805 | ip->i_new_size = 0; | ||
806 | |||
807 | /* | ||
808 | * Initialize inode's trace buffers. | ||
809 | */ | ||
810 | #ifdef XFS_INODE_TRACE | ||
811 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); | ||
812 | #endif | ||
813 | #ifdef XFS_BMAP_TRACE | ||
814 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); | ||
815 | #endif | ||
816 | #ifdef XFS_BTREE_TRACE | ||
817 | ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); | ||
818 | #endif | ||
819 | #ifdef XFS_RW_TRACE | ||
820 | ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); | ||
821 | #endif | ||
822 | #ifdef XFS_ILOCK_TRACE | ||
823 | ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); | ||
824 | #endif | ||
825 | #ifdef XFS_DIR2_TRACE | ||
826 | ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); | ||
827 | #endif | ||
828 | |||
829 | return ip; | ||
830 | } | ||
831 | |||
832 | /* | ||
833 | * Given a mount structure and an inode number, return a pointer | ||
834 | * to a newly allocated in-core inode corresponding to the given | ||
835 | * inode number. | ||
836 | * | ||
837 | * Initialize the inode's attributes and extent pointers if it | ||
838 | * already has them (it will not if the inode has no links). | ||
839 | */ | 762 | */ |
840 | int | 763 | int |
841 | xfs_iread( | 764 | xfs_iread( |
842 | xfs_mount_t *mp, | 765 | xfs_mount_t *mp, |
843 | xfs_trans_t *tp, | 766 | xfs_trans_t *tp, |
844 | xfs_ino_t ino, | 767 | xfs_inode_t *ip, |
845 | xfs_inode_t **ipp, | ||
846 | xfs_daddr_t bno, | 768 | xfs_daddr_t bno, |
847 | uint imap_flags) | 769 | uint iget_flags) |
848 | { | 770 | { |
849 | xfs_buf_t *bp; | 771 | xfs_buf_t *bp; |
850 | xfs_dinode_t *dip; | 772 | xfs_dinode_t *dip; |
851 | xfs_inode_t *ip; | ||
852 | int error; | 773 | int error; |
853 | 774 | ||
854 | ip = xfs_inode_alloc(mp, ino); | ||
855 | if (!ip) | ||
856 | return ENOMEM; | ||
857 | |||
858 | /* | 775 | /* |
859 | * Fill in the location information in the in-core inode. | 776 | * Fill in the location information in the in-core inode. |
860 | */ | 777 | */ |
861 | ip->i_imap.im_blkno = bno; | 778 | ip->i_imap.im_blkno = bno; |
862 | error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, imap_flags); | 779 | error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); |
863 | if (error) | 780 | if (error) |
864 | goto out_destroy_inode; | 781 | return error; |
865 | ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); | 782 | ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); |
866 | 783 | ||
867 | /* | 784 | /* |
868 | * Get pointers to the on-disk inode and the buffer containing it. | 785 | * Get pointers to the on-disk inode and the buffer containing it. |
869 | */ | 786 | */ |
870 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, | 787 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, |
871 | XFS_BUF_LOCK, imap_flags); | 788 | XFS_BUF_LOCK, iget_flags); |
872 | if (error) | 789 | if (error) |
873 | goto out_destroy_inode; | 790 | return error; |
874 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); | 791 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); |
875 | 792 | ||
876 | /* | 793 | /* |
@@ -968,14 +885,8 @@ xfs_iread( | |||
968 | * to worry about the inode being changed just because we released | 885 | * to worry about the inode being changed just because we released |
969 | * the buffer. | 886 | * the buffer. |
970 | */ | 887 | */ |
971 | xfs_trans_brelse(tp, bp); | ||
972 | *ipp = ip; | ||
973 | return 0; | ||
974 | |||
975 | out_brelse: | 888 | out_brelse: |
976 | xfs_trans_brelse(tp, bp); | 889 | xfs_trans_brelse(tp, bp); |
977 | out_destroy_inode: | ||
978 | xfs_destroy_inode(ip); | ||
979 | return error; | 890 | return error; |
980 | } | 891 | } |
981 | 892 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 49e609c39d7e..ae5800e7d396 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -516,8 +516,8 @@ void xfs_ireclaim(xfs_inode_t *); | |||
516 | /* | 516 | /* |
517 | * xfs_inode.c prototypes. | 517 | * xfs_inode.c prototypes. |
518 | */ | 518 | */ |
519 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 519 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, |
520 | xfs_inode_t **, xfs_daddr_t, uint); | 520 | struct xfs_inode *, xfs_daddr_t, uint); |
521 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, | 521 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
522 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, | 522 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, |
523 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); | 523 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); |