@@ -642,6 +642,13 @@ void generic_shutdown_super(struct super_block *sb)
sb->s_dio_done_wq = NULL;
}
+#ifdef CONFIG_FS_VERITY
+ if (sb->s_read_done_wq) {
+ destroy_workqueue(sb->s_read_done_wq);
+ sb->s_read_done_wq = NULL;
+ }
+#endif
+
if (sop->put_super)
sop->put_super(sb);
@@ -1221,6 +1221,8 @@ struct super_block {
#endif
#ifdef CONFIG_FS_VERITY
const struct fsverity_operations *s_vop;
+ /* Completion queue for post read verification */
+ struct workqueue_struct *s_read_done_wq;
#endif
#if IS_ENABLED(CONFIG_UNICODE)
struct unicode_map *s_encoding;
@@ -241,6 +241,22 @@ void fsverity_enqueue_verify_work(struct work_struct *work);
void fsverity_invalidate_block(struct inode *inode,
struct fsverity_blockbuf *block);
+static inline int fsverity_set_ops(struct super_block *sb,
+ const struct fsverity_operations *ops)
+{
+ sb->s_vop = ops;
+
+ /* Create per-sb workqueue for post read bio verification */
+ struct workqueue_struct *wq = alloc_workqueue(
+ "pread/%s", (WQ_FREEZABLE | WQ_MEM_RECLAIM), 0, sb->s_id);
+ if (!wq)
+ return -ENOMEM;
+
+ sb->s_read_done_wq = wq;
+
+ return 0;
+}
+
#else /* !CONFIG_FS_VERITY */
static inline struct fsverity_info *fsverity_get_info(const struct inode *inode)
@@ -318,6 +334,12 @@ static inline void fsverity_enqueue_verify_work(struct work_struct *work)
WARN_ON_ONCE(1);
}
+static inline int fsverity_set_ops(struct super_block *sb,
+ const struct fsverity_operations *ops)
+{
+ return -EOPNOTSUPP;
+}
+
#endif /* !CONFIG_FS_VERITY */
static inline bool fsverity_verify_folio(struct folio *folio)