diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 105 |
1 files changed, 57 insertions, 48 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7f7be5f98f52..bb262c25c8de 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -896,7 +896,6 @@ xfs_dinode_to_disk( | |||
896 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); | 896 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); |
897 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); | 897 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); |
898 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); | 898 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
899 | to->di_flushiter = cpu_to_be16(from->di_flushiter); | ||
900 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); | 899 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); |
901 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); | 900 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); |
902 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); | 901 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); |
@@ -924,6 +923,9 @@ xfs_dinode_to_disk( | |||
924 | to->di_lsn = cpu_to_be64(from->di_lsn); | 923 | to->di_lsn = cpu_to_be64(from->di_lsn); |
925 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); | 924 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); |
926 | uuid_copy(&to->di_uuid, &from->di_uuid); | 925 | uuid_copy(&to->di_uuid, &from->di_uuid); |
926 | to->di_flushiter = 0; | ||
927 | } else { | ||
928 | to->di_flushiter = cpu_to_be16(from->di_flushiter); | ||
927 | } | 929 | } |
928 | } | 930 | } |
929 | 931 | ||
@@ -1028,6 +1030,15 @@ xfs_dinode_calc_crc( | |||
1028 | 1030 | ||
1029 | /* | 1031 | /* |
1030 | * Read the disk inode attributes into the in-core inode structure. | 1032 | * Read the disk inode attributes into the in-core inode structure. |
1033 | * | ||
1034 | * For version 5 superblocks, if we are initialising a new inode and we are not | ||
1035 | * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new | ||
1036 | * inode core with a random generation number. If we are keeping inodes around, | ||
1037 | * we need to read the inode cluster to get the existing generation number off | ||
1038 | * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode | ||
1039 | * format) then log recovery is dependent on the di_flushiter field being | ||
1040 | * initialised from the current on-disk value and hence we must also read the | ||
1041 | * inode off disk. | ||
1031 | */ | 1042 | */ |
1032 | int | 1043 | int |
1033 | xfs_iread( | 1044 | xfs_iread( |
@@ -1047,6 +1058,23 @@ xfs_iread( | |||
1047 | if (error) | 1058 | if (error) |
1048 | return error; | 1059 | return error; |
1049 | 1060 | ||
1061 | /* shortcut IO on inode allocation if possible */ | ||
1062 | if ((iget_flags & XFS_IGET_CREATE) && | ||
1063 | xfs_sb_version_hascrc(&mp->m_sb) && | ||
1064 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { | ||
1065 | /* initialise the on-disk inode core */ | ||
1066 | memset(&ip->i_d, 0, sizeof(ip->i_d)); | ||
1067 | ip->i_d.di_magic = XFS_DINODE_MAGIC; | ||
1068 | ip->i_d.di_gen = prandom_u32(); | ||
1069 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
1070 | ip->i_d.di_version = 3; | ||
1071 | ip->i_d.di_ino = ip->i_ino; | ||
1072 | uuid_copy(&ip->i_d.di_uuid, &mp->m_sb.sb_uuid); | ||
1073 | } else | ||
1074 | ip->i_d.di_version = 2; | ||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1050 | /* | 1078 | /* |
1051 | * Get pointers to the on-disk inode and the buffer containing it. | 1079 | * Get pointers to the on-disk inode and the buffer containing it. |
1052 | */ | 1080 | */ |
@@ -1133,17 +1161,16 @@ xfs_iread( | |||
1133 | xfs_buf_set_ref(bp, XFS_INO_REF); | 1161 | xfs_buf_set_ref(bp, XFS_INO_REF); |
1134 | 1162 | ||
1135 | /* | 1163 | /* |
1136 | * Use xfs_trans_brelse() to release the buffer containing the | 1164 | * 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() | 1165 | * 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 | 1166 | * 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() | 1167 | * brelse(). If we're within a transaction, then xfs_trans_brelse() |
1140 | * will only release the buffer if it is not dirty within the | 1168 | * 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, | 1169 | * transaction. It will be OK to release the buffer in this case, |
1142 | * because inodes on disk are never destroyed and we will be | 1170 | * 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 | 1171 | * 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 | 1172 | * 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 | 1173 | * being changed just because we released the buffer. |
1146 | * the buffer. | ||
1147 | */ | 1174 | */ |
1148 | out_brelse: | 1175 | out_brelse: |
1149 | xfs_trans_brelse(tp, bp); | 1176 | xfs_trans_brelse(tp, bp); |
@@ -2028,8 +2055,6 @@ xfs_ifree( | |||
2028 | int error; | 2055 | int error; |
2029 | int delete; | 2056 | int delete; |
2030 | xfs_ino_t first_ino; | 2057 | xfs_ino_t first_ino; |
2031 | xfs_dinode_t *dip; | ||
2032 | xfs_buf_t *ibp; | ||
2033 | 2058 | ||
2034 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 2059 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2035 | ASSERT(ip->i_d.di_nlink == 0); | 2060 | ASSERT(ip->i_d.di_nlink == 0); |
@@ -2042,14 +2067,13 @@ xfs_ifree( | |||
2042 | * Pull the on-disk inode from the AGI unlinked list. | 2067 | * Pull the on-disk inode from the AGI unlinked list. |
2043 | */ | 2068 | */ |
2044 | error = xfs_iunlink_remove(tp, ip); | 2069 | error = xfs_iunlink_remove(tp, ip); |
2045 | if (error != 0) { | 2070 | if (error) |
2046 | return error; | 2071 | return error; |
2047 | } | ||
2048 | 2072 | ||
2049 | error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); | 2073 | error = xfs_difree(tp, ip->i_ino, flist, &delete, &first_ino); |
2050 | if (error != 0) { | 2074 | if (error) |
2051 | return error; | 2075 | return error; |
2052 | } | 2076 | |
2053 | ip->i_d.di_mode = 0; /* mark incore inode as free */ | 2077 | ip->i_d.di_mode = 0; /* mark incore inode as free */ |
2054 | ip->i_d.di_flags = 0; | 2078 | ip->i_d.di_flags = 0; |
2055 | ip->i_d.di_dmevmask = 0; | 2079 | ip->i_d.di_dmevmask = 0; |
@@ -2061,31 +2085,10 @@ xfs_ifree( | |||
2061 | * by reincarnations of this inode. | 2085 | * by reincarnations of this inode. |
2062 | */ | 2086 | */ |
2063 | ip->i_d.di_gen++; | 2087 | ip->i_d.di_gen++; |
2064 | |||
2065 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 2088 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
2066 | 2089 | ||
2067 | error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &dip, &ibp, | 2090 | 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); | 2091 | error = xfs_ifree_cluster(ip, tp, first_ino); |
2088 | } | ||
2089 | 2092 | ||
2090 | return error; | 2093 | return error; |
2091 | } | 2094 | } |
@@ -2160,8 +2163,8 @@ xfs_iroot_realloc( | |||
2160 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, | 2163 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, |
2161 | (int)new_size); | 2164 | (int)new_size); |
2162 | ifp->if_broot_bytes = (int)new_size; | 2165 | ifp->if_broot_bytes = (int)new_size; |
2163 | ASSERT(ifp->if_broot_bytes <= | 2166 | ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= |
2164 | XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip)); | 2167 | XFS_IFORK_SIZE(ip, whichfork)); |
2165 | memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); | 2168 | memmove(np, op, cur_max * (uint)sizeof(xfs_dfsbno_t)); |
2166 | return; | 2169 | return; |
2167 | } | 2170 | } |
@@ -2214,8 +2217,9 @@ xfs_iroot_realloc( | |||
2214 | kmem_free(ifp->if_broot); | 2217 | kmem_free(ifp->if_broot); |
2215 | ifp->if_broot = new_broot; | 2218 | ifp->if_broot = new_broot; |
2216 | ifp->if_broot_bytes = (int)new_size; | 2219 | ifp->if_broot_bytes = (int)new_size; |
2217 | ASSERT(ifp->if_broot_bytes <= | 2220 | if (ifp->if_broot) |
2218 | XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ(ip)); | 2221 | ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= |
2222 | XFS_IFORK_SIZE(ip, whichfork)); | ||
2219 | return; | 2223 | return; |
2220 | } | 2224 | } |
2221 | 2225 | ||
@@ -2526,9 +2530,8 @@ xfs_iflush_fork( | |||
2526 | if ((iip->ili_fields & brootflag[whichfork]) && | 2530 | if ((iip->ili_fields & brootflag[whichfork]) && |
2527 | (ifp->if_broot_bytes > 0)) { | 2531 | (ifp->if_broot_bytes > 0)) { |
2528 | ASSERT(ifp->if_broot != NULL); | 2532 | ASSERT(ifp->if_broot != NULL); |
2529 | ASSERT(ifp->if_broot_bytes <= | 2533 | ASSERT(XFS_BMAP_BMDR_SPACE(ifp->if_broot) <= |
2530 | (XFS_IFORK_SIZE(ip, whichfork) + | 2534 | XFS_IFORK_SIZE(ip, whichfork)); |
2531 | XFS_BROOT_SIZE_ADJ(ip))); | ||
2532 | xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, | 2535 | xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, |
2533 | (xfs_bmdr_block_t *)cp, | 2536 | (xfs_bmdr_block_t *)cp, |
2534 | XFS_DFORK_SIZE(dip, mp, whichfork)); | 2537 | XFS_DFORK_SIZE(dip, mp, whichfork)); |
@@ -2886,12 +2889,18 @@ xfs_iflush_int( | |||
2886 | __func__, ip->i_ino, ip->i_d.di_forkoff, ip); | 2889 | __func__, ip->i_ino, ip->i_d.di_forkoff, ip); |
2887 | goto corrupt_out; | 2890 | goto corrupt_out; |
2888 | } | 2891 | } |
2892 | |||
2889 | /* | 2893 | /* |
2890 | * bump the flush iteration count, used to detect flushes which | 2894 | * Inode item log recovery for v1/v2 inodes are dependent on the |
2891 | * postdate a log record during recovery. This is redundant as we now | 2895 | * di_flushiter count for correct sequencing. We bump the flush |
2892 | * log every change and hence this can't happen. Still, it doesn't hurt. | 2896 | * iteration count so we can detect flushes which postdate a log record |
2897 | * during recovery. This is redundant as we now log every change and | ||
2898 | * hence this can't happen but we need to still do it to ensure | ||
2899 | * backwards compatibility with old kernels that predate logging all | ||
2900 | * inode changes. | ||
2893 | */ | 2901 | */ |
2894 | ip->i_d.di_flushiter++; | 2902 | if (ip->i_d.di_version < 3) |
2903 | ip->i_d.di_flushiter++; | ||
2895 | 2904 | ||
2896 | /* | 2905 | /* |
2897 | * Copy the dirty parts of the inode into the on-disk | 2906 | * Copy the dirty parts of the inode into the on-disk |