@@ -31,6 +31,7 @@
#include "xfs_rtbitmap.h"
#include "xfs_rtgroup.h"
#include "xfs_zone_alloc.h"
+#include <linux/fsverity.h>
/* Kernel only BMAP related definitions and functions */
@@ -553,6 +554,15 @@ xfs_can_free_eofblocks(
if (last_fsb <= end_fsb)
return false;
+ /*
+ * Don't clean fsverity inodes as they already have been cleaned up and
+ * are read-only. Skip inodes which have merkle tree being built, the
+ * merkle tree is written beyond EOF
+ */
+ if (fsverity_active(VFS_IC(ip)) ||
+ xfs_iflags_test(ip, XFS_VERITY_CONSTRUCTION))
+ return false;
+
/*
* Check if there is an post-EOF extent to free. If there are any
* delalloc blocks attached to the inode (data fork delalloc
@@ -579,6 +589,9 @@ xfs_free_eofblocks(
struct xfs_trans *tp;
struct xfs_mount *mp = ip->i_mount;
int error;
+ int bmapi_flags = XFS_BMAPI_NODISCARD;
+ bool has_verity =
+ ip->i_diflags2 & XFS_DIFLAG2_VERITY;
/* Attach the dquots to the inode up front. */
error = xfs_qm_dqattach(ip);
@@ -593,15 +606,20 @@ xfs_free_eofblocks(
*
* Note that this means we also leave speculative preallocations in
* place for preallocated files.
+ *
+ * Clean up delalloc reservations for fsverity too as those won't be
+ * used
*/
- if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) {
+ if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND) ||
+ has_verity) {
if (ip->i_delayed_blks) {
xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK,
round_up(XFS_ISIZE(ip), mp->m_sb.sb_blocksize),
LLONG_MAX, NULL);
}
xfs_inode_clear_eofblocks_tag(ip);
- return 0;
+ if (!has_verity)
+ return 0;
}
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
@@ -613,6 +631,13 @@ xfs_free_eofblocks(
xfs_ilock(ip, XFS_ILOCK_EXCL);
xfs_trans_ijoin(tp, ip, 0);
+ /*
+ * While fs-verity writes metadata after EOF, it can leave unwritten
+ * preallocations. Clear all that out.
+ */
+ if (has_verity)
+ bmapi_flags |= XFS_BMAPI_UNWRITTEN;
+
/*
* Do not update the on-disk file size. If we update the on-disk file
* size and then the system crashes before the contents of the file are
@@ -620,7 +645,7 @@ xfs_free_eofblocks(
* bug).
*/
error = xfs_itruncate_extents_flags(&tp, ip, XFS_DATA_FORK,
- XFS_ISIZE(ip), XFS_BMAPI_NODISCARD);
+ XFS_ISIZE(ip), bmapi_flags);
if (error)
goto err_cancel;