diff options
-rw-r--r-- | fs/xfs/xfs_iget.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 17 |
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); |
203 | out_destroy: | 203 | out_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 | */ | ||
323 | static 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 | */ |
315 | static inline void | 332 | static inline void |