Commit 9ed0451ee0a13469f7b38e4ced8974036f6d114f

Authored by Christoph Hellwig
Committed by Lachlan McIlroy
1 parent 087e3b0460

[XFS] free partially initialized inodes using destroy_inode

To make sure we free the security data inodes need to be freed using the
proper VFS helper (which we also need to export for this). We mark these
inodes bad so we can skip the flush path for them.

SGI-PV: 987246

SGI-Modid: xfs-linux-melb:xfs-kern:32398a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>

Showing 3 changed files with 29 additions and 11 deletions Side-by-side Diff

... ... @@ -201,7 +201,7 @@
201 201 if (lock_flags)
202 202 xfs_iunlock(ip, lock_flags);
203 203 out_destroy:
204   - xfs_idestroy(ip);
  204 + xfs_destroy_inode(ip);
205 205 return error;
206 206 }
207 207  
... ... @@ -898,18 +898,14 @@
898 898 * know that this is a new incore inode.
899 899 */
900 900 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK);
901   - if (error) {
902   - xfs_idestroy(ip);
903   - return error;
904   - }
  901 + if (error)
  902 + goto out_destroy_inode;
905 903  
906 904 /*
907 905 * If we got something that isn't an inode it means someone
908 906 * (nfs or dmi) has a stale handle.
909 907 */
910 908 if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
911   - xfs_idestroy(ip);
912   - xfs_trans_brelse(tp, bp);
913 909 #ifdef DEBUG
914 910 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
915 911 "dip->di_core.di_magic (0x%x) != "
... ... @@ -917,7 +913,8 @@
917 913 be16_to_cpu(dip->di_core.di_magic),
918 914 XFS_DINODE_MAGIC);
919 915 #endif /* DEBUG */
920   - return XFS_ERROR(EINVAL);
  916 + error = XFS_ERROR(EINVAL);
  917 + goto out_brelse;
921 918 }
922 919  
923 920 /*
924 921  
... ... @@ -931,14 +928,12 @@
931 928 xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
932 929 error = xfs_iformat(ip, dip);
933 930 if (error) {
934   - xfs_idestroy(ip);
935   - xfs_trans_brelse(tp, bp);
936 931 #ifdef DEBUG
937 932 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
938 933 "xfs_iformat() returned error %d",
939 934 error);
940 935 #endif /* DEBUG */
941   - return error;
  936 + goto out_brelse;
942 937 }
943 938 } else {
944 939 ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
... ... @@ -1004,6 +999,12 @@
1004 999 xfs_trans_brelse(tp, bp);
1005 1000 *ipp = ip;
1006 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 /*
... ... @@ -310,6 +310,23 @@
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 330 * i_flags helper functions
314 331 */
315 332 static inline void