aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_iget.c2
-rw-r--r--fs/xfs/xfs_inode.c21
-rw-r--r--fs/xfs/xfs_inode.h17
3 files changed, 29 insertions, 11 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 377c0cd14999..837cae781536 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -201,7 +201,7 @@ out_unlock:
201 if (lock_flags) 201 if (lock_flags)
202 xfs_iunlock(ip, lock_flags); 202 xfs_iunlock(ip, lock_flags);
203out_destroy: 203out_destroy:
204 xfs_idestroy(ip); 204 xfs_destroy_inode(ip);
205 return error; 205 return error;
206} 206}
207 207
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 35e419191abf..cd522827f99e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -898,18 +898,14 @@ xfs_iread(
898 * know that this is a new incore inode. 898 * know that this is a new incore inode.
899 */ 899 */
900 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK); 900 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK);
901 if (error) { 901 if (error)
902 xfs_idestroy(ip); 902 goto out_destroy_inode;
903 return error;
904 }
905 903
906 /* 904 /*
907 * If we got something that isn't an inode it means someone 905 * If we got something that isn't an inode it means someone
908 * (nfs or dmi) has a stale handle. 906 * (nfs or dmi) has a stale handle.
909 */ 907 */
910 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { 908 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
911 xfs_idestroy(ip);
912 xfs_trans_brelse(tp, bp);
913#ifdef DEBUG 909#ifdef DEBUG
914 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 910 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
915 "dip->di_core.di_magic (0x%x) != " 911 "dip->di_core.di_magic (0x%x) != "
@@ -917,7 +913,8 @@ xfs_iread(
917 be16_to_cpu(dip->di_core.di_magic), 913 be16_to_cpu(dip->di_core.di_magic),
918 XFS_DINODE_MAGIC); 914 XFS_DINODE_MAGIC);
919#endif /* DEBUG */ 915#endif /* DEBUG */
920 return XFS_ERROR(EINVAL); 916 error = XFS_ERROR(EINVAL);
917 goto out_brelse;
921 } 918 }
922 919
923 /* 920 /*
@@ -931,14 +928,12 @@ xfs_iread(
931 xfs_dinode_from_disk(&ip->i_d, &dip->di_core); 928 xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
932 error = xfs_iformat(ip, dip); 929 error = xfs_iformat(ip, dip);
933 if (error) { 930 if (error) {
934 xfs_idestroy(ip);
935 xfs_trans_brelse(tp, bp);
936#ifdef DEBUG 931#ifdef DEBUG
937 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " 932 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
938 "xfs_iformat() returned error %d", 933 "xfs_iformat() returned error %d",
939 error); 934 error);
940#endif /* DEBUG */ 935#endif /* DEBUG */
941 return error; 936 goto out_brelse;
942 } 937 }
943 } else { 938 } else {
944 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); 939 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
@@ -1004,6 +999,12 @@ xfs_iread(
1004 xfs_trans_brelse(tp, bp); 999 xfs_trans_brelse(tp, bp);
1005 *ipp = ip; 1000 *ipp = ip;
1006 return 0; 1001 return 0;
1002
1003 out_brelse:
1004 xfs_trans_brelse(tp, bp);
1005 out_destroy_inode:
1006 xfs_destroy_inode(ip);
1007 return error;
1007} 1008}
1008 1009
1009/* 1010/*
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 5d12cfeb43c5..7f007ef4bbb3 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -310,6 +310,23 @@ static inline struct inode *VFS_I(struct xfs_inode *ip)
310} 310}
311 311
312/* 312/*
313 * Get rid of a partially initialized inode.
314 *
315 * We have to go through destroy_inode to make sure allocations
316 * from init_inode_always like the security data are undone.
317 *
318 * We mark the inode bad so that it takes the short cut in
319 * the reclaim path instead of going through the flush path
320 * which doesn't make sense for an inode that has never seen the
321 * light of day.
322 */
323static inline void xfs_destroy_inode(struct xfs_inode *ip)
324{
325 make_bad_inode(VFS_I(ip));
326 return destroy_inode(VFS_I(ip));
327}
328
329/*
313 * i_flags helper functions 330 * i_flags helper functions
314 */ 331 */
315static inline void 332static inline void