struct inode *inode = file_inode(filp);
        const int credits = 2; /* superblock and inode for ext4_orphan_del() */
        handle_t *handle;
+       struct ext4_iloc iloc;
        int err = 0;
-       int err2;
 
-       if (desc != NULL) {
-               /* Succeeded; write the verity descriptor. */
-               err = ext4_write_verity_descriptor(inode, desc, desc_size,
-                                                  merkle_tree_size);
-
-               /* Write all pages before clearing VERITY_IN_PROGRESS. */
-               if (!err)
-                       err = filemap_write_and_wait(inode->i_mapping);
-       }
+       /*
+        * If an error already occurred (which fs/verity/ signals by passing
+        * desc == NULL), then only clean-up is needed.
+        */
+       if (desc == NULL)
+               goto cleanup;
 
-       /* If we failed, truncate anything we wrote past i_size. */
-       if (desc == NULL || err)
-               ext4_truncate(inode);
+       /* Append the verity descriptor. */
+       err = ext4_write_verity_descriptor(inode, desc, desc_size,
+                                          merkle_tree_size);
+       if (err)
+               goto cleanup;
 
        /*
-        * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and
-        * deleting the inode from the orphan list, even if something failed.
-        * If everything succeeded, we'll also set the verity bit in the same
-        * transaction.
+        * Write all pages (both data and verity metadata).  Note that this must
+        * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages
+        * beyond i_size won't be written properly.  For crash consistency, this
+        * also must happen before the verity inode flag gets persisted.
         */
+       err = filemap_write_and_wait(inode->i_mapping);
+       if (err)
+               goto cleanup;
 
-       ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
+       /*
+        * Finally, set the verity inode flag and remove the inode from the
+        * orphan list (in a single transaction).
+        */
 
        handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
        if (IS_ERR(handle)) {
-               ext4_orphan_del(NULL, inode);
-               return PTR_ERR(handle);
+               err = PTR_ERR(handle);
+               goto cleanup;
        }
 
-       err2 = ext4_orphan_del(handle, inode);
-       if (err2)
-               goto out_stop;
+       err = ext4_orphan_del(handle, inode);
+       if (err)
+               goto stop_and_cleanup;
 
-       if (desc != NULL && !err) {
-               struct ext4_iloc iloc;
+       err = ext4_reserve_inode_write(handle, inode, &iloc);
+       if (err)
+               goto stop_and_cleanup;
 
-               err = ext4_reserve_inode_write(handle, inode, &iloc);
-               if (err)
-                       goto out_stop;
-               ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
-               ext4_set_inode_flags(inode, false);
-               err = ext4_mark_iloc_dirty(handle, inode, &iloc);
-       }
-out_stop:
+       ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
+       ext4_set_inode_flags(inode, false);
+       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+       if (err)
+               goto stop_and_cleanup;
+
+       ext4_journal_stop(handle);
+
+       ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
+       return 0;
+
+stop_and_cleanup:
        ext4_journal_stop(handle);
-       return err ?: err2;
+cleanup:
+       /*
+        * Verity failed to be enabled, so clean up by truncating any verity
+        * metadata that was written beyond i_size (both from cache and from
+        * disk), removing the inode from the orphan list (if it wasn't done
+        * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS.
+        */
+       truncate_inode_pages(inode->i_mapping, inode->i_size);
+       ext4_truncate(inode);
+       ext4_orphan_del(NULL, inode);
+       ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
+       return err;
 }
 
 static int ext4_get_verity_descriptor_location(struct inode *inode,