aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2018-10-18 02:18:58 -0400
committerDave Chinner <david@fromorbit.com>2018-10-18 02:18:58 -0400
commitdaa79baefc47293c753fed191d722f7ef605a303 (patch)
tree34f39a4c2079bf783847dae0dd11d4012c1587d2 /fs/xfs
parent97e5a6e6dc44b9ea660f85de084f6e38cb5cf39c (diff)
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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c21
-rw-r--r--fs/xfs/libxfs/xfs_format.h8
-rw-r--r--fs/xfs/libxfs/xfs_sb.c5
-rw-r--r--fs/xfs/scrub/scrub.c13
-rw-r--r--fs/xfs/xfs_bmap_util.c51
-rw-r--r--fs/xfs/xfs_ioctl.c8
6 files changed, 12 insertions, 94 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index a47670332326..da6b768664e3 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -4081,8 +4081,7 @@ xfs_bmapi_allocate(
4081 * extents to real extents when we're about to write the data. 4081 * extents to real extents when we're about to write the data.
4082 */ 4082 */
4083 if ((!bma->wasdel || (bma->flags & XFS_BMAPI_COWFORK)) && 4083 if ((!bma->wasdel || (bma->flags & XFS_BMAPI_COWFORK)) &&
4084 (bma->flags & XFS_BMAPI_PREALLOC) && 4084 (bma->flags & XFS_BMAPI_PREALLOC))
4085 xfs_sb_version_hasextflgbit(&mp->m_sb))
4086 bma->got.br_state = XFS_EXT_UNWRITTEN; 4085 bma->got.br_state = XFS_EXT_UNWRITTEN;
4087 4086
4088 if (bma->wasdel) 4087 if (bma->wasdel)
@@ -5245,8 +5244,7 @@ __xfs_bunmapi(
5245 * unmapping part of it. But we can't really 5244 * unmapping part of it. But we can't really
5246 * get rid of part of a realtime extent. 5245 * get rid of part of a realtime extent.
5247 */ 5246 */
5248 if (del.br_state == XFS_EXT_UNWRITTEN || 5247 if (del.br_state == XFS_EXT_UNWRITTEN) {
5249 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5250 /* 5248 /*
5251 * This piece is unwritten, or we're not 5249 * This piece is unwritten, or we're not
5252 * using unwritten extents. Skip over it. 5250 * using unwritten extents. Skip over it.
@@ -5296,10 +5294,9 @@ __xfs_bunmapi(
5296 del.br_blockcount -= mod; 5294 del.br_blockcount -= mod;
5297 del.br_startoff += mod; 5295 del.br_startoff += mod;
5298 del.br_startblock += mod; 5296 del.br_startblock += mod;
5299 } else if ((del.br_startoff == start && 5297 } else if (del.br_startoff == start &&
5300 (del.br_state == XFS_EXT_UNWRITTEN || 5298 (del.br_state == XFS_EXT_UNWRITTEN ||
5301 tp->t_blk_res == 0)) || 5299 tp->t_blk_res == 0)) {
5302 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
5303 /* 5300 /*
5304 * Can't make it unwritten. There isn't 5301 * Can't make it unwritten. There isn't
5305 * a full extent here so just skip it. 5302 * a full extent here so just skip it.
@@ -6114,11 +6111,7 @@ xfs_bmap_validate_extent(
6114 XFS_FSB_TO_AGNO(mp, endfsb)) 6111 XFS_FSB_TO_AGNO(mp, endfsb))
6115 return __this_address; 6112 return __this_address;
6116 } 6113 }
6117 if (irec->br_state != XFS_EXT_NORM) { 6114 if (irec->br_state != XFS_EXT_NORM && whichfork != XFS_DATA_FORK)
6118 if (whichfork != XFS_DATA_FORK) 6115 return __this_address;
6119 return __this_address;
6120 if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
6121 return __this_address;
6122 }
6123 return NULL; 6116 return NULL;
6124} 6117}
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index afbe336600e1..9995d5ae380b 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -287,6 +287,8 @@ static inline bool xfs_sb_good_v4_features(struct xfs_sb *sbp)
287{ 287{
288 if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT)) 288 if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
289 return false; 289 return false;
290 if (!(sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT))
291 return false;
290 292
291 /* check for unknown features in the fs */ 293 /* check for unknown features in the fs */
292 if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) || 294 if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
@@ -357,12 +359,6 @@ static inline bool xfs_sb_version_haslogv2(struct xfs_sb *sbp)
357 (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT); 359 (sbp->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
358} 360}
359 361
360static inline bool xfs_sb_version_hasextflgbit(struct xfs_sb *sbp)
361{
362 return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 ||
363 (sbp->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
364}
365
366static inline bool xfs_sb_version_hassector(struct xfs_sb *sbp) 362static inline bool xfs_sb_version_hassector(struct xfs_sb *sbp)
367{ 363{
368 return (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT); 364 return (sbp->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 081f46e30556..b5a82acd7dfe 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -1115,7 +1115,8 @@ xfs_fs_geometry(
1115 1115
1116 geo->version = XFS_FSOP_GEOM_VERSION; 1116 geo->version = XFS_FSOP_GEOM_VERSION;
1117 geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK | 1117 geo->flags = XFS_FSOP_GEOM_FLAGS_NLINK |
1118 XFS_FSOP_GEOM_FLAGS_DIRV2; 1118 XFS_FSOP_GEOM_FLAGS_DIRV2 |
1119 XFS_FSOP_GEOM_FLAGS_EXTFLG;
1119 if (xfs_sb_version_hasattr(sbp)) 1120 if (xfs_sb_version_hasattr(sbp))
1120 geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR; 1121 geo->flags |= XFS_FSOP_GEOM_FLAGS_ATTR;
1121 if (xfs_sb_version_hasquota(sbp)) 1122 if (xfs_sb_version_hasquota(sbp))
@@ -1124,8 +1125,6 @@ xfs_fs_geometry(
1124 geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN; 1125 geo->flags |= XFS_FSOP_GEOM_FLAGS_IALIGN;
1125 if (xfs_sb_version_hasdalign(sbp)) 1126 if (xfs_sb_version_hasdalign(sbp))
1126 geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN; 1127 geo->flags |= XFS_FSOP_GEOM_FLAGS_DALIGN;
1127 if (xfs_sb_version_hasextflgbit(sbp))
1128 geo->flags |= XFS_FSOP_GEOM_FLAGS_EXTFLG;
1129 if (xfs_sb_version_hassector(sbp)) 1128 if (xfs_sb_version_hassector(sbp))
1130 geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR; 1129 geo->flags |= XFS_FSOP_GEOM_FLAGS_SECTOR;
1131 if (xfs_sb_version_hasasciici(sbp)) 1130 if (xfs_sb_version_hasasciici(sbp))
diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c
index 4bfae1e61d30..1b2344d00525 100644
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -412,19 +412,6 @@ xchk_validate_inputs(
412 goto out; 412 goto out;
413 } 413 }
414 414
415 error = -EOPNOTSUPP;
416 /*
417 * We won't scrub any filesystem that doesn't have the ability
418 * to record unwritten extents. The option was made default in
419 * 2003, removed from mkfs in 2007, and cannot be disabled in
420 * v5, so if we find a filesystem without this flag it's either
421 * really old or totally unsupported. Avoid it either way.
422 * We also don't support v1-v3 filesystems, which aren't
423 * mountable.
424 */
425 if (!xfs_sb_version_hasextflgbit(&mp->m_sb))
426 goto out;
427
428 /* 415 /*
429 * We only want to repair read-write v5+ filesystems. Defer the check 416 * We only want to repair read-write v5+ filesystems. Defer the check
430 * for ops->repair until after our scrub confirms that we need to 417 * for ops->repair until after our scrub confirms that we need to
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 6de8d90041ff..416524f6ba69 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1043,44 +1043,6 @@ out_trans_cancel:
1043} 1043}
1044 1044
1045static int 1045static int
1046xfs_adjust_extent_unmap_boundaries(
1047 struct xfs_inode *ip,
1048 xfs_fileoff_t *startoffset_fsb,
1049 xfs_fileoff_t *endoffset_fsb)
1050{
1051 struct xfs_mount *mp = ip->i_mount;
1052 struct xfs_bmbt_irec imap;
1053 int nimap, error;
1054 xfs_extlen_t mod = 0;
1055
1056 nimap = 1;
1057 error = xfs_bmapi_read(ip, *startoffset_fsb, 1, &imap, &nimap, 0);
1058 if (error)
1059 return error;
1060
1061 if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
1062 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1063 div_u64_rem(imap.br_startblock, mp->m_sb.sb_rextsize, &mod);
1064 if (mod)
1065 *startoffset_fsb += mp->m_sb.sb_rextsize - mod;
1066 }
1067
1068 nimap = 1;
1069 error = xfs_bmapi_read(ip, *endoffset_fsb - 1, 1, &imap, &nimap, 0);
1070 if (error)
1071 return error;
1072
1073 if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
1074 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1075 mod++;
1076 if (mod && mod != mp->m_sb.sb_rextsize)
1077 *endoffset_fsb -= mod;
1078 }
1079
1080 return 0;
1081}
1082
1083static int
1084xfs_flush_unmap_range( 1046xfs_flush_unmap_range(
1085 struct xfs_inode *ip, 1047 struct xfs_inode *ip,
1086 xfs_off_t offset, 1048 xfs_off_t offset,
@@ -1133,19 +1095,8 @@ xfs_free_file_space(
1133 endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len); 1095 endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len);
1134 1096
1135 /* 1097 /*
1136 * Need to zero the stuff we're not freeing, on disk. If it's a RT file 1098 * Need to zero the stuff we're not freeing, on disk.
1137 * and we can't use unwritten extents then we actually need to ensure
1138 * to zero the whole extent, otherwise we just need to take of block
1139 * boundaries, and xfs_bunmapi will handle the rest.
1140 */ 1099 */
1141 if (XFS_IS_REALTIME_INODE(ip) &&
1142 !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
1143 error = xfs_adjust_extent_unmap_boundaries(ip, &startoffset_fsb,
1144 &endoffset_fsb);
1145 if (error)
1146 return error;
1147 }
1148
1149 if (endoffset_fsb > startoffset_fsb) { 1100 if (endoffset_fsb > startoffset_fsb) {
1150 while (!done) { 1101 while (!done) {
1151 error = xfs_unmap_extent(ip, startoffset_fsb, 1102 error = xfs_unmap_extent(ip, startoffset_fsb,
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0ef5ece5634c..6e2c08f30f60 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -604,14 +604,6 @@ xfs_ioc_space(
604 uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; 604 uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
605 int error; 605 int error;
606 606
607 /*
608 * Only allow the sys admin to reserve space unless
609 * unwritten extents are enabled.
610 */
611 if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
612 !capable(CAP_SYS_ADMIN))
613 return -EPERM;
614
615 if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) 607 if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
616 return -EPERM; 608 return -EPERM;
617 609