aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c68
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 */
1032int 1037int
1033xfs_iread( 1038xfs_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}