tree:
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git
repair-metadata-atomically
head: 03560ddd3fbb967b10047a3d7a31266990f797cf
commit: 81599d970c97632eaef01cc6f164edac4b649d4a [206/227] xfs: actually account for quota
changes in xfs_swap_extents
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 81599d970c97632eaef01cc6f164edac4b649d4a
# 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/xfs_bmap_util.c: In function 'xfs_swap_extent_rmap':
fs/xfs/xfs_bmap_util.c:1439:38: warning: suggest braces around empty body in an
'if' statement [-Wempty-body]
1439 | XFS_TRANS_DQ_BCOUNT, tip_delta);
| ^
fs/xfs/xfs_bmap_util.c:1442:37: warning: suggest braces around empty body in an
'if' statement [-Wempty-body]
1442 | XFS_TRANS_DQ_BCOUNT, ip_delta);
| ^
fs/xfs/xfs_bmap_util.c: In function 'xfs_swap_extent_forks':
> fs/xfs/xfs_bmap_util.c:1493:12: warning: variable
'temp_blks' set but not used [-Wunused-but-set-variable]
1493 | int64_t
temp_blks;
| ^~~~~~~~~
vim +/temp_blks +1493 fs/xfs/xfs_bmap_util.c
1352
1353 /*
1354 * Move extents from one file to another, when rmap is enabled.
1355 */
1356 STATIC int
1357 xfs_swap_extent_rmap(
1358 struct xfs_trans **tpp,
1359 struct xfs_inode *ip,
1360 struct xfs_inode *tip)
1361 {
1362 struct xfs_trans *tp = *tpp;
1363 struct xfs_bmbt_irec irec;
1364 struct xfs_bmbt_irec uirec;
1365 struct xfs_bmbt_irec tirec;
1366 xfs_fileoff_t offset_fsb;
1367 xfs_fileoff_t end_fsb;
1368 xfs_filblks_t count_fsb;
1369 int error;
1370 xfs_filblks_t ilen;
1371 xfs_filblks_t rlen;
1372 int nimaps;
1373 uint64_t tip_flags2;
1374
1375 /*
1376 * If the source file has shared blocks, we must flag the donor
1377 * file as having shared blocks so that we get the shared-block
1378 * rmap functions when we go to fix up the rmaps. The flags
1379 * will be switch for reals later.
1380 */
1381 tip_flags2 = tip->i_d.di_flags2;
1382 if (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK)
1383 tip->i_d.di_flags2 |= XFS_DIFLAG2_REFLINK;
1384
1385 offset_fsb = 0;
1386 end_fsb = XFS_B_TO_FSB(ip->i_mount, i_size_read(VFS_I(ip)));
1387 count_fsb = (xfs_filblks_t)(end_fsb - offset_fsb);
1388
1389 while (count_fsb) {
1390 /* Read extent from the donor file */
1391 nimaps = 1;
1392 error = xfs_bmapi_read(tip, offset_fsb, count_fsb, &tirec,
1393 &nimaps, 0);
1394 if (error)
1395 goto out;
1396 ASSERT(nimaps == 1);
1397 ASSERT(tirec.br_startblock != DELAYSTARTBLOCK);
1398
1399 trace_xfs_swap_extent_rmap_remap(tip, &tirec);
1400 ilen = tirec.br_blockcount;
1401
1402 /* Unmap the old blocks in the source file. */
1403 while (tirec.br_blockcount) {
1404 int64_t ip_delta = 0, tip_delta = 0;
1405
1406 ASSERT(tp->t_firstblock == NULLFSBLOCK);
1407 trace_xfs_swap_extent_rmap_remap_piece(tip, &tirec);
1408
1409 /* Read extent from the source file */
1410 nimaps = 1;
1411 error = xfs_bmapi_read(ip, tirec.br_startoff,
1412 tirec.br_blockcount, &irec,
1413 &nimaps, 0);
1414 if (error)
1415 goto out;
1416 ASSERT(nimaps == 1);
1417 ASSERT(tirec.br_startoff == irec.br_startoff);
1418 trace_xfs_swap_extent_rmap_remap_piece(ip, &irec);
1419
1420 /* Trim the extent. */
1421 uirec = tirec;
1422 uirec.br_blockcount = rlen = min_t(xfs_filblks_t,
1423 tirec.br_blockcount,
1424 irec.br_blockcount);
1425 trace_xfs_swap_extent_rmap_remap_piece(tip, &uirec);
1426
1427 /* Update quota accounting. */
1428 if (xfs_bmap_is_mapped_extent(&irec)) {
1429 tip_delta += irec.br_blockcount;
1430 ip_delta -= irec.br_blockcount;
1431 }
1432 if (xfs_bmap_is_mapped_extent(&uirec)) {
1433 tip_delta -= uirec.br_blockcount;
1434 ip_delta += uirec.br_blockcount;
1435 }
1436
1437 if (tip_delta)
1438 xfs_trans_mod_dquot_byino(tp, tip,
1439 XFS_TRANS_DQ_BCOUNT, tip_delta);
1440 if
(ip_delta)
1441 xfs_trans_mod_dquot_byino(tp, ip,
1442 XFS_TRANS_DQ_BCOUNT, ip_delta);
1443
1444 /* Remove the mapping from the donor file. */
1445 xfs_bmap_unmap_extent(tp, tip, &uirec);
1446
1447 /* Remove the mapping from the source file. */
1448 xfs_bmap_unmap_extent(tp, ip, &irec);
1449
1450 /* Map the donor file's blocks into the source file. */
1451 xfs_bmap_map_extent(tp, ip, &uirec);
1452
1453 /* Map the source file's blocks into the donor file. */
1454 xfs_bmap_map_extent(tp, tip, &irec);
1455
1456 error = xfs_defer_finish(tpp);
1457 tp = *tpp;
1458 if (error)
1459 goto out;
1460
1461 tirec.br_startoff += rlen;
1462 if (tirec.br_startblock != HOLESTARTBLOCK &&
1463 tirec.br_startblock != DELAYSTARTBLOCK)
1464 tirec.br_startblock += rlen;
1465 tirec.br_blockcount -= rlen;
1466 }
1467
1468 /* Roll on... */
1469 count_fsb -= ilen;
1470 offset_fsb += ilen;
1471 }
1472
1473 tip->i_d.di_flags2 = tip_flags2;
1474 return 0;
1475
1476 out:
1477 trace_xfs_swap_extent_rmap_error(ip, error, _RET_IP_);
1478 tip->i_d.di_flags2 = tip_flags2;
1479 return error;
1480 }
1481
1482 /* Swap the extents of two files by swapping data forks. */
1483 STATIC int
1484 xfs_swap_extent_forks(
1485 struct xfs_trans *tp,
1486 struct xfs_inode *ip,
1487 struct xfs_inode *tip,
1488 int *src_log_flags,
1489 int *target_log_flags)
1490 {
1491 xfs_filblks_t aforkblks = 0;
1492 xfs_filblks_t taforkblks = 0;
1493 int64_t temp_blks;
1494 xfs_extnum_t junk;
1495 uint64_t tmp;
1496 int error;
1497
1498 /*
1499 * Count the number of extended attribute blocks
1500 */
1501 if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0))
&&
1502 (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
1503 error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &junk,
1504 &aforkblks);
1505 if (error)
1506 return error;
1507 }
1508 if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0))
&&
1509 (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
1510 error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK, &junk,
1511 &taforkblks);
1512 if (error)
1513 return error;
1514 }
1515
1516 /*
1517 * Btree format (v3) inodes have the inode number stamped in the bmbt
1518 * block headers. We can't start changing the bmbt blocks until the
1519 * inode owner change is logged so recovery does the right thing in the
1520 * event of a crash. Set the owner change log flags now and leave the
1521 * bmbt scan as the last step.
1522 */
1523 if (xfs_sb_version_has_v3inode(&ip->i_mount->m_sb)) {
1524 if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE)
1525 (*target_log_flags) |= XFS_ILOG_DOWNER;
1526 if (tip->i_d.di_format == XFS_DINODE_FMT_BTREE)
1527 (*src_log_flags) |= XFS_ILOG_DOWNER;
1528 }
1529
1530 /*
1531 * Swap the data forks of the inodes
1532 */
1533 swap(ip->i_df, tip->i_df);
1534
1535 /* Update quota accounting. */
1536 temp_blks = tip->i_d.di_nblocks - taforkblks + aforkblks;
1537 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT,
1538 temp_blks - ip->i_d.di_nblocks);
1539
1540 temp_blks = ip->i_d.di_nblocks + taforkblks - aforkblks;
1541 xfs_trans_mod_dquot_byino(tp, tip, XFS_TRANS_DQ_BCOUNT,
1542 temp_blks - tip->i_d.di_nblocks);
1543
1544 /*
1545 * Fix the on-disk inode values
1546 */
1547 tmp = (uint64_t)ip->i_d.di_nblocks;
1548 ip->i_d.di_nblocks = tip->i_d.di_nblocks - taforkblks + aforkblks;
1549 tip->i_d.di_nblocks = tmp + taforkblks - aforkblks;
1550
1551 swap(ip->i_d.di_nextents, tip->i_d.di_nextents);
1552 swap(ip->i_d.di_format, tip->i_d.di_format);
1553
1554 /*
1555 * The extents in the source inode could still contain speculative
1556 * preallocation beyond EOF (e.g. the file is open but not modified
1557 * while defrag is in progress). In that case, we need to copy over the
1558 * number of delalloc blocks the data fork in the source inode is
1559 * tracking beyond EOF so that when the fork is truncated away when the
1560 * temporary inode is unlinked we don't underrun the i_delayed_blks
1561 * counter on that inode.
1562 */
1563 ASSERT(tip->i_delayed_blks == 0);
1564 tip->i_delayed_blks = ip->i_delayed_blks;
1565 ip->i_delayed_blks = 0;
1566
1567 switch (ip->i_d.di_format) {
1568 case XFS_DINODE_FMT_EXTENTS:
1569 (*src_log_flags) |= XFS_ILOG_DEXT;
1570 break;
1571 case XFS_DINODE_FMT_BTREE:
1572 ASSERT(!xfs_sb_version_has_v3inode(&ip->i_mount->m_sb) ||
1573 (*src_log_flags & XFS_ILOG_DOWNER));
1574 (*src_log_flags) |= XFS_ILOG_DBROOT;
1575 break;
1576 }
1577
1578 switch (tip->i_d.di_format) {
1579 case XFS_DINODE_FMT_EXTENTS:
1580 (*target_log_flags) |= XFS_ILOG_DEXT;
1581 break;
1582 case XFS_DINODE_FMT_BTREE:
1583 (*target_log_flags) |= XFS_ILOG_DBROOT;
1584 ASSERT(!xfs_sb_version_has_v3inode(&ip->i_mount->m_sb) ||
1585 (*target_log_flags & XFS_ILOG_DOWNER));
1586 break;
1587 }
1588
1589 return 0;
1590 }
1591
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org