From b7fdeb4debfd9b992ec9a02e725c78923449c9b0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 9 Nov 2018 16:59:17 -0600 Subject: [PATCH] xfs: remove suport for filesystems without unwritten extent flag Source kernel commit: daa79baefc47293c753fed191d722f7ef605a303 The option to enable unwritten extents was made default in 2003, removed from mkfs in 2007, and cannot be disabled in v5. We also rely on it for a lot of common functionality, so filesystems without it will run a completely untested and buggy code path. Enabling the support also is a simple bit flip using xfs_db, so legacy file systems can still be brought forward. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner Signed-off-by: Eric Sandeen --- db/sb.c | 6 ++++-- libxfs/xfs_bmap.c | 21 +++++++-------------- libxfs/xfs_format.h | 8 ++------ libxfs/xfs_sb.c | 5 ++--- repair/dinode.c | 18 +----------------- repair/sb.c | 7 ++----- repair/versions.c | 5 +---- 7 files changed, 19 insertions(+), 51 deletions(-) diff --git a/db/sb.c b/db/sb.c index f676eea3c..5059b261c 100644 --- a/db/sb.c +++ b/db/sb.c @@ -658,7 +658,8 @@ version_string( strcat(s, ",DALIGN"); if (xfs_sb_version_haslogv2(sbp)) strcat(s, ",LOGV2"); - if (xfs_sb_version_hasextflgbit(sbp)) + /* This feature is required now as well */ + if (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT) strcat(s, ",EXTFLG"); if (xfs_sb_version_hassector(sbp)) strcat(s, ",SECTOR"); @@ -725,7 +726,8 @@ version_f( version = 0x0034 | XFS_SB_VERSION_EXTFLGBIT; break; case XFS_SB_VERSION_4: - if (xfs_sb_version_hasextflgbit(&mp->m_sb)) + if (mp->m_sb.sb_versionnum & + XFS_SB_VERSION_EXTFLGBIT) dbprintf( _("unwritten extents flag is already enabled\n")); else diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index cf4e9637d..c17d3515c 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -4072,8 +4072,7 @@ xfs_bmapi_allocate( * extents to real extents when we're about to write the data. */ if ((!bma->wasdel || (bma->flags & XFS_BMAPI_COWFORK)) && - (bma->flags & XFS_BMAPI_PREALLOC) && - xfs_sb_version_hasextflgbit(&mp->m_sb)) + (bma->flags & XFS_BMAPI_PREALLOC)) bma->got.br_state = XFS_EXT_UNWRITTEN; if (bma->wasdel) @@ -5236,8 +5235,7 @@ __xfs_bunmapi( * unmapping part of it. But we can't really * get rid of part of a realtime extent. */ - if (del.br_state == XFS_EXT_UNWRITTEN || - !xfs_sb_version_hasextflgbit(&mp->m_sb)) { + if (del.br_state == XFS_EXT_UNWRITTEN) { /* * This piece is unwritten, or we're not * using unwritten extents. Skip over it. @@ -5287,10 +5285,9 @@ __xfs_bunmapi( del.br_blockcount -= mod; del.br_startoff += mod; del.br_startblock += mod; - } else if ((del.br_startoff == start && - (del.br_state == XFS_EXT_UNWRITTEN || - tp->t_blk_res == 0)) || - !xfs_sb_version_hasextflgbit(&mp->m_sb)) { + } else if (del.br_startoff == start && + (del.br_state == XFS_EXT_UNWRITTEN || + tp->t_blk_res == 0)) { /* * Can't make it unwritten. There isn't * a full extent here so just skip it. @@ -6105,11 +6102,7 @@ xfs_bmap_validate_extent( XFS_FSB_TO_AGNO(mp, endfsb)) return __this_address; } - if (irec->br_state != XFS_EXT_NORM) { - if (whichfork != XFS_DATA_FORK) - return __this_address; - if (!xfs_sb_version_hasextflgbit(&mp->m_sb)) - return __this_address; - } + if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK) + return __this_address; return NULL; } diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index da87afa7e..0d3422167 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -287,6 +287,8 @@ static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp) { if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)) return false; + if (!(sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT)) + return false; /* check for unknown features in the fs */ if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) || @@ -357,12 +359,6 @@ static inline bool xfs_sb_version_haslogv2(struct xfs_sb *sbp) (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); } -static inline bool xfs_sb_version_hasextflgbit(struct xfs_sb *sbp) -{ - return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 || - (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT); -} - static inline bool xfs_sb_version_hassector(struct xfs_sb *sbp) { return (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT); diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index 93584fac2..cee77a67f 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -1092,7 +1092,8 @@ xfs_fs_geometry( geo->version = XFS_FSOP_GEOM_VERSION; geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK | - XFS_FSOP_GEOM_FLAGS_DIRV2; + XFS_FSOP_GEOM_FLAGS_DIRV2 | + XFS_FSOP_GEOM_FLAGS_EXTFLG; if (xfs_sb_version_hasattr(sbp)) geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR; if (xfs_sb_version_hasquota(sbp)) @@ -1101,8 +1102,6 @@ xfs_fs_geometry( geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN; if (xfs_sb_version_hasdalign(sbp)) geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN; - if (xfs_sb_version_hasextflgbit(sbp)) - geo->flags |= XFS_FSOP_GEOM_FLAGS_EXTFLG; if (xfs_sb_version_hassector(sbp)) geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR; if (xfs_sb_version_hasasciici(sbp)) diff --git a/repair/dinode.c b/repair/dinode.c index f466e7784..f670bf87c 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -338,21 +338,6 @@ _("inode %" PRIu64 " - bad rt extent overflows - start %" PRIu64 ", " return 1; } - /* - * verify that the blocks listed in the record - * are multiples of an extent - */ - if (xfs_sb_version_hasextflgbit(&mp->m_sb) == 0 && - (irec->br_startblock % mp->m_sb.sb_rextsize != 0 || - irec->br_blockcount % mp->m_sb.sb_rextsize != 0)) { - do_warn( -_("malformed rt inode extent [%" PRIu64 " %" PRIu64 "] (fs rtext size = %u)\n"), - irec->br_startblock, - irec->br_blockcount, - mp->m_sb.sb_rextsize); - return 1; - } - /* * set the appropriate number of extents * this iterates block by block, this can be optimised using extents @@ -360,8 +345,7 @@ _("malformed rt inode extent [%" PRIu64 " %" PRIu64 "] (fs rtext size = %u)\n"), for (b = irec->br_startblock; b < irec->br_startblock + irec->br_blockcount; b += mp->m_sb.sb_rextsize) { ext = (xfs_rtblock_t) b / mp->m_sb.sb_rextsize; - pwe = xfs_sb_version_hasextflgbit(&mp->m_sb) && - irec->br_state == XFS_EXT_UNWRITTEN && + pwe = irec->br_state == XFS_EXT_UNWRITTEN && (b % mp->m_sb.sb_rextsize != 0); if (check_dups == 1) { diff --git a/repair/sb.c b/repair/sb.c index 059422c56..119bf2190 100644 --- a/repair/sb.c +++ b/repair/sb.c @@ -57,8 +57,7 @@ copy_sb(xfs_sb_t *source, xfs_sb_t *dest) */ if (xfs_sb_version_hasdalign(source)) dest->sb_versionnum |= XFS_SB_VERSION_DALIGNBIT; - if (xfs_sb_version_hasextflgbit(source)) - dest->sb_versionnum |= XFS_SB_VERSION_EXTFLGBIT; + dest->sb_versionnum |= XFS_SB_VERSION_EXTFLGBIT; /* * these are all supposed to be zero or will get reset anyway @@ -683,9 +682,7 @@ get_sb_geometry(fs_geometry_t *geo, xfs_sb_t *sbp) if (xfs_sb_version_hasdalign(sbp)) geo->sb_salignbit = 1; - if (xfs_sb_version_hasextflgbit(sbp)) - geo->sb_extflgbit = 1; - + geo->sb_extflgbit = 1; geo->sb_fully_zeroed = 1; } diff --git a/repair/versions.c b/repair/versions.c index 8fad41fa3..4c44b4e79 100644 --- a/repair/versions.c +++ b/repair/versions.c @@ -102,7 +102,7 @@ parse_sb_version(xfs_sb_t *sb) fs_aligned_inodes = 0; fs_sb_feature_bits = 0; fs_ino_alignment = 0; - fs_has_extflgbit = 0; + fs_has_extflgbit = 1; have_uquotino = 0; have_gquotino = 0; have_pquotino = 0; @@ -116,9 +116,6 @@ parse_sb_version(xfs_sb_t *sb) * ok, check to make sure that the sb isn't newer * than we are */ - if (xfs_sb_version_hasextflgbit(sb)) - fs_has_extflgbit = 1; - if (!xfs_sb_good_version(sb)) { do_warn(_("WARNING: unknown superblock version %d\n"), XFS_SB_VERSION_NUM(sb)); -- 2.39.2