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 | } |
