tree: https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git vectorized-scrub head: 9716b2732a485c80e6988c5bdf42bd53d337773f commit: 6420f9fb66b09f0f0dfa8c1bd45d010ce76adedc [154/352] vfs: introduce new file range exchange ioctl config: h8300-randconfig-m031-20210702 (attached as .config) compiler: h8300-linux-gcc (GCC) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot smatch warnings: fs/remap_range.c:629 generic_xchg_file_range_checks() warn: unsigned 'fxr->length' is never less than zero. vim +629 fs/remap_range.c 583 584 /* Performs necessary checks before doing a range exchange. */ 585 static int generic_xchg_file_range_checks(struct file *file1, 586 struct file *file2, 587 struct file_xchg_range *fxr, 588 unsigned int blocksize) 589 { 590 struct inode *inode1 = file1->f_mapping->host; 591 struct inode *inode2 = file2->f_mapping->host; 592 uint64_t blkmask = blocksize - 1; 593 int64_t test_len; 594 uint64_t blen; 595 loff_t size1, size2; 596 int ret; 597 598 /* Don't touch certain kinds of inodes */ 599 if (IS_IMMUTABLE(inode1) || IS_IMMUTABLE(inode2)) 600 return -EPERM; 601 if (IS_SWAPFILE(inode1) || IS_SWAPFILE(inode2)) 602 return -ETXTBSY; 603 604 size1 = i_size_read(inode1); 605 size2 = i_size_read(inode2); 606 607 /* Ranges cannot start after EOF. */ 608 if (fxr->file1_offset > size1 || fxr->file2_offset > size2) 609 return -EINVAL; 610 611 /* 612 * If the caller asked for full files, check that the offset/length 613 * values cover all of both files. 614 */ 615 if ((fxr->flags & FILE_XCHG_RANGE_FULL_FILES) && 616 (fxr->file1_offset != 0 || fxr->file2_offset != 0 || 617 fxr->length != size1 || fxr->length != size2)) 618 return -EDOM; 619 620 /* 621 * If the caller said to exchange to EOF, we set the length of the 622 * request large enough to cover everything to the end of both files. 623 */ 624 if (fxr->flags & FILE_XCHG_RANGE_TO_EOF) 625 fxr->length = max_t(int64_t, size1 - fxr->file1_offset, 626 size2 - fxr->file2_offset); 627 628 /* No negative lengths */ > 629 if (fxr->length < 0) 630 return -EINVAL; 631 632 /* The start of both ranges must be aligned to an fs block. */ 633 if (!IS_ALIGNED(fxr->file1_offset, blocksize) || 634 !IS_ALIGNED(fxr->file2_offset, blocksize)) 635 return -EINVAL; 636 637 /* Ensure offsets don't wrap. */ 638 if (fxr->file1_offset + fxr->length < fxr->file1_offset || 639 fxr->file2_offset + fxr->length < fxr->file2_offset) 640 return -EINVAL; 641 642 /* 643 * We require both ranges to be within EOF, unless we're exchanging 644 * to EOF. generic_xchg_range_prep already checked that both 645 * fxr->file1_offset and fxr->file2_offset are within EOF. 646 */ 647 if (!(fxr->flags & FILE_XCHG_RANGE_TO_EOF) && 648 (fxr->file1_offset + fxr->length > size1 || 649 fxr->file2_offset + fxr->length > size2)) 650 return -EINVAL; 651 652 /* 653 * Make sure we don't hit any file size limits. If we hit any size 654 * limits such that test_length was adjusted, we abort the whole 655 * operation. 656 */ 657 test_len = fxr->length; 658 ret = generic_write_check_limits(file2, fxr->file2_offset, &test_len); 659 if (ret) 660 return ret; 661 ret = generic_write_check_limits(file1, fxr->file1_offset, &test_len); 662 if (ret) 663 return ret; 664 if (test_len != fxr->length) 665 return -EINVAL; 666 667 /* 668 * If the user wanted us to exchange up to the infile's EOF, round up 669 * to the next block boundary for this check. Do the same for the 670 * outfile. 671 * 672 * Otherwise, reject the range length if it's not block aligned. We 673 * already confirmed the starting offsets' block alignment. 674 */ 675 if (fxr->file1_offset + fxr->length == size1) 676 blen = ALIGN(size1, blocksize) - fxr->file1_offset; 677 else if (fxr->file2_offset + fxr->length == size2) 678 blen = ALIGN(size2, blocksize) - fxr->file2_offset; 679 else if (!IS_ALIGNED(fxr->length, blocksize)) 680 return -EINVAL; 681 else 682 blen = fxr->length; 683 684 /* Don't allow overlapped exchanges within the same file. */ 685 if (inode1 == inode2 && 686 fxr->file2_offset + blen > fxr->file1_offset && 687 fxr->file1_offset + blen > fxr->file2_offset) 688 return -EINVAL; 689 690 /* If we already failed the freshness check, we're done. */ 691 ret = generic_xchg_file_range_check_fresh(inode2, fxr); 692 if (ret) 693 return ret; 694 695 /* 696 * Ensure that we don't exchange a partial EOF block into the middle of 697 * another file. 698 */ 699 if ((fxr->length & blkmask) == 0) 700 return 0; 701 702 blen = fxr->length; 703 if (fxr->file2_offset + blen < size2) 704 blen &= ~blkmask; 705 706 if (fxr->file1_offset + blen < size1) 707 blen &= ~blkmask; 708 709 return blen == fxr->length ? 0 : -EINVAL; 710 } 711 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org