xfs: remove suport for filesystems without unwritten extent flag
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 <hch@lst.de> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
97e5a6e6dc
commit
daa79baefc
@ -4081,8 +4081,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)
|
||||
@ -5245,8 +5244,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.
|
||||
@ -5296,10 +5294,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.
|
||||
@ -6114,11 +6111,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1115,7 +1115,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))
|
||||
@ -1124,8 +1125,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))
|
||||
|
@ -412,19 +412,6 @@ xchk_validate_inputs(
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = -EOPNOTSUPP;
|
||||
/*
|
||||
* We won't scrub any filesystem that doesn't have the ability
|
||||
* to record unwritten extents. The option was made default in
|
||||
* 2003, removed from mkfs in 2007, and cannot be disabled in
|
||||
* v5, so if we find a filesystem without this flag it's either
|
||||
* really old or totally unsupported. Avoid it either way.
|
||||
* We also don't support v1-v3 filesystems, which aren't
|
||||
* mountable.
|
||||
*/
|
||||
if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* We only want to repair read-write v5+ filesystems. Defer the check
|
||||
* for ops->repair until after our scrub confirms that we need to
|
||||
|
@ -1042,44 +1042,6 @@ out_trans_cancel:
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
static int
|
||||
xfs_adjust_extent_unmap_boundaries(
|
||||
struct xfs_inode *ip,
|
||||
xfs_fileoff_t *startoffset_fsb,
|
||||
xfs_fileoff_t *endoffset_fsb)
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
struct xfs_bmbt_irec imap;
|
||||
int nimap, error;
|
||||
xfs_extlen_t mod = 0;
|
||||
|
||||
nimap = 1;
|
||||
error = xfs_bmapi_read(ip, *startoffset_fsb, 1, &imap, &nimap, 0);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
|
||||
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
|
||||
div_u64_rem(imap.br_startblock, mp->m_sb.sb_rextsize, &mod);
|
||||
if (mod)
|
||||
*startoffset_fsb += mp->m_sb.sb_rextsize - mod;
|
||||
}
|
||||
|
||||
nimap = 1;
|
||||
error = xfs_bmapi_read(ip, *endoffset_fsb - 1, 1, &imap, &nimap, 0);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
|
||||
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
|
||||
mod++;
|
||||
if (mod && mod != mp->m_sb.sb_rextsize)
|
||||
*endoffset_fsb -= mod;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
xfs_flush_unmap_range(
|
||||
struct xfs_inode *ip,
|
||||
@ -1133,19 +1095,8 @@ xfs_free_file_space(
|
||||
endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len);
|
||||
|
||||
/*
|
||||
* Need to zero the stuff we're not freeing, on disk. If it's a RT file
|
||||
* and we can't use unwritten extents then we actually need to ensure
|
||||
* to zero the whole extent, otherwise we just need to take of block
|
||||
* boundaries, and xfs_bunmapi will handle the rest.
|
||||
* Need to zero the stuff we're not freeing, on disk.
|
||||
*/
|
||||
if (XFS_IS_REALTIME_INODE(ip) &&
|
||||
!xfs_sb_version_hasextflgbit(&mp->m_sb)) {
|
||||
error = xfs_adjust_extent_unmap_boundaries(ip, &startoffset_fsb,
|
||||
&endoffset_fsb);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (endoffset_fsb > startoffset_fsb) {
|
||||
while (!done) {
|
||||
error = xfs_unmap_extent(ip, startoffset_fsb,
|
||||
|
@ -604,14 +604,6 @@ xfs_ioc_space(
|
||||
uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Only allow the sys admin to reserve space unless
|
||||
* unwritten extents are enabled.
|
||||
*/
|
||||
if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
|
||||
!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
|
||||
return -EPERM;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user