aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-11-27 22:23:42 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:38:17 -0500
commit24f211bad09a31f19dda0c3faffe0244f4f235f5 (patch)
tree3554243712a41729df866e348a3925ffdf950b8c /fs/xfs
parentb48d8d64377f39913663a06f4757f3b8c6fc6d87 (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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_iget.c88
-rw-r--r--fs/xfs/xfs_inode.c103
-rw-r--r--fs/xfs/xfs_inode.h4
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 */
51STATIC struct xfs_inode *
52xfs_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 */
763STATIC struct xfs_inode *
764xfs_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 */
840int 763int
841xfs_iread( 764xfs_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 */
519int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, 519int xfs_iread(struct xfs_mount *, struct xfs_trans *,
520 xfs_inode_t **, xfs_daddr_t, uint); 520 struct xfs_inode *, xfs_daddr_t, uint);
521int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, 521int 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 **);