tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master head: 274d7803837da78dfc911bcda0d593412676fc20 commit: 521502e8682f049895d2023dc50c23ebb9d68e07 [11738/11993] ext4: factor out ext4_fc_get_tl() config: powerpc-randconfig-s031-20220925 compiler: powerpc-linux-gcc (GCC) 12.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-39-gce1a6720-dirty # https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=521502e8682f049895d2023dc50c23ebb9d68e07 git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git git fetch --no-tags linux-next master git checkout 521502e8682f049895d2023dc50c23ebb9d68e07 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=powerpc SHELL=/bin/bash fs/ext4/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot sparse warnings: (new ones prefixed by >>) >> fs/ext4/fast_commit.c:1522:42: sparse: sparse: incorrect type in initializer (different base types) @@ expected int tag @@ got restricted __le16 [usertype] fc_tag @@ fs/ext4/fast_commit.c:1522:42: sparse: expected int tag fs/ext4/fast_commit.c:1522:42: sparse: got restricted __le16 [usertype] fc_tag >> fs/ext4/fast_commit.c:1547:23: sparse: sparse: restricted __le16 degrades to integer >> fs/ext4/fast_commit.c:2039:17: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned short [usertype] tag @@ got restricted __le16 [addressable] [usertype] fc_tag @@ fs/ext4/fast_commit.c:2039:17: sparse: expected unsigned short [usertype] tag fs/ext4/fast_commit.c:2039:17: sparse: got restricted __le16 [addressable] [usertype] fc_tag fs/ext4/fast_commit.c:2061:58: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2094:58: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2041:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2036:51: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2159:17: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned short [usertype] tag @@ got restricted __le16 [addressable] [usertype] fc_tag @@ fs/ext4/fast_commit.c:2159:17: sparse: expected unsigned short [usertype] tag fs/ext4/fast_commit.c:2159:17: sparse: got restricted __le16 [addressable] [usertype] fc_tag >> fs/ext4/fast_commit.c:2182:48: sparse: sparse: incorrect type in argument 4 (different base types) @@ expected int priv1 @@ got restricted __le16 [addressable] [usertype] fc_len @@ fs/ext4/fast_commit.c:2182:48: sparse: expected int priv1 fs/ext4/fast_commit.c:2182:48: sparse: got restricted __le16 [addressable] [usertype] fc_len fs/ext4/fast_commit.c:2186:51: sparse: sparse: incorrect type in argument 4 (different base types) @@ expected int priv1 @@ got restricted __le16 [addressable] [usertype] fc_len @@ fs/ext4/fast_commit.c:2186:51: sparse: expected int priv1 fs/ext4/fast_commit.c:2186:51: sparse: got restricted __le16 [addressable] [usertype] fc_len >> fs/ext4/fast_commit.c:2193:52: sparse: sparse: incorrect type in argument 2 (different base types) @@ expected int tag @@ got restricted __le16 [addressable] [usertype] fc_tag @@ fs/ext4/fast_commit.c:2193:52: sparse: expected int tag fs/ext4/fast_commit.c:2193:52: sparse: got restricted __le16 [addressable] [usertype] fc_tag fs/ext4/fast_commit.c:2193:66: sparse: sparse: incorrect type in argument 4 (different base types) @@ expected int priv1 @@ got restricted __le16 [addressable] [usertype] fc_len @@ fs/ext4/fast_commit.c:2193:66: sparse: expected int priv1 fs/ext4/fast_commit.c:2193:66: sparse: got restricted __le16 [addressable] [usertype] fc_len fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2161:27: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:2150:51: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:1350:29: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:1350:29: sparse: sparse: restricted __le16 degrades to integer fs/ext4/fast_commit.c:1350:29: sparse: sparse: restricted __le16 degrades to integer >> fs/ext4/fast_commit.c:1356:20: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] fc_len @@ got unsigned short [usertype] @@ fs/ext4/fast_commit.c:1356:20: sparse: expected restricted __le16 [usertype] fc_len fs/ext4/fast_commit.c:1356:20: sparse: got unsigned short [usertype] >> fs/ext4/fast_commit.c:1357:20: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] fc_tag @@ got unsigned short [usertype] @@ fs/ext4/fast_commit.c:1357:20: sparse: expected restricted __le16 [usertype] fc_tag fs/ext4/fast_commit.c:1357:20: sparse: got unsigned short [usertype] >> fs/ext4/fast_commit.c:1356:20: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] fc_len @@ got unsigned short [usertype] @@ fs/ext4/fast_commit.c:1356:20: sparse: expected restricted __le16 [usertype] fc_len fs/ext4/fast_commit.c:1356:20: sparse: got unsigned short [usertype] >> fs/ext4/fast_commit.c:1357:20: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le16 [usertype] fc_tag @@ got unsigned short [usertype] @@ fs/ext4/fast_commit.c:1357:20: sparse: expected restricted __le16 [usertype] fc_tag fs/ext4/fast_commit.c:1357:20: sparse: got unsigned short [usertype] vim +1522 fs/ext4/fast_commit.c 1352 1353 static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val) 1354 { 1355 memcpy(tl, val, EXT4_FC_TAG_BASE_LEN); > 1356 tl->fc_len = le16_to_cpu(tl->fc_len); > 1357 tl->fc_tag = le16_to_cpu(tl->fc_tag); 1358 } 1359 1360 /* Unlink replay function */ 1361 static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl, 1362 u8 *val) 1363 { 1364 struct inode *inode, *old_parent; 1365 struct qstr entry; 1366 struct dentry_info_args darg; 1367 int ret = 0; 1368 1369 tl_to_darg(&darg, tl, val); 1370 1371 trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino, 1372 darg.parent_ino, darg.dname_len); 1373 1374 entry.name = darg.dname; 1375 entry.len = darg.dname_len; 1376 inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); 1377 1378 if (IS_ERR(inode)) { 1379 ext4_debug("Inode %d not found", darg.ino); 1380 return 0; 1381 } 1382 1383 old_parent = ext4_iget(sb, darg.parent_ino, 1384 EXT4_IGET_NORMAL); 1385 if (IS_ERR(old_parent)) { 1386 ext4_debug("Dir with inode %d not found", darg.parent_ino); 1387 iput(inode); 1388 return 0; 1389 } 1390 1391 ret = __ext4_unlink(NULL, old_parent, &entry, inode); 1392 /* -ENOENT ok coz it might not exist anymore. */ 1393 if (ret == -ENOENT) 1394 ret = 0; 1395 iput(old_parent); 1396 iput(inode); 1397 return ret; 1398 } 1399 1400 static int ext4_fc_replay_link_internal(struct super_block *sb, 1401 struct dentry_info_args *darg, 1402 struct inode *inode) 1403 { 1404 struct inode *dir = NULL; 1405 struct dentry *dentry_dir = NULL, *dentry_inode = NULL; 1406 struct qstr qstr_dname = QSTR_INIT(darg->dname, darg->dname_len); 1407 int ret = 0; 1408 1409 dir = ext4_iget(sb, darg->parent_ino, EXT4_IGET_NORMAL); 1410 if (IS_ERR(dir)) { 1411 ext4_debug("Dir with inode %d not found.", darg->parent_ino); 1412 dir = NULL; 1413 goto out; 1414 } 1415 1416 dentry_dir = d_obtain_alias(dir); 1417 if (IS_ERR(dentry_dir)) { 1418 ext4_debug("Failed to obtain dentry"); 1419 dentry_dir = NULL; 1420 goto out; 1421 } 1422 1423 dentry_inode = d_alloc(dentry_dir, &qstr_dname); 1424 if (!dentry_inode) { 1425 ext4_debug("Inode dentry not created."); 1426 ret = -ENOMEM; 1427 goto out; 1428 } 1429 1430 ret = __ext4_link(dir, inode, dentry_inode); 1431 /* 1432 * It's possible that link already existed since data blocks 1433 * for the dir in question got persisted before we crashed OR 1434 * we replayed this tag and crashed before the entire replay 1435 * could complete. 1436 */ 1437 if (ret && ret != -EEXIST) { 1438 ext4_debug("Failed to link\n"); 1439 goto out; 1440 } 1441 1442 ret = 0; 1443 out: 1444 if (dentry_dir) { 1445 d_drop(dentry_dir); 1446 dput(dentry_dir); 1447 } else if (dir) { 1448 iput(dir); 1449 } 1450 if (dentry_inode) { 1451 d_drop(dentry_inode); 1452 dput(dentry_inode); 1453 } 1454 1455 return ret; 1456 } 1457 1458 /* Link replay function */ 1459 static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl, 1460 u8 *val) 1461 { 1462 struct inode *inode; 1463 struct dentry_info_args darg; 1464 int ret = 0; 1465 1466 tl_to_darg(&darg, tl, val); 1467 trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino, 1468 darg.parent_ino, darg.dname_len); 1469 1470 inode = ext4_iget(sb, darg.ino, EXT4_IGET_NORMAL); 1471 if (IS_ERR(inode)) { 1472 ext4_debug("Inode not found."); 1473 return 0; 1474 } 1475 1476 ret = ext4_fc_replay_link_internal(sb, &darg, inode); 1477 iput(inode); 1478 return ret; 1479 } 1480 1481 /* 1482 * Record all the modified inodes during replay. We use this later to setup 1483 * block bitmaps correctly. 1484 */ 1485 static int ext4_fc_record_modified_inode(struct super_block *sb, int ino) 1486 { 1487 struct ext4_fc_replay_state *state; 1488 int i; 1489 1490 state = &EXT4_SB(sb)->s_fc_replay_state; 1491 for (i = 0; i < state->fc_modified_inodes_used; i++) 1492 if (state->fc_modified_inodes[i] == ino) 1493 return 0; 1494 if (state->fc_modified_inodes_used == state->fc_modified_inodes_size) { 1495 int *fc_modified_inodes; 1496 1497 fc_modified_inodes = krealloc(state->fc_modified_inodes, 1498 sizeof(int) * (state->fc_modified_inodes_size + 1499 EXT4_FC_REPLAY_REALLOC_INCREMENT), 1500 GFP_KERNEL); 1501 if (!fc_modified_inodes) 1502 return -ENOMEM; 1503 state->fc_modified_inodes = fc_modified_inodes; 1504 state->fc_modified_inodes_size += 1505 EXT4_FC_REPLAY_REALLOC_INCREMENT; 1506 } 1507 state->fc_modified_inodes[state->fc_modified_inodes_used++] = ino; 1508 return 0; 1509 } 1510 1511 /* 1512 * Inode replay function 1513 */ 1514 static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl, 1515 u8 *val) 1516 { 1517 struct ext4_fc_inode fc_inode; 1518 struct ext4_inode *raw_inode; 1519 struct ext4_inode *raw_fc_inode; 1520 struct inode *inode = NULL; 1521 struct ext4_iloc iloc; > 1522 int inode_len, ino, ret, tag = tl->fc_tag; 1523 struct ext4_extent_header *eh; 1524 1525 memcpy(&fc_inode, val, sizeof(fc_inode)); 1526 1527 ino = le32_to_cpu(fc_inode.fc_ino); 1528 trace_ext4_fc_replay(sb, tag, ino, 0, 0); 1529 1530 inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); 1531 if (!IS_ERR(inode)) { 1532 ext4_ext_clear_bb(inode); 1533 iput(inode); 1534 } 1535 inode = NULL; 1536 1537 ret = ext4_fc_record_modified_inode(sb, ino); 1538 if (ret) 1539 goto out; 1540 1541 raw_fc_inode = (struct ext4_inode *) 1542 (val + offsetof(struct ext4_fc_inode, fc_raw_inode)); 1543 ret = ext4_get_fc_inode_loc(sb, ino, &iloc); 1544 if (ret) 1545 goto out; 1546 > 1547 inode_len = tl->fc_len - sizeof(struct ext4_fc_inode); 1548 raw_inode = ext4_raw_inode(&iloc); 1549 1550 memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block)); 1551 memcpy(&raw_inode->i_generation, &raw_fc_inode->i_generation, 1552 inode_len - offsetof(struct ext4_inode, i_generation)); 1553 if (le32_to_cpu(raw_inode->i_flags) & EXT4_EXTENTS_FL) { 1554 eh = (struct ext4_extent_header *)(&raw_inode->i_block[0]); 1555 if (eh->eh_magic != EXT4_EXT_MAGIC) { 1556 memset(eh, 0, sizeof(*eh)); 1557 eh->eh_magic = EXT4_EXT_MAGIC; 1558 eh->eh_max = cpu_to_le16( 1559 (sizeof(raw_inode->i_block) - 1560 sizeof(struct ext4_extent_header)) 1561 / sizeof(struct ext4_extent)); 1562 } 1563 } else if (le32_to_cpu(raw_inode->i_flags) & EXT4_INLINE_DATA_FL) { 1564 memcpy(raw_inode->i_block, raw_fc_inode->i_block, 1565 sizeof(raw_inode->i_block)); 1566 } 1567 1568 /* Immediately update the inode on disk. */ 1569 ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh); 1570 if (ret) 1571 goto out; 1572 ret = sync_dirty_buffer(iloc.bh); 1573 if (ret) 1574 goto out; 1575 ret = ext4_mark_inode_used(sb, ino); 1576 if (ret) 1577 goto out; 1578 1579 /* Given that we just wrote the inode on disk, this SHOULD succeed. */ 1580 inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL); 1581 if (IS_ERR(inode)) { 1582 ext4_debug("Inode not found."); 1583 return -EFSCORRUPTED; 1584 } 1585 1586 /* 1587 * Our allocator could have made different decisions than before 1588 * crashing. This should be fixed but until then, we calculate 1589 * the number of blocks the inode. 1590 */ 1591 if (!ext4_test_inode_flag(inode, EXT4_INODE_INLINE_DATA)) 1592 ext4_ext_replay_set_iblocks(inode); 1593 1594 inode->i_generation = le32_to_cpu(ext4_raw_inode(&iloc)->i_generation); 1595 ext4_reset_inode_seed(inode); 1596 1597 ext4_inode_csum_set(inode, ext4_raw_inode(&iloc), EXT4_I(inode)); 1598 ret = ext4_handle_dirty_metadata(NULL, NULL, iloc.bh); 1599 sync_dirty_buffer(iloc.bh); 1600 brelse(iloc.bh); 1601 out: 1602 iput(inode); 1603 if (!ret) 1604 blkdev_issue_flush(sb->s_bdev); 1605 1606 return 0; 1607 } 1608 -- 0-DAY CI Kernel Test Service https://01.org/lkp