summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-08-22 04:15:47 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-22 04:15:47 +0300
commitc22fc16d172fba4d19ffd8f2aa8fe67edba63895 (patch)
treed88b1becfcf2cdccfe0c9429da0c9a998b879d3c /fs
parentc1fecabecc352e40f99e6c5d7a74b8fcdfb38ae1 (diff)
parent7d5e049e72c4cb933b557c78cbd63285dd8102ce (diff)
downloadlinux-c22fc16d172fba4d19ffd8f2aa8fe67edba63895.tar.xz
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.c2
-rw-r--r--fs/xfs/scrub/repair.c46
-rw-r--r--fs/xfs/xfs_mount.c1
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;