On 5/2/25 16:15, Dan Carpenter wrote:
> Hello Matthew Wilcox (Oracle),
>
> Commit 5d895f7beae9 ("f2fs: Use folios in do_garbage_collect()") from
> Mar 31, 2025 (linux-next), leads to the following Smatch static
> checker warning:
>
> fs/f2fs/gc.c:1799 do_garbage_collect()
> error: 'sum_folio' dereferencing possible ERR_PTR()
>
> fs/f2fs/gc.c
> 1716 static int do_garbage_collect(struct f2fs_sb_info *sbi,
> 1717 unsigned int start_segno,
> 1718 struct gc_inode_list *gc_list, int
> gc_type,
> 1719 bool force_migrate, bool one_time)
> 1720 {
> 1721 struct blk_plug plug;
> 1722 unsigned int segno = start_segno;
> 1723 unsigned int end_segno = start_segno + SEGS_PER_SEC(sbi);
> 1724 unsigned int sec_end_segno;
> 1725 int seg_freed = 0, migrated = 0;
> 1726 unsigned char type = IS_DATASEG(get_seg_entry(sbi,
> segno)->type) ?
> 1727 SUM_TYPE_DATA :
> SUM_TYPE_NODE;
> 1728 unsigned char data_type = (type == SUM_TYPE_DATA) ? DATA :
> NODE;
> 1729 int submitted = 0;
> 1730
> 1731 if (__is_large_section(sbi)) {
> 1732 sec_end_segno = rounddown(end_segno,
> SEGS_PER_SEC(sbi));
> 1733
> 1734 /*
> 1735 * zone-capacity can be less than zone-size in zoned
> devices,
> 1736 * resulting in less than expected usable segments
> in the zone,
> 1737 * calculate the end segno in the zone which can be
> garbage
> 1738 * collected
> 1739 */
> 1740 if (f2fs_sb_has_blkzoned(sbi))
> 1741 sec_end_segno -= SEGS_PER_SEC(sbi) -
> 1742 f2fs_usable_segs_in_sec(sbi);
> 1743
> 1744 if (gc_type == BG_GC || one_time) {
> 1745 unsigned int window_granularity =
> 1746 sbi->migration_window_granularity;
> 1747
> 1748 if (f2fs_sb_has_blkzoned(sbi) &&
> 1749 !has_enough_free_blocks(sbi,
> 1750
> sbi->gc_thread->boost_zoned_gc_percent))
> 1751 window_granularity *=
> 1752 BOOST_GC_MULTIPLE;
> 1753
> 1754 end_segno = start_segno + window_granularity;
> 1755 }
> 1756
> 1757 if (end_segno > sec_end_segno)
> 1758 end_segno = sec_end_segno;
> 1759 }
> 1760
> 1761 sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type);
> 1762
> 1763 /* readahead multi ssa blocks those have contiguous address
> */
> 1764 if (__is_large_section(sbi))
> 1765 f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno),
> 1766 end_segno - segno, META_SSA,
> true);
> 1767
> 1768 /* reference all summary page */
> 1769 while (segno < end_segno) {
> 1770 struct folio *sum_folio = f2fs_get_sum_folio(sbi,
> segno++);
> 1771 if (IS_ERR(sum_folio)) {
> 1772 int err = PTR_ERR(sum_folio);
> 1773
> 1774 end_segno = segno - 1;
> 1775 for (segno = start_segno; segno < end_segno;
> segno++) {
> 1776 sum_folio =
> filemap_get_folio(META_MAPPING(sbi),
> 1777 GET_SUM_BLOCK(sbi,
> segno));
> 1778 folio_put_refs(sum_folio, 2);
> 1779 }
> 1780 return err;
> 1781 }
> 1782 folio_unlock(sum_folio);
> 1783 }
> 1784
> 1785 blk_start_plug(&plug);
> 1786
> 1787 for (segno = start_segno; segno < end_segno; segno++) {
> 1788 struct f2fs_summary_block *sum;
> 1789
> 1790 /* find segment summary of victim */
> 1791 struct folio *sum_folio =
> filemap_get_folio(META_MAPPING(sbi),
> 1792 GET_SUM_BLOCK(sbi, segno));
>
> Smatch gets a bit confused here and thinks filemap_get_folio() can return
> a lot of different error pointers, but really filemap_get_folio() can only
> return ERR_PTR(-ENOENT). And possibly in this context, it can't even
> return that?
Dan,
It shouldn't fail due to we have grabbed that page in do_garbage_collect() as
below,
and haven't released the reference yet.
> 1768 /* reference all summary page */
> 1769 while (segno < end_segno) {
> 1770 struct folio *sum_folio = f2fs_get_sum_folio(sbi,
> segno++);
>
> One time email warning etc. I could also mark filemap_get_folio() as
> a no fail function to prevent false positives.
So, it doesn't mean filemap_get_folio() never fail, can Smatch detect above
condition to avoid triggering warning?
Thanks,
>
> 1793
> 1794 if (get_valid_blocks(sbi, segno, false) == 0)
> 1795 goto freed;
> 1796 if (gc_type == BG_GC && __is_large_section(sbi) &&
> 1797 migrated >=
> sbi->migration_granularity)
> 1798 goto skip;
> --> 1799 if (!folio_test_uptodate(sum_folio) ||
> ^^^^^^^^^
> Dereferenced here.
>
> 1800 unlikely(f2fs_cp_error(sbi)))
> 1801 goto skip;
> 1802
>
> regards,
> dan carpenter
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel