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
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to