diff options
Diffstat (limited to 'fs/xfs/libxfs')
| -rw-r--r-- | fs/xfs/libxfs/xfs_sb.c | 40 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_sb.h | 5 | 
2 files changed, 34 insertions, 11 deletions
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index d991eec05436..73a4b895de67 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -530,7 +530,8 @@ xfs_validate_sb_common(  	}  	if (!xfs_validate_stripe_geometry(mp, XFS_FSB_TO_B(mp, sbp->sb_unit), -			XFS_FSB_TO_B(mp, sbp->sb_width), 0, false)) +			XFS_FSB_TO_B(mp, sbp->sb_width), 0, +			xfs_buf_daddr(bp) == XFS_SB_DADDR, false))  		return -EFSCORRUPTED;  	/* @@ -1323,8 +1324,10 @@ xfs_sb_get_secondary(  }  /* - * sunit, swidth, sectorsize(optional with 0) should be all in bytes, - * so users won't be confused by values in error messages. + * sunit, swidth, sectorsize(optional with 0) should be all in bytes, so users + * won't be confused by values in error messages.  This function returns false + * if the stripe geometry is invalid and the caller is unable to repair the + * stripe configuration later in the mount process.   */  bool  xfs_validate_stripe_geometry( @@ -1332,20 +1335,21 @@ xfs_validate_stripe_geometry(  	__s64			sunit,  	__s64			swidth,  	int			sectorsize, +	bool			may_repair,  	bool			silent)  {  	if (swidth > INT_MAX) {  		if (!silent)  			xfs_notice(mp,  "stripe width (%lld) is too large", swidth); -		return false; +		goto check_override;  	}  	if (sunit > swidth) {  		if (!silent)  			xfs_notice(mp,  "stripe unit (%lld) is larger than the stripe width (%lld)", sunit, swidth); -		return false; +		goto check_override;  	}  	if (sectorsize && (int)sunit % sectorsize) { @@ -1353,21 +1357,21 @@ xfs_validate_stripe_geometry(  			xfs_notice(mp,  "stripe unit (%lld) must be a multiple of the sector size (%d)",  				   sunit, sectorsize); -		return false; +		goto check_override;  	}  	if (sunit && !swidth) {  		if (!silent)  			xfs_notice(mp,  "invalid stripe unit (%lld) and stripe width of 0", sunit); -		return false; +		goto check_override;  	}  	if (!sunit && swidth) {  		if (!silent)  			xfs_notice(mp,  "invalid stripe width (%lld) and stripe unit of 0", swidth); -		return false; +		goto check_override;  	}  	if (sunit && (int)swidth % (int)sunit) { @@ -1375,9 +1379,27 @@ xfs_validate_stripe_geometry(  			xfs_notice(mp,  "stripe width (%lld) must be a multiple of the stripe unit (%lld)",  				   swidth, sunit); -		return false; +		goto check_override;  	}  	return true; + +check_override: +	if (!may_repair) +		return false; +	/* +	 * During mount, mp->m_dalign will not be set unless the sunit mount +	 * option was set. If it was set, ignore the bad stripe alignment values +	 * and allow the validation and overwrite later in the mount process to +	 * attempt to overwrite the bad stripe alignment values with the values +	 * supplied by mount options. +	 */ +	if (!mp->m_dalign) +		return false; +	if (!silent) +		xfs_notice(mp, +"Will try to correct with specified mount options sunit (%d) and swidth (%d)", +			BBTOB(mp->m_dalign), BBTOB(mp->m_swidth)); +	return true;  }  /* diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index 2e8e8d63d4eb..37b1ed1bc209 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -35,8 +35,9 @@ extern int	xfs_sb_get_secondary(struct xfs_mount *mp,  				struct xfs_trans *tp, xfs_agnumber_t agno,  				struct xfs_buf **bpp); -extern bool	xfs_validate_stripe_geometry(struct xfs_mount *mp, -		__s64 sunit, __s64 swidth, int sectorsize, bool silent); +bool	xfs_validate_stripe_geometry(struct xfs_mount *mp, +		__s64 sunit, __s64 swidth, int sectorsize, bool may_repair, +		bool silent);  uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);  |