diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-21 18:15:47 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-21 18:15:47 -0700 |
commit | c22fc16d172fba4d19ffd8f2aa8fe67edba63895 (patch) | |
tree | d88b1becfcf2cdccfe0c9429da0c9a998b879d3c /fs | |
parent | c1fecabecc352e40f99e6c5d7a74b8fcdfb38ae1 (diff) | |
parent | 7d5e049e72c4cb933b557c78cbd63285dd8102ce (diff) |
Merge tag 'xfs-4.19-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Darrick Wong:
- Fix an uninitialized variable
- Don't use obviously garbage AG header counters to calculate
transaction reservations
- Trigger icount recalculation on bad icount when mounting
* tag 'xfs-4.19-merge-7' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
iomap: fix WARN_ON_ONCE on uninitialized variable
xfs: sanity check ag header values in xrep_calc_ag_resblks
xfs: recalculate summary counters at mount time if icount is bad
Diffstat (limited to 'fs')
-rw-r--r-- | fs/iomap.c | 2 | ||||
-rw-r--r-- | fs/xfs/scrub/repair.c | 46 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 1 |
3 files changed, 29 insertions, 20 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index 009071e73bc0..74762b1ec233 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -290,7 +290,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data, sector_t sector; if (iomap->type == IOMAP_INLINE) { - WARN_ON_ONCE(poff); + WARN_ON_ONCE(pos); iomap_read_inline_data(inode, page, iomap); return PAGE_SIZE; } diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 17cf48564390..9f08dd9bf1d5 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -195,8 +195,8 @@ xrep_calc_ag_resblks( struct xfs_scrub_metadata *sm = sc->sm; struct xfs_perag *pag; struct xfs_buf *bp; - xfs_agino_t icount = 0; - xfs_extlen_t aglen = 0; + xfs_agino_t icount = NULLAGINO; + xfs_extlen_t aglen = NULLAGBLOCK; xfs_extlen_t usedlen; xfs_extlen_t freelen; xfs_extlen_t bnobt_sz; @@ -208,20 +208,14 @@ xrep_calc_ag_resblks( if (!(sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)) return 0; - /* Use in-core counters if possible. */ pag = xfs_perag_get(mp, sm->sm_agno); - if (pag->pagi_init) + if (pag->pagi_init) { + /* Use in-core icount if possible. */ icount = pag->pagi_count; - - /* - * Otherwise try to get the actual counters from disk; if not, make - * some worst case assumptions. - */ - if (icount == 0) { + } else { + /* Try to get the actual counters from disk. */ error = xfs_ialloc_read_agi(mp, NULL, sm->sm_agno, &bp); - if (error) { - icount = mp->m_sb.sb_agblocks / mp->m_sb.sb_inopblock; - } else { + if (!error) { icount = pag->pagi_count; xfs_buf_relse(bp); } @@ -229,18 +223,32 @@ xrep_calc_ag_resblks( /* Now grab the block counters from the AGF. */ error = xfs_alloc_read_agf(mp, NULL, sm->sm_agno, 0, &bp); - if (error) { - aglen = mp->m_sb.sb_agblocks; - freelen = aglen; - usedlen = aglen; - } else { + if (!error) { aglen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_length); - freelen = pag->pagf_freeblks; + freelen = be32_to_cpu(XFS_BUF_TO_AGF(bp)->agf_freeblks); usedlen = aglen - freelen; xfs_buf_relse(bp); } xfs_perag_put(pag); + /* If the icount is impossible, make some worst-case assumptions. */ + if (icount == NULLAGINO || + !xfs_verify_agino(mp, sm->sm_agno, icount)) { + xfs_agino_t first, last; + + xfs_agino_range(mp, sm->sm_agno, &first, &last); + icount = last - first + 1; + } + + /* If the block counts are impossible, make worst-case assumptions. */ + if (aglen == NULLAGBLOCK || + aglen != xfs_ag_block_count(mp, sm->sm_agno) || + freelen >= aglen) { + aglen = xfs_ag_block_count(mp, sm->sm_agno); + freelen = aglen; + usedlen = aglen; + } + trace_xrep_calc_ag_resblks(mp, sm->sm_agno, icount, aglen, freelen, usedlen); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 99db27d6ac8a..02d15098dbee 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -637,6 +637,7 @@ xfs_check_summary_counts( */ if (XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && (mp->m_sb.sb_fdblocks > mp->m_sb.sb_dblocks || + !xfs_verify_icount(mp, mp->m_sb.sb_icount) || mp->m_sb.sb_ifree > mp->m_sb.sb_icount)) mp->m_flags |= XFS_MOUNT_BAD_SUMMARY; |