Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'xfs-fixes-6.18-rc5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Carlos Maiolino:
"This contain fixes for the RT and zoned allocator, and a few fixes for
atomic writes"

* tag 'xfs-fixes-6.18-rc5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: free xfs_busy_extents structure when no RT extents are queued
xfs: fix zone selection in xfs_select_open_zone_mru
xfs: fix a rtgroup leak when xfs_init_zone fails
xfs: fix various problems in xfs_atomic_write_cow_iomap_begin
xfs: fix delalloc write failures in software-provided atomic writes

+76 -16
+3 -1
fs/xfs/xfs_discard.c
··· 726 726 break; 727 727 } 728 728 729 - if (!tr.queued) 729 + if (!tr.queued) { 730 + kfree(tr.extents); 730 731 break; 732 + } 731 733 732 734 /* 733 735 * We hand the extent list to the discard function here so the
+69 -13
fs/xfs/xfs_iomap.c
··· 1091 1091 }; 1092 1092 #endif /* CONFIG_XFS_RT */ 1093 1093 1094 + #ifdef DEBUG 1095 + static void 1096 + xfs_check_atomic_cow_conversion( 1097 + struct xfs_inode *ip, 1098 + xfs_fileoff_t offset_fsb, 1099 + xfs_filblks_t count_fsb, 1100 + const struct xfs_bmbt_irec *cmap) 1101 + { 1102 + struct xfs_iext_cursor icur; 1103 + struct xfs_bmbt_irec cmap2 = { }; 1104 + 1105 + if (xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap2)) 1106 + xfs_trim_extent(&cmap2, offset_fsb, count_fsb); 1107 + 1108 + ASSERT(cmap2.br_startoff == cmap->br_startoff); 1109 + ASSERT(cmap2.br_blockcount == cmap->br_blockcount); 1110 + ASSERT(cmap2.br_startblock == cmap->br_startblock); 1111 + ASSERT(cmap2.br_state == cmap->br_state); 1112 + } 1113 + #else 1114 + # define xfs_check_atomic_cow_conversion(...) ((void)0) 1115 + #endif 1116 + 1094 1117 static int 1095 1118 xfs_atomic_write_cow_iomap_begin( 1096 1119 struct inode *inode, ··· 1125 1102 { 1126 1103 struct xfs_inode *ip = XFS_I(inode); 1127 1104 struct xfs_mount *mp = ip->i_mount; 1128 - const xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 1129 - xfs_fileoff_t end_fsb = xfs_iomap_end_fsb(mp, offset, length); 1130 - xfs_filblks_t count_fsb = end_fsb - offset_fsb; 1105 + const xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset); 1106 + const xfs_fileoff_t end_fsb = XFS_B_TO_FSB(mp, offset + length); 1107 + const xfs_filblks_t count_fsb = end_fsb - offset_fsb; 1108 + xfs_filblks_t hole_count_fsb; 1131 1109 int nmaps = 1; 1132 1110 xfs_filblks_t resaligned; 1133 1111 struct xfs_bmbt_irec cmap; ··· 1154 1130 return -EAGAIN; 1155 1131 1156 1132 trace_xfs_iomap_atomic_write_cow(ip, offset, length); 1157 - 1133 + retry: 1158 1134 xfs_ilock(ip, XFS_ILOCK_EXCL); 1159 1135 1160 1136 if (!ip->i_cowfp) { ··· 1165 1141 if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap)) 1166 1142 cmap.br_startoff = end_fsb; 1167 1143 if (cmap.br_startoff <= offset_fsb) { 1144 + if (isnullstartblock(cmap.br_startblock)) 1145 + goto convert_delay; 1146 + 1147 + /* 1148 + * cmap could extend outside the write range due to previous 1149 + * speculative preallocations. We must trim cmap to the write 1150 + * range because the cow fork treats written mappings to mean 1151 + * "write in progress". 1152 + */ 1168 1153 xfs_trim_extent(&cmap, offset_fsb, count_fsb); 1169 1154 goto found; 1170 1155 } 1171 1156 1172 - end_fsb = cmap.br_startoff; 1173 - count_fsb = end_fsb - offset_fsb; 1157 + hole_count_fsb = cmap.br_startoff - offset_fsb; 1174 1158 1175 - resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb, 1159 + resaligned = xfs_aligned_fsb_count(offset_fsb, hole_count_fsb, 1176 1160 xfs_get_cowextsz_hint(ip)); 1177 1161 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1178 1162 ··· 1201 1169 if (!xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &cmap)) 1202 1170 cmap.br_startoff = end_fsb; 1203 1171 if (cmap.br_startoff <= offset_fsb) { 1204 - xfs_trim_extent(&cmap, offset_fsb, count_fsb); 1205 1172 xfs_trans_cancel(tp); 1173 + if (isnullstartblock(cmap.br_startblock)) 1174 + goto convert_delay; 1175 + xfs_trim_extent(&cmap, offset_fsb, count_fsb); 1206 1176 goto found; 1207 1177 } 1208 1178 ··· 1216 1182 * atomic writes to that same range will be aligned (and don't require 1217 1183 * this COW-based method). 1218 1184 */ 1219 - error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, 1185 + error = xfs_bmapi_write(tp, ip, offset_fsb, hole_count_fsb, 1220 1186 XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC | 1221 1187 XFS_BMAPI_EXTSZALIGN, 0, &cmap, &nmaps); 1222 1188 if (error) { ··· 1229 1195 if (error) 1230 1196 goto out_unlock; 1231 1197 1198 + /* 1199 + * cmap could map more blocks than the range we passed into bmapi_write 1200 + * because of EXTSZALIGN or adjacent pre-existing unwritten mappings 1201 + * that were merged. Trim cmap to the original write range so that we 1202 + * don't convert more than we were asked to do for this write. 1203 + */ 1204 + xfs_trim_extent(&cmap, offset_fsb, count_fsb); 1205 + 1232 1206 found: 1233 1207 if (cmap.br_state != XFS_EXT_NORM) { 1234 - error = xfs_reflink_convert_cow_locked(ip, offset_fsb, 1235 - count_fsb); 1208 + error = xfs_reflink_convert_cow_locked(ip, cmap.br_startoff, 1209 + cmap.br_blockcount); 1236 1210 if (error) 1237 1211 goto out_unlock; 1238 1212 cmap.br_state = XFS_EXT_NORM; 1213 + xfs_check_atomic_cow_conversion(ip, offset_fsb, count_fsb, 1214 + &cmap); 1239 1215 } 1240 1216 1241 - length = XFS_FSB_TO_B(mp, cmap.br_startoff + cmap.br_blockcount); 1242 - trace_xfs_iomap_found(ip, offset, length - offset, XFS_COW_FORK, &cmap); 1217 + trace_xfs_iomap_found(ip, offset, length, XFS_COW_FORK, &cmap); 1243 1218 seq = xfs_iomap_inode_sequence(ip, IOMAP_F_SHARED); 1244 1219 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1245 1220 return xfs_bmbt_to_iomap(ip, iomap, &cmap, flags, IOMAP_F_SHARED, seq); 1246 1221 1222 + convert_delay: 1223 + xfs_iunlock(ip, XFS_ILOCK_EXCL); 1224 + error = xfs_bmapi_convert_delalloc(ip, XFS_COW_FORK, offset, iomap, 1225 + NULL); 1226 + if (error) 1227 + return error; 1228 + 1229 + /* 1230 + * Try the lookup again, because the delalloc conversion might have 1231 + * turned the COW mapping into unwritten, but we need it to be in 1232 + * written state. 1233 + */ 1234 + goto retry; 1247 1235 out_unlock: 1248 1236 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1249 1237 return error;
+4 -2
fs/xfs/xfs_zone_alloc.c
··· 615 615 lockdep_assert_held(&zi->zi_open_zones_lock); 616 616 617 617 list_for_each_entry_reverse(oz, &zi->zi_open_zones, oz_entry) 618 - if (xfs_try_use_zone(zi, file_hint, oz, false)) 618 + if (xfs_try_use_zone(zi, file_hint, oz, XFS_ZONE_ALLOC_OK)) 619 619 return oz; 620 620 621 621 cond_resched_lock(&zi->zi_open_zones_lock); ··· 1249 1249 1250 1250 while ((rtg = xfs_rtgroup_next(mp, rtg))) { 1251 1251 error = xfs_init_zone(&iz, rtg, NULL); 1252 - if (error) 1252 + if (error) { 1253 + xfs_rtgroup_rele(rtg); 1253 1254 goto out_free_zone_info; 1255 + } 1254 1256 } 1255 1257 } 1256 1258