diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 68 |
1 files changed, 32 insertions, 36 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7f7be5f98f52..9ecfe1e559fc 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1028,6 +1028,11 @@ xfs_dinode_calc_crc( | |||
1028 | 1028 | ||
1029 | /* | 1029 | /* |
1030 | * Read the disk inode attributes into the in-core inode structure. | 1030 | * Read the disk inode attributes into the in-core inode structure. |
1031 | * | ||
1032 | * If we are initialising a new inode and we are not utilising the | ||
1033 | * XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new inode core | ||
1034 | * with a random generation number. If we are keeping inodes around, we need to | ||
1035 | * read the inode cluster to get the existing generation number off disk. | ||
1031 | */ | 1036 | */ |
1032 | int | 1037 | int |
1033 | xfs_iread( | 1038 | xfs_iread( |
@@ -1047,6 +1052,22 @@ xfs_iread( | |||
1047 | if (error) | 1052 | if (error) |
1048 | return error; | 1053 | return error; |
1049 | 1054 | ||
1055 | /* shortcut IO on inode allocation if possible */ | ||
1056 | if ((iget_flags & XFS_IGET_CREATE) && | ||
1057 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { | ||
1058 | /* initialise the on-disk inode core */ | ||
1059 | memset(&ip->i_d, 0, sizeof(ip->i_d)); | ||
1060 | ip->i_d.di_magic = XFS_DINODE_MAGIC; | ||
1061 | ip->i_d.di_gen = prandom_u32(); | ||
1062 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
1063 | ip->i_d.di_version = 3; | ||
1064 | ip->i_d.di_ino = ip->i_ino; | ||
1065 | uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); | ||
1066 | } else | ||
1067 | ip->i_d.di_version = 2; | ||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1050 | /* | 1071 | /* |
1051 | * Get pointers to the on-disk inode and the buffer containing it. | 1072 | * Get pointers to the on-disk inode and the buffer containing it. |
1052 | */ | 1073 | */ |
@@ -1133,17 +1154,16 @@ xfs_iread( | |||
1133 | xfs_buf_set_ref(bp, XFS_INO_REF); | 1154 | xfs_buf_set_ref(bp, XFS_INO_REF); |
1134 | 1155 | ||
1135 | /* | 1156 | /* |
1136 | * Use xfs_trans_brelse() to release the buffer containing the | 1157 | * Use xfs_trans_brelse() to release the buffer containing the on-disk |
1137 | * on-disk inode, because it was acquired with xfs_trans_read_buf() | 1158 | * inode, because it was acquired with xfs_trans_read_buf() in |
1138 | * in xfs_imap_to_bp() above. If tp is NULL, this is just a normal | 1159 | * xfs_imap_to_bp() above. If tp is NULL, this is just a normal |
1139 | * brelse(). If we're within a transaction, then xfs_trans_brelse() | 1160 | * brelse(). If we're within a transaction, then xfs_trans_brelse() |
1140 | * will only release the buffer if it is not dirty within the | 1161 | * will only release the buffer if it is not dirty within the |
1141 | * transaction. It will be OK to release the buffer in this case, | 1162 | * transaction. It will be OK to release the buffer in this case, |
1142 | * because inodes on disk are never destroyed and we will be | 1163 | * because inodes on disk are never destroyed and we will be locking the |
1143 | * locking the new in-core inode before putting it in the hash | 1164 | * new in-core inode before putting it in the cache where other |
1144 | * table where other processes can find it. Thus we don't have | 1165 | * processes can find it. Thus we don't have to worry about the inode |
1145 | * to worry about the inode being changed just because we released | 1166 | * being changed just because we released the buffer. |
1146 | * the buffer. | ||
1147 | */ | 1167 | */ |
1148 | out_brelse: | 1168 | out_brelse: |
1149 | xfs_trans_brelse(tp, bp); | 1169 | xfs_trans_brelse(tp, bp); |
@@ -2028,8 +2048,6 @@ xfs_ifree( | |||
2028 | int error; | 2048 | int error; |
2029 | int delete; | 2049 | int delete; |
2030 | xfs_ino_t first_ino; | 2050 | xfs_ino_t first_ino; |
2031 | xfs_dinode_t *dip; | ||
2032 | xfs_buf_t *ibp; | ||
2033 | 2051 | ||
2034 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 2052 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2035 | ASSERT(ip->i_d.di_nlink == 0); | 2053 | ASSERT(ip->i_d.di_nlink == 0); |
@@ -2042,14 +2060,13 @@ xfs_ifree( | |||
2042 | * Pull the on-disk inode from the AGI unlinked list. | 2060 | * Pull the on-disk inode from the AGI unlinked list. |
2043 | */ | 2061 | */ |
2044 | error = xfs_iunlink_remove(tp, ip); | 2062 | error = xfs_iunlink_remove(tp, ip); |
2045 | if (error != 0) { | 2063 | if (error) |
2046 | return error; | 2064 | return error; |
2047 | } | ||
2048 | 2065 | ||
2049 | error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); | 2066 | error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); |
2050 | if (error != 0) { | 2067 | if (error) |
2051 | return error; | 2068 | return error; |
2052 | } | 2069 | |
2053 | ip->i_d.di_mode = 0; /* mark incore inode as free */ | 2070 | ip->i_d.di_mode = 0; /* mark incore inode as free */ |
2054 | ip->i_d.di_flags = 0; | 2071 | ip->i_d.di_flags = 0; |
2055 | ip->i_d.di_dmevmask = 0; | 2072 | ip->i_d.di_dmevmask = 0; |
@@ -2061,31 +2078,10 @@ xfs_ifree( | |||
2061 | * by reincarnations of this inode. | 2078 | * by reincarnations of this inode. |
2062 | */ | 2079 | */ |
2063 | ip->i_d.di_gen++; | 2080 | ip->i_d.di_gen++; |
2064 | |||
2065 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 2081 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
2066 | 2082 | ||
2067 | error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp, | 2083 | if (delete) |
2068 | 0, 0); | ||
2069 | if (error) | ||
2070 | return error; | ||
2071 | |||
2072 | /* | ||
2073 | * Clear the on-disk di_mode. This is to prevent xfs_bulkstat | ||
2074 | * from picking up this inode when it is reclaimed (its incore state | ||
2075 | * initialzed but not flushed to disk yet). The in-core di_mode is | ||
2076 | * already cleared and a corresponding transaction logged. | ||
2077 | * The hack here just synchronizes the in-core to on-disk | ||
2078 | * di_mode value in advance before the actual inode sync to disk. | ||
2079 | * This is OK because the inode is already unlinked and would never | ||
2080 | * change its di_mode again for this inode generation. | ||
2081 | * This is a temporary hack that would require a proper fix | ||
2082 | * in the future. | ||
2083 | */ | ||
2084 | dip->di_mode = 0; | ||
2085 | |||
2086 | if (delete) { | ||
2087 | error = xfs_ifree_cluster(ip, tp, first_ino); | 2084 | error = xfs_ifree_cluster(ip, tp, first_ino); |
2088 | } | ||
2089 | 2085 | ||
2090 | return error; | 2086 | return error; |
2091 | } | 2087 | } |