* [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS
@ 2026-11-04 19:46 Andrey Albershteyn
2026-11-04 19:46 ` [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS Andrey Albershteyn
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
Hi folks,
This patchset lifts two things from filesystems to VFS level:
- No-oping FS_VERITY_FL in SET ioctl()
- runtime fsverity construction flag
The first one fixes BTRFS get-modify-set loop with
FS_IOC_GETFLAGS/SETFLAGS ioctl()s, as it does return fsverity flag but
not mask it out.
Andrey Albershteyn (5):
fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS
fsverity: add I_VERITY_BUILDING inode state flag
btrfs: use I_VERITY_BUILDING instead of private flags
ext4: use I_VERITY_BUILDING instead of private flags
f2fs: use I_VERITY_BUILDING instead of private flags
fs/btrfs/btrfs_inode.h | 7 -------
fs/btrfs/verity.c | 12 ++----------
fs/ext4/ext4.h | 7 -------
fs/ext4/file.c | 2 +-
fs/ext4/inode.c | 17 +++++++++--------
fs/ext4/ioctl.c | 3 +--
fs/ext4/verity.c | 18 +++++-------------
fs/f2fs/data.c | 10 +++++-----
fs/f2fs/f2fs.h | 7 -------
fs/f2fs/verity.c | 15 ++++-----------
fs/file_attr.c | 10 ++++++++++
fs/verity/enable.c | 22 +++++++++++++++++++---
include/linux/fs.h | 6 ++++++
include/linux/fsverity.h | 21 +++++++++++++++++++++
14 files changed, 83 insertions(+), 74 deletions(-)
--
2.54.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
@ 2026-11-04 19:46 ` Andrey Albershteyn
2026-11-04 19:55 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag Andrey Albershteyn
` (4 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4, Boris Burkov, David Sterba
The common use of FS_IOC_GETFLAGS/SETFLAGS is get-modify-set loop.
Filesystems could return verity status with GETFLAGS, attempting to then
pass FS_VERITY_FL to SETFLAGS is not allowed.
The ext4 and f2fs already treat FS_VERITY_FL in the set path as no-op,
however, BTRFS returns -EOPNOTSUPP. So, the modification of other flags
doesn't work on BTRFS for fsverity inodes.
Fix it for BTRFS and anyone else, the ext4 and f2fs masking becomes
no-op. The file_get/setattr() path is fine here as this flag is cleared
right before fileattr_set_prepare(). The future fsverity support in XFS
would also need it.
Cc: Boris Burkov <boris@bur.io>
Cc: David Sterba <dsterba@suse.com>
Fixes: 146054090b08 ("btrfs: initial fsverity support")
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/file_attr.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fs/file_attr.c b/fs/file_attr.c
index 833e03810b24..b43977d5f8e0 100644
--- a/fs/file_attr.c
+++ b/fs/file_attr.c
@@ -199,6 +199,16 @@ static int fileattr_set_prepare(struct inode *inode,
if (err)
return err;
+ /*
+ * verity is settable only via FS_IOC_ENABLE_VERITY; never through
+ * fileattr
+ *
+ * Treat it as a no-op so the FS_IOC_GETFLAGS/SETFLAGS round-trip
+ * doesn't break for other flags
+ */
+ fa->flags &= ~FS_VERITY_FL;
+ fa->fsx_xflags &= ~FS_XFLAG_VERITY;
+
/*
* Project Quota ID state is only allowed to change from within the init
* namespace. Enforce that restriction only if we are trying to change
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
2026-11-04 19:46 ` [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS Andrey Albershteyn
@ 2026-11-04 19:46 ` Andrey Albershteyn
2026-11-04 19:57 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags Andrey Albershteyn
` (3 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
Every filesystem that supports fs-verity keeps a private runtime inode
flag meaning Merkle tree is currently being built *_VERITY_IN_PROGRESS.
They all serve the same two purposes: reject a concurrent enable with
-EBUSY and let the write paths recognize the special writes done while
the tree is under construction.
Hoist this flag into the VFS as a new inode state flag,
I_VERITY_BUILDING, and manage its lifetime in the generic fs-verity
enable path. The flag is set after ->begin_enable_verity() succeeds and
cleared after ->end_enable_verity() returns (both on the success and the
rollback paths). Add the concurrent-enable guard.
A new helper, fsverity_is_building(), is provided for filesystems to
query the flag. No filesystem uses it yet; the per-fs flags are
converted in following patches.
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/verity/enable.c | 22 +++++++++++++++++++---
include/linux/fs.h | 6 ++++++
include/linux/fsverity.h | 21 +++++++++++++++++++++
3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/fs/verity/enable.c b/fs/verity/enable.c
index fe8493280b77..65d3571c62b5 100644
--- a/fs/verity/enable.c
+++ b/fs/verity/enable.c
@@ -229,13 +229,23 @@ static int enable_verity(struct file *filp,
/*
* Start enabling verity on this file, serialized by the inode lock.
- * Fail if verity is already enabled or is already being enabled.
+ * Fail if verity is already enabled or is already being enabled. Set
+ * I_VERITY_BUILDING inode runtime flag which will be cleared when
+ * enablement succeeded or rolled back.
*/
inode_lock(inode);
- if (IS_VERITY(inode))
+ if (IS_VERITY(inode)) {
err = -EEXIST;
- else
+ } else if (inode_state_read_once(inode) & I_VERITY_BUILDING) {
+ err = -EBUSY;
+ } else {
err = vops->begin_enable_verity(filp);
+ if (!err) {
+ spin_lock(&inode->i_lock);
+ inode_state_set(inode, I_VERITY_BUILDING);
+ spin_unlock(&inode->i_lock);
+ }
+ }
inode_unlock(inode);
if (err)
goto out;
@@ -291,6 +301,9 @@ static int enable_verity(struct file *filp,
*/
inode_lock(inode);
err = vops->end_enable_verity(filp, desc, desc_size, params.tree_size);
+ spin_lock(&inode->i_lock);
+ inode_state_clear(inode, I_VERITY_BUILDING);
+ spin_unlock(&inode->i_lock);
inode_unlock(inode);
if (err) {
fsverity_err(inode, "%ps() failed with err %d",
@@ -317,6 +330,9 @@ static int enable_verity(struct file *filp,
rollback:
inode_lock(inode);
(void)vops->end_enable_verity(filp, NULL, 0, params.tree_size);
+ spin_lock(&inode->i_lock);
+ inode_state_clear(inode, I_VERITY_BUILDING);
+ spin_unlock(&inode->i_lock);
inode_unlock(inode);
goto out;
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 99caef43ff3c..7c90ce09f797 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -707,6 +707,11 @@ is_uncached_acl(struct posix_acl *acl)
* I_LRU_ISOLATING Inode is pinned being isolated from LRU without holding
* i_count.
*
+ * I_VERITY_BUILDING fs-verity is being enabled on the inode: the Merkle
+ * tree is under construction. The file is effectively
+ * read-only to userspace; the only writes happening are
+ * for the fs-verity metadata.
+ *
* Q: What is the difference between I_WILL_FREE and I_FREEING?
*
* __I_{SYNC,NEW,LRU_ISOLATING} are used to derive unique addresses to wait
@@ -741,6 +746,7 @@ enum inode_state_flags_enum {
I_SYNC_QUEUED = (1U << 17),
I_PINNING_NETFS_WB = (1U << 18),
I_METADATA_WRITEBACK = (1U << 19),
+ I_VERITY_BUILDING = (1U << 20),
};
#define I_DIRTY_INODE (I_DIRTY_SYNC | I_DIRTY_DATASYNC)
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index 61fe96ccdff6..c72edec57e30 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -164,6 +164,22 @@ static inline bool fsverity_active(const struct inode *inode)
return false;
}
+/**
+ * fsverity_is_building() - is fs-verity being enabled on the inode
+ * @inode: inode to check
+ *
+ * This checks whether the inode's Merkle tree is currently being built.
+ * While this is the case the file is read-only to userspace and the only writes
+ * allowed are for the fs-verity metadata. This becomes false when fsverity
+ * metadata is fully created and written to disk or building failed.
+ *
+ * Return: true if fs-verity is being enabled on the inode
+ */
+static inline bool fsverity_is_building(const struct inode *inode)
+{
+ return inode_state_read_once((struct inode *)inode) & I_VERITY_BUILDING;
+}
+
struct fsverity_info *__fsverity_get_info(const struct inode *inode);
/**
* fsverity_get_info - get fsverity information for an inode
@@ -217,6 +233,11 @@ static inline bool fsverity_active(const struct inode *inode)
return false;
}
+static inline bool fsverity_is_building(const struct inode *inode)
+{
+ return false;
+}
+
static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)
{
return NULL;
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
2026-11-04 19:46 ` [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS Andrey Albershteyn
2026-11-04 19:46 ` [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag Andrey Albershteyn
@ 2026-11-04 19:46 ` Andrey Albershteyn
2026-11-04 20:00 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 4/5] ext4: " Andrey Albershteyn
` (2 subsequent siblings)
5 siblings, 1 reply; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
Now that the VFS tracks an inode whose Merkle tree is under construction
via I_VERITY_BUILDING and handles the concurrent-enable guard in the
generic fs-verity enable path, drop the inode runtime flags that
duplicated this.
btrfs only used BTRFS_INODE_VERITY_IN_PROGRESS internally, so remove it
outright.
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/btrfs/btrfs_inode.h | 7 -------
fs/btrfs/verity.c | 12 ++----------
2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 0782f917fccc..5c752b947b56 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -78,13 +78,6 @@ enum {
* the file range, inode's io_tree).
*/
BTRFS_INODE_NO_DELALLOC_FLUSH,
- /*
- * Set when we are working on enabling verity for a file. Computing and
- * writing the whole Merkle tree can take a while so we want to prevent
- * races where two separate tasks attempt to simultaneously start verity
- * on the same file.
- */
- BTRFS_INODE_VERITY_IN_PROGRESS,
/* Set when this inode is a free space inode. */
BTRFS_INODE_FREE_SPACE_INODE,
/* Set when there are no capabilities in XATTs for the inode. */
diff --git a/fs/btrfs/verity.c b/fs/btrfs/verity.c
index b34d2247cf84..82e2ebad0d3e 100644
--- a/fs/btrfs/verity.c
+++ b/fs/btrfs/verity.c
@@ -461,7 +461,6 @@ static int rollback_verity(struct btrfs_inode *inode)
btrfs_assert_inode_locked(inode);
truncate_inode_pages(inode->vfs_inode.i_mapping, inode->vfs_inode.i_size);
- clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
ret = btrfs_drop_verity_items(inode);
if (ret) {
btrfs_handle_fs_error(root->fs_info, ret,
@@ -513,7 +512,6 @@ static int rollback_verity(struct btrfs_inode *inode)
* - mark the inode with the verity flag
* - delete the orphan item
* - mark the ro compat bit
- * - clear the in progress bit
*
* Returns 0 on success, negative error code on failure.
*/
@@ -555,7 +553,6 @@ static int finish_verity(struct btrfs_inode *inode, const void *desc,
goto end_trans;
/* Now that rollback is no longer possible, set S_VERITY. */
btrfs_sync_inode_flags_to_i_flags(inode);
- clear_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
btrfs_set_fs_compat_ro(root->fs_info, VERITY);
end_trans:
if (ret)
@@ -570,8 +567,8 @@ static int finish_verity(struct btrfs_inode *inode, const void *desc,
*
* @filp: file to enable verity on
*
- * Begin enabling fsverity for the file. We drop any existing verity items, add
- * an orphan and set the in progress bit.
+ * Begin enabling fsverity for the file. We drop any existing verity items and
+ * add an orphan.
*
* Returns 0 on success, negative error code on failure.
*/
@@ -587,9 +584,6 @@ static int btrfs_begin_enable_verity(struct file *filp)
if (IS_ENCRYPTED(&inode->vfs_inode))
return -EOPNOTSUPP;
- if (test_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags))
- return -EBUSY;
-
/*
* This should almost never do anything, but theoretically, it's
* possible that we failed to enable verity on a file, then were
@@ -606,8 +600,6 @@ static int btrfs_begin_enable_verity(struct file *filp)
return PTR_ERR(trans);
ret = btrfs_orphan_add(trans, inode);
- if (!ret)
- set_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
btrfs_end_transaction(trans);
return 0;
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5] ext4: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
` (2 preceding siblings ...)
2026-11-04 19:46 ` [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags Andrey Albershteyn
@ 2026-11-04 19:46 ` Andrey Albershteyn
2026-11-04 20:01 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 5/5] f2fs: " Andrey Albershteyn
2026-11-04 21:57 ` [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Eric Biggers
5 siblings, 1 reply; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
Now that the VFS tracks an inode whose Merkle tree is under construction
via I_VERITY_BUILDING and handles the concurrent-enable guard in the
generic fs-verity enable path, drop the per-filesystem runtime flags that
duplicated this state.
Replace ext4 own helper ext4_verity_in_progress() with
fsverity_is_building(), and remove the EXT4_STATE_VERITY_IN_PROGRESS
flags. The IS_ENABLED() guard is fine to remove now as
fsverity_is_building() has stub for disabled fsverity.
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/ext4/ext4.h | 7 -------
fs/ext4/file.c | 2 +-
fs/ext4/inode.c | 17 +++++++++--------
fs/ext4/ioctl.c | 3 +--
fs/ext4/verity.c | 18 +++++-------------
5 files changed, 16 insertions(+), 31 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f38fec3167fb..bc624ed58353 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2049,7 +2049,6 @@ enum {
EXT4_STATE_MAY_INLINE_DATA, /* may have in-inode data */
EXT4_STATE_EXT_PRECACHED, /* extents have been precached */
EXT4_STATE_LUSTRE_EA_INODE, /* Lustre-style ea_inode */
- EXT4_STATE_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
EXT4_STATE_FC_COMMITTING, /* Fast commit ongoing */
EXT4_STATE_FC_FLUSHING_DATA, /* Fast commit flushing data */
EXT4_STATE_ORPHAN_FILE, /* Inode orphaned in orphan file */
@@ -2128,12 +2127,6 @@ static inline int ext4_inode_state_wait_bit(int bit)
#define EXT4_SB(sb) (sb)
#endif
-static inline bool ext4_verity_in_progress(struct inode *inode)
-{
- return IS_ENABLED(CONFIG_FS_VERITY) &&
- ext4_test_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
-}
-
#define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime
/*
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 50d3c92709c8..109dea94c6e3 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -318,7 +318,7 @@ static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *from)
* partial block that beyond the existing EOF, as it may contains
* stale data written through mmap.
*/
- if (iocb->ki_pos > old_size && !ext4_verity_in_progress(inode)) {
+ if (iocb->ki_pos > old_size && !fsverity_is_building(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 10cd85d4c721..171028185c9d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -42,6 +42,7 @@
#include <linux/bitops.h>
#include <linux/iomap.h>
#include <linux/iversion.h>
+#include <linux/fsverity.h>
#include "ext4_jbd2.h"
#include "ext4_extents.h"
@@ -511,7 +512,7 @@ void ext4_check_map_extents_env(struct inode *inode)
is_special_ino(inode->i_sb, inode->i_ino) ||
(inode_state_read_once(inode) & (I_FREEING | I_WILL_FREE | I_NEW)) ||
ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE) ||
- ext4_verity_in_progress(inode))
+ fsverity_is_building(inode))
return;
WARN_ON_ONCE(!inode_is_locked(inode) &&
@@ -1498,7 +1499,7 @@ static int ext4_write_begin(const struct kiocb *iocb,
if (ret) {
bool extended = (pos + len > inode->i_size) &&
- !ext4_verity_in_progress(inode);
+ !fsverity_is_building(inode);
folio_unlock(folio);
/*
@@ -1565,7 +1566,7 @@ static int ext4_write_end(const struct kiocb *iocb,
loff_t old_size = inode->i_size;
int ret = 0, ret2;
int i_size_changed = 0;
- bool verity = ext4_verity_in_progress(inode);
+ bool verity = fsverity_is_building(inode);
trace_ext4_write_end(inode, pos, len, copied);
@@ -1670,7 +1671,7 @@ static int ext4_journalled_write_end(const struct kiocb *iocb,
int partial = 0;
unsigned from, to;
int size_changed = 0;
- bool verity = ext4_verity_in_progress(inode);
+ bool verity = fsverity_is_building(inode);
trace_ext4_journalled_write_end(inode, pos, len, copied);
from = pos & (PAGE_SIZE - 1);
@@ -2215,7 +2216,7 @@ static void mpage_submit_folio(struct mpage_da_data *mpd, struct folio *folio)
size = i_size_read(mpd->inode);
len = folio_size(folio);
if (folio_pos(folio) + len > size &&
- !ext4_verity_in_progress(mpd->inode))
+ !fsverity_is_building(mpd->inode))
len = size & (len - 1);
ext4_bio_write_folio(&mpd->io_submit, folio, len);
}
@@ -2305,7 +2306,7 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
ext4_lblk_t blocks = (i_size_read(inode) + i_blocksize(inode) - 1)
>> inode->i_blkbits;
- if (ext4_verity_in_progress(inode))
+ if (fsverity_is_building(inode))
blocks = EXT_MAX_BLOCKS;
do {
@@ -2711,7 +2712,7 @@ static int mpage_journal_page_buffers(handle_t *handle,
mpd->wbc->nr_to_write -= folio_nr_pages(folio);
if (folio_pos(folio) + len > size &&
- !ext4_verity_in_progress(inode))
+ !fsverity_is_building(inode))
len = size & (len - 1);
return ext4_journal_folio_buffers(handle, folio, len);
@@ -3276,7 +3277,7 @@ static int ext4_da_write_begin(const struct kiocb *iocb,
index = pos >> PAGE_SHIFT;
- if (ext4_nonda_switch(inode->i_sb) || ext4_verity_in_progress(inode)) {
+ if (ext4_nonda_switch(inode->i_sb) || fsverity_is_building(inode)) {
*fsdata = (void *)FALL_BACK_TO_NONDELALLOC;
return ext4_write_begin(iocb, mapping, pos,
len, foliop, fsdata);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index e8e579498c99..d3db2e77ebda 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -575,8 +575,7 @@ static bool dax_compatible(struct inode *inode, unsigned int oldflags,
if (flags & EXT4_DAX_FL) {
if ((oldflags & EXT4_DAX_MUT_EXCL) ||
- ext4_test_inode_state(inode,
- EXT4_STATE_VERITY_IN_PROGRESS)) {
+ fsverity_is_building(inode)) {
return false;
}
}
diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
index 56fe3e5b33e0..0189c8868b74 100644
--- a/fs/ext4/verity.c
+++ b/fs/ext4/verity.c
@@ -83,9 +83,6 @@ static int ext4_begin_enable_verity(struct file *filp)
if (IS_DAX(inode) || ext4_test_inode_flag(inode, EXT4_INODE_DAX))
return -EINVAL;
- if (ext4_verity_in_progress(inode))
- return -EBUSY;
-
/*
* Since the file was opened readonly, we have to initialize the jbd
* inode and quotas here and not rely on ->open() doing it. This must
@@ -123,8 +120,6 @@ static int ext4_begin_enable_verity(struct file *filp)
return PTR_ERR(handle);
err = ext4_orphan_add(handle, inode);
- if (err == 0)
- ext4_set_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
ext4_journal_stop(handle);
return err;
@@ -185,10 +180,9 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc,
goto cleanup;
/*
- * 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.
+ * Write all pages (both data and verity metadata). For crash
+ * consistency, this also must happen before the verity inode flag gets
+ * persisted.
*/
err = filemap_write_and_wait(inode->i_mapping);
if (err)
@@ -224,7 +218,6 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc,
/* Now that rollback is no longer possible, set S_VERITY. */
ext4_set_inode_flags(inode, false);
- ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
return 0;
stop_and_cleanup:
@@ -234,13 +227,12 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc,
/*
* 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.
+ * disk) and removing the inode from the orphan list (if it wasn't done
+ * already).
*/
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;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5] f2fs: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
` (3 preceding siblings ...)
2026-11-04 19:46 ` [PATCH 4/5] ext4: " Andrey Albershteyn
@ 2026-11-04 19:46 ` Andrey Albershteyn
2026-11-04 20:04 ` sashiko-bot
2026-11-04 21:57 ` [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Eric Biggers
5 siblings, 1 reply; 12+ messages in thread
From: Andrey Albershteyn @ 2026-11-04 19:46 UTC (permalink / raw)
To: ebiggers, hch, fsverity
Cc: Andrey Albershteyn, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
Now that the VFS tracks an inode whose Merkle tree is under construction
via I_VERITY_BUILDING and handles the concurrent-enable guard in the
generic fs-verity enable path, drop the inode runtime flags that
duplicated this state.
Replace f2fs own helper f2fs_verity_in_progress() with
fsverity_is_building(), and remove the and FI_VERITY_IN_PROGRESS flags.
It's fine to remove IS_ENABLED() guard as fsverity_is_building() has
stub.
Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
---
fs/f2fs/data.c | 10 +++++-----
fs/f2fs/f2fs.h | 7 -------
fs/f2fs/verity.c | 15 ++++-----------
3 files changed, 9 insertions(+), 23 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 28fd8afff5d4..ab6f6f182f97 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3356,7 +3356,7 @@ int f2fs_write_single_data_page(struct folio *folio, int *submitted,
goto redirty_out;
if (folio->index < end_index ||
- f2fs_verity_in_progress(inode) ||
+ fsverity_is_building(inode) ||
compr_blocks)
goto write;
@@ -3889,7 +3889,7 @@ void f2fs_write_failed(struct inode *inode, loff_t to)
return;
/* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
- if (to > i_size && !f2fs_verity_in_progress(inode)) {
+ if (to > i_size && !fsverity_is_building(inode)) {
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);
@@ -4205,7 +4205,7 @@ static int f2fs_write_begin(const struct kiocb *iocb,
return 0;
if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
- !f2fs_verity_in_progress(inode)) {
+ !fsverity_is_building(inode)) {
folio_zero_segment(folio, len, folio_size(folio));
return 0;
}
@@ -4279,7 +4279,7 @@ static int f2fs_write_end(const struct kiocb *iocb,
f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
if (pos + copied > i_size_read(inode) &&
- !f2fs_verity_in_progress(inode))
+ !fsverity_is_building(inode))
f2fs_i_size_write(inode, pos + copied);
return copied;
}
@@ -4294,7 +4294,7 @@ static int f2fs_write_end(const struct kiocb *iocb,
folio_set_f2fs_atomic(folio);
if (pos + copied > i_size_read(inode) &&
- !f2fs_verity_in_progress(inode)) {
+ !fsverity_is_building(inode)) {
f2fs_i_size_write(inode, pos + copied);
if (f2fs_is_atomic_file(inode))
f2fs_i_size_write(F2FS_I(inode)->cow_inode,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f7423b3f6e4a..374c861f13b9 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -925,7 +925,6 @@ enum {
FI_EXTRA_ATTR, /* indicate file has extra attribute */
FI_PROJ_INHERIT, /* indicate file inherits projectid */
FI_PIN_FILE, /* indicate file should not be gced */
- FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
FI_COMPRESS_CORRUPT, /* indicate compressed cluster is corrupted */
FI_MMAP_FILE, /* indicate file was mmapped */
@@ -3535,12 +3534,6 @@ static inline void clear_inode_flag(struct inode *inode, int flag)
__mark_inode_dirty_flag(inode, flag, false);
}
-static inline bool f2fs_verity_in_progress(struct inode *inode)
-{
- return IS_ENABLED(CONFIG_FS_VERITY) &&
- is_inode_flag_set(inode, FI_VERITY_IN_PROGRESS);
-}
-
static inline void set_acl_inode(struct inode *inode, umode_t mode)
{
F2FS_I(inode)->i_acl_mode = mode;
diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
index 4a2cea4288f9..af3d33c6f26d 100644
--- a/fs/f2fs/verity.c
+++ b/fs/f2fs/verity.c
@@ -94,9 +94,6 @@ static int f2fs_begin_enable_verity(struct file *filp)
struct inode *inode = file_inode(filp);
int err;
- if (f2fs_verity_in_progress(inode))
- return -EBUSY;
-
if (f2fs_is_atomic_file(inode))
return -EOPNOTSUPP;
@@ -113,7 +110,6 @@ static int f2fs_begin_enable_verity(struct file *filp)
if (err)
return err;
- set_inode_flag(inode, FI_VERITY_IN_PROGRESS);
return 0;
}
@@ -143,10 +139,9 @@ static int f2fs_end_enable_verity(struct file *filp, const void *desc,
goto cleanup;
/*
- * Write all pages (both data and verity metadata). Note that this must
- * happen before clearing FI_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.
+ * Write all pages (both data and verity metadata). For crash
+ * consistency, this also must happen before the verity inode flag gets
+ * persisted.
*/
err = filemap_write_and_wait(inode->i_mapping);
if (err)
@@ -164,14 +159,13 @@ static int f2fs_end_enable_verity(struct file *filp, const void *desc,
f2fs_set_inode_flags(inode);
f2fs_mark_inode_dirty_sync(inode, true);
- clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
return 0;
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) and clearing FI_VERITY_IN_PROGRESS.
+ * disk).
*
* Taking i_gc_rwsem[WRITE] is needed to stop f2fs garbage collection
* from re-instantiating cached pages we are truncating (since unlike
@@ -186,7 +180,6 @@ static int f2fs_end_enable_verity(struct file *filp, const void *desc,
set_sbi_flag(sbi, SBI_NEED_FSCK);
}
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
- clear_inode_flag(inode, FI_VERITY_IN_PROGRESS);
return err ?: err2;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS
2026-11-04 19:46 ` [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS Andrey Albershteyn
@ 2026-11-04 19:55 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-11-04 19:55 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: linux-ext4, tytso
> The common use of FS_IOC_GETFLAGS/SETFLAGS is get-modify-set loop.
> Filesystems could return verity status with GETFLAGS, attempting to then
> pass FS_VERITY_FL to SETFLAGS is not allowed.
>
> The ext4 and f2fs already treat FS_VERITY_FL in the set path as no-op,
> however, BTRFS returns -EOPNOTSUPP. So, the modification of other flags
> doesn't work on BTRFS for fsverity inodes.
>
> Fix it for BTRFS and anyone else, the ext4 and f2fs masking becomes
> no-op. The file_get/setattr() path is fine here as this flag is cleared
> right before fileattr_set_prepare(). The future fsverity support in XFS
> would also need it.
>
> Cc: Boris Burkov <boris@bur.io>
> Cc: David Sterba <dsterba@suse.com>
> Fixes: 146054090b08 ("btrfs: initial fsverity support")
> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104194618.103332-1-aalbersh@kernel.org?part=1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag
2026-11-04 19:46 ` [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag Andrey Albershteyn
@ 2026-11-04 19:57 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-11-04 19:57 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: linux-ext4, tytso
> Every filesystem that supports fs-verity keeps a private runtime inode
> flag meaning Merkle tree is currently being built *_VERITY_IN_PROGRESS.
> They all serve the same two purposes: reject a concurrent enable with
> -EBUSY and let the write paths recognize the special writes done while
> the tree is under construction.
>
> Hoist this flag into the VFS as a new inode state flag,
> I_VERITY_BUILDING, and manage its lifetime in the generic fs-verity
> enable path. The flag is set after ->begin_enable_verity() succeeds and
> cleared after ->end_enable_verity() returns (both on the success and the
> rollback paths). Add the concurrent-enable guard.
>
> A new helper, fsverity_is_building(), is provided for filesystems to
> query the flag. No filesystem uses it yet; the per-fs flags are
> converted in following patches.
>
> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104194618.103332-1-aalbersh@kernel.org?part=2
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 ` [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags Andrey Albershteyn
@ 2026-11-04 20:00 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-11-04 20:00 UTC (permalink / raw)
To: Andrey Albershteyn, ebiggers, hch, fsverity; +Cc: linux-ext4, dsterba, tytso
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] btrfs: unpropagated btrfs_orphan_add() error in btrfs_begin_enable_verity()
--
commit d32a0bd97250023398879e80e49ecc247da4ccdf
Author: Andrey Albershteyn via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
btrfs: use I_VERITY_BUILDING instead of private flags
This commit removes the BTRFS_INODE_VERITY_IN_PROGRESS inode runtime flag now
that the generic VFS fs-verity path tracks in-progress Merkle tree
construction via I_VERITY_BUILDING.
> diff --git a/fs/btrfs/verity.c b/fs/btrfs/verity.c
> index b34d2247cf84e..82e2ebad0d3e6 100644
> --- a/fs/btrfs/verity.c
> +++ b/fs/btrfs/verity.c
[ ... ]
> @@ -606,8 +600,6 @@ static int btrfs_begin_enable_verity(struct file *filp)
> return PTR_ERR(trans);
>
> ret = btrfs_orphan_add(trans, inode);
> - if (!ret)
> - set_bit(BTRFS_INODE_VERITY_IN_PROGRESS, &inode->runtime_flags);
> btrfs_end_transaction(trans);
>
> return 0;
[Severity: Medium]
In btrfs_begin_enable_verity(), removing the if (!ret) check leaves the return
value of btrfs_orphan_add() in ret unread (which triggers an unused-but-set
variable compiler warning) while the function still ends with return 0.
Previously, if btrfs_orphan_add() failed during the
fsverity_ioctl_enable() -> enable_verity() -> btrfs_begin_enable_verity()
path, BTRFS_INODE_VERITY_IN_PROGRESS was not set. Now, enable_verity() in
fs/verity/enable.c checks the return value of begin_enable_verity():
err = vops->begin_enable_verity(filp);
if (!err) {
spin_lock(&inode->i_lock);
inode_state_set(inode, I_VERITY_BUILDING);
spin_unlock(&inode->i_lock);
}
Because btrfs_begin_enable_verity() returns 0 even when btrfs_orphan_add()
fails and aborts the transaction, enable_verity() will still set
I_VERITY_BUILDING and proceed to build_merkle_tree() without an orphan item.
Should btrfs_begin_enable_verity() return ret instead of 0?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104194618.103332-1-aalbersh@kernel.org?part=3
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5] ext4: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 ` [PATCH 4/5] ext4: " Andrey Albershteyn
@ 2026-11-04 20:01 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-11-04 20:01 UTC (permalink / raw)
To: Andrey Albershteyn; +Cc: linux-ext4, tytso
> Now that the VFS tracks an inode whose Merkle tree is under construction
> via I_VERITY_BUILDING and handles the concurrent-enable guard in the
> generic fs-verity enable path, drop the per-filesystem runtime flags that
> duplicated this state.
>
> Replace ext4 own helper ext4_verity_in_progress() with
> fsverity_is_building(), and remove the EXT4_STATE_VERITY_IN_PROGRESS
> flags. The IS_ENABLED() guard is fine to remove now as
> fsverity_is_building() has stub for disabled fsverity.
>
> Signed-off-by: Andrey Albershteyn <aalbersh@kernel.org>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104194618.103332-1-aalbersh@kernel.org?part=4
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/5] f2fs: use I_VERITY_BUILDING instead of private flags
2026-11-04 19:46 ` [PATCH 5/5] f2fs: " Andrey Albershteyn
@ 2026-11-04 20:04 ` sashiko-bot
0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-11-04 20:04 UTC (permalink / raw)
To: Andrey Albershteyn, ebiggers, hch, fsverity; +Cc: linux-ext4, dsterba, tytso
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] f2fs: unconverted f2fs_verity_in_progress() calls break build in data.c
--
commit 915530af8afaaef004825dfc719049bb96b8cda2
Author: Andrey Albershteyn via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
f2fs: use I_VERITY_BUILDING instead of private flags
This commit replaces the f2fs-specific FI_VERITY_IN_PROGRESS flag and
f2fs_verity_in_progress() helper with the generic fsverity_is_building()
helper.
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 4fa4d8042f702..11d1cade11510 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -925,7 +925,6 @@ enum {
> FI_EXTRA_ATTR, /* indicate file has extra attribute */
> FI_PROJ_INHERIT, /* indicate file inherits projectid */
> FI_PIN_FILE, /* indicate file should not be gced */
> - FI_VERITY_IN_PROGRESS, /* building fs-verity Merkle tree */
> FI_COMPRESSED_FILE, /* indicate file's data can be compressed */
> FI_COMPRESS_CORRUPT, /* indicate compressed cluster is corrupted */
> FI_MMAP_FILE, /* indicate file was mmapped */
> @@ -3627,12 +3626,6 @@ static inline void clear_inode_flag(struct inode *inode, int flag)
> __mark_inode_dirty_flag(inode, flag, false);
> }
>
> -static inline bool f2fs_verity_in_progress(struct inode *inode)
> -{
> - return IS_ENABLED(CONFIG_FS_VERITY) &&
> - is_inode_flag_set(inode, FI_VERITY_IN_PROGRESS);
> -}
> -
> static inline void set_acl_inode(struct inode *inode, umode_t mode)
> {
> F2FS_I(inode)->i_acl_mode = mode;
[Severity: Low]
Does removing f2fs_verity_in_progress() break the build in fs/f2fs/data.c?
Two callers in fs/f2fs/data.c still reference f2fs_verity_in_progress()
after this patch:
fs/f2fs/data.c:f2fs_write_cache_folios() {
...
retry:
pos = folio_pos(folio);
end_pos = pos + folio_size(folio);
isize = i_size_read(inode);
verity_in_progress = f2fs_verity_in_progress(inode);
...
}
and:
fs/f2fs/data.c:prepare_large_folio_write_begin() {
...
if (!f2fs_verity_in_progress(inode) &&
!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode)) {
size_t zoff = ori_off + len;
...
}
Should these two call sites also be converted to fsverity_is_building(inode)?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104194618.103332-1-aalbersh@kernel.org?part=5
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
` (4 preceding siblings ...)
2026-11-04 19:46 ` [PATCH 5/5] f2fs: " Andrey Albershteyn
@ 2026-11-04 21:57 ` Eric Biggers
5 siblings, 0 replies; 12+ messages in thread
From: Eric Biggers @ 2026-11-04 21:57 UTC (permalink / raw)
To: Andrey Albershteyn
Cc: hch, fsverity, linux-xfs, linux-btrfs, linux-f2fs-devel,
linux-ext4
On Wed, Nov 04, 2026 at 08:46:09PM +0100, Andrey Albershteyn wrote:
> Hi folks,
>
> This patchset lifts two things from filesystems to VFS level:
> - No-oping FS_VERITY_FL in SET ioctl()
> - runtime fsverity construction flag
>
> The first one fixes BTRFS get-modify-set loop with
> FS_IOC_GETFLAGS/SETFLAGS ioctl()s, as it does return fsverity flag but
> not mask it out.
Changes to 'struct inode' should be Cc'ed to linux-fsdevel as well.
- Eric
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-11-04 21:57 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 19:46 [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Andrey Albershteyn
2026-11-04 19:46 ` [PATCH 1/5] fsverity: strip FS_VERITY_FL from FS_IOC_SETFLAGS Andrey Albershteyn
2026-11-04 19:55 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 2/5] fsverity: add I_VERITY_BUILDING inode state flag Andrey Albershteyn
2026-11-04 19:57 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 3/5] btrfs: use I_VERITY_BUILDING instead of private flags Andrey Albershteyn
2026-11-04 20:00 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 4/5] ext4: " Andrey Albershteyn
2026-11-04 20:01 ` sashiko-bot
2026-11-04 19:46 ` [PATCH 5/5] f2fs: " Andrey Albershteyn
2026-11-04 20:04 ` sashiko-bot
2026-11-04 21:57 ` [PATCH 0/5] fsverity: lift ioctl() input masking and runtime inode flag to VFS Eric Biggers
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox