tree:
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git
repair-metadata-atomically
head: 03560ddd3fbb967b10047a3d7a31266990f797cf
commit: a616ac921a9590b684f485c1111726d28b135bb9 [214/227] xfs: create deferred log items
for extent swapping
config: mips-randconfig-r036-20200520 (attached as .config)
compiler: mips64el-linux-gcc (GCC) 9.3.0
reproduce:
wget
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O
~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout a616ac921a9590b684f485c1111726d28b135bb9
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
fs/xfs/libxfs/xfs_swapext.c: In function 'xfs_swapext_finish_one':
> fs/xfs/libxfs/xfs_swapext.c:306:37: warning: suggest braces
around empty body in an 'if' statement [-Wempty-body]
306 |
XFS_TRANS_DQ_BCOUNT, ip1_delta);
| ^
fs/xfs/libxfs/xfs_swapext.c:309:37: warning: suggest braces around empty body in an
'if' statement [-Wempty-body]
309 | XFS_TRANS_DQ_BCOUNT, ip2_delta);
| ^
vim +/if +306 fs/xfs/libxfs/xfs_swapext.c
208
209 /* Finish one extent swap, possibly log more. */
210 int
211 xfs_swapext_finish_one(
212 struct xfs_trans *tp,
213 struct xfs_swapext_intent *sxi)
214 {
215 struct xfs_bmbt_irec irec1, irec2;
216 int whichfork;
217 int nimaps;
218 int bmap_flags;
219 int error;
220
221 whichfork = (sxi->sxi_flags & XFS_SWAP_EXTENT_ATTR_FORK) ?
222 XFS_ATTR_FORK : XFS_DATA_FORK;
223 bmap_flags = xfs_bmapi_aflag(whichfork);
224
225 while (sxi->sxi_blockcount > 0) {
226 int64_t ip1_delta = 0, ip2_delta = 0;
227
228 /* Read extent from the first file */
229 nimaps = 1;
230 error = xfs_bmapi_read(sxi->sxi_ip1, sxi->sxi_startoff1,
231 sxi->sxi_blockcount, &irec1, &nimaps,
232 bmap_flags);
233 if (error)
234 return error;
235 if (nimaps != 1 ||
236 irec1.br_startblock == DELAYSTARTBLOCK ||
237 irec1.br_startoff != sxi->sxi_startoff1) {
238 /*
239 * We should never get no mapping or a delalloc extent
240 * or something that doesn't match what we asked for,
241 * since the caller flushed both inodes and we hold the
242 * ILOCKs for both inodes.
243 */
244 ASSERT(0);
245 return -EINVAL;
246 }
247
248 /* Read extent from the second file */
249 nimaps = 1;
250 error = xfs_bmapi_read(sxi->sxi_ip2, sxi->sxi_startoff2,
251 irec1.br_blockcount, &irec2, &nimaps,
252 bmap_flags);
253 if (error)
254 return error;
255 if (nimaps != 1 ||
256 irec2.br_startblock == DELAYSTARTBLOCK ||
257 irec2.br_startoff != sxi->sxi_startoff2) {
258 /*
259 * We should never get no mapping or a delalloc extent
260 * or something that doesn't match what we asked for,
261 * since the caller flushed both inodes and we hold the
262 * ILOCKs for both inodes.
263 */
264 ASSERT(0);
265 return -EINVAL;
266 }
267
268 /*
269 * We can only swap as many blocks as the smaller of the two
270 * extent maps.
271 */
272 irec1.br_blockcount = min(irec1.br_blockcount,
273 irec2.br_blockcount);
274
275 trace_xfs_swapext_extent1(sxi->sxi_ip1, &irec1);
276 trace_xfs_swapext_extent2(sxi->sxi_ip2, &irec2);
277
278 /*
279 * Two extents mapped to the same physical block must not have
280 * different states; that's filesystem corruption. Move on to
281 * the next extent if they're both holes or both the same
282 * physical extent.
283 */
284 if (irec1.br_startblock == irec2.br_startblock) {
285 if (irec1.br_state != irec2.br_state)
286 return -EFSCORRUPTED;
287
288 sxi->sxi_startoff1 += irec1.br_blockcount;
289 sxi->sxi_startoff2 += irec1.br_blockcount;
290 sxi->sxi_blockcount -= irec1.br_blockcount;
291 continue;
292 }
293
294 /* Update quota accounting. */
295 if (xfs_bmap_is_mapped_extent(&irec1)) {
296 ip1_delta -= irec1.br_blockcount;
297 ip2_delta += irec1.br_blockcount;
298 }
299 if (xfs_bmap_is_mapped_extent(&irec2)) {
300 ip1_delta += irec2.br_blockcount;
301 ip2_delta -= irec2.br_blockcount;
302 }
303
304 if (ip1_delta)
305 xfs_trans_mod_dquot_byino(tp, sxi->sxi_ip1,
306 XFS_TRANS_DQ_BCOUNT, ip1_delta);
307 if
(ip2_delta)
308 xfs_trans_mod_dquot_byino(tp, sxi->sxi_ip2,
309 XFS_TRANS_DQ_BCOUNT, ip2_delta);
310
311 /* Remove both mappings. */
312 xfs_bmap_unmap_extent(tp, sxi->sxi_ip1, whichfork, &irec1);
313 xfs_bmap_unmap_extent(tp, sxi->sxi_ip2, whichfork, &irec2);
314
315 /*
316 * Re-add both mappings. We swap the file offsets between the
317 * two maps and add the opposite map, which has the effect of
318 * filling the logical offsets we just unmapped, but with with
319 * the physical mapping information swapped.
320 */
321 swap(irec1.br_startoff, irec2.br_startoff);
322 xfs_bmap_map_extent(tp, sxi->sxi_ip1, whichfork, &irec2);
323 xfs_bmap_map_extent(tp, sxi->sxi_ip2, whichfork, &irec1);
324
325 /* Make sure we're not mapping extents past EOF. */
326 if (whichfork == XFS_DATA_FORK) {
327 xfs_swapext_update_size(tp, sxi->sxi_ip1, &irec2,
328 sxi->sxi_isize1);
329 xfs_swapext_update_size(tp, sxi->sxi_ip2, &irec1,
330 sxi->sxi_isize2);
331 }
332
333 /*
334 * Advance our cursor and exit. The caller (either defer ops
335 * or log recovery) will log the SXD item, and if *blockcount
336 * is nonzero, it will log a new SXI item for the remainder
337 * and call us back.
338 */
339 sxi->sxi_startoff1 += irec1.br_blockcount;
340 sxi->sxi_startoff2 += irec1.br_blockcount;
341 sxi->sxi_blockcount -= irec1.br_blockcount;
342 break;
343 }
344
345 /*
346 * If we've reached the end of the remap operation and the caller
347 * wanted us to exchange the sizes, do that now.
348 */
349 if (sxi->sxi_blockcount == 0 &&
350 (sxi->sxi_flags & XFS_SWAP_EXTENT_SET_SIZES)) {
351 sxi->sxi_ip1->i_d.di_size = sxi->sxi_isize1;
352 sxi->sxi_ip2->i_d.di_size = sxi->sxi_isize2;
353 xfs_trans_log_inode(tp, sxi->sxi_ip1, XFS_ILOG_CORE);
354 xfs_trans_log_inode(tp, sxi->sxi_ip2, XFS_ILOG_CORE);
355 }
356
357 if (xfs_swapext_has_more_work(sxi))
358 trace_xfs_swapext_defer(tp->t_mountp, sxi);
359 return 0;
360 }
361
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org