Merge tag 'f2fs-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
[linux-2.6-block.git] / fs / f2fs / data.c
index adc64d514b797bc402879d7174bf4b32e412b186..5755e897a5f03671a3147a6dbc5cc8bf190ea5f1 100644 (file)
@@ -74,6 +74,7 @@ static enum count_type __read_io_type(struct page *page)
 enum bio_post_read_step {
        STEP_INITIAL = 0,
        STEP_DECRYPT,
+       STEP_VERITY,
 };
 
 struct bio_post_read_ctx {
@@ -120,8 +121,23 @@ static void decrypt_work(struct work_struct *work)
        bio_post_read_processing(ctx);
 }
 
+static void verity_work(struct work_struct *work)
+{
+       struct bio_post_read_ctx *ctx =
+               container_of(work, struct bio_post_read_ctx, work);
+
+       fsverity_verify_bio(ctx->bio);
+
+       bio_post_read_processing(ctx);
+}
+
 static void bio_post_read_processing(struct bio_post_read_ctx *ctx)
 {
+       /*
+        * We use different work queues for decryption and for verity because
+        * verity may require reading metadata pages that need decryption, and
+        * we shouldn't recurse to the same workqueue.
+        */
        switch (++ctx->cur_step) {
        case STEP_DECRYPT:
                if (ctx->enabled_steps & (1 << STEP_DECRYPT)) {
@@ -131,6 +147,14 @@ static void bio_post_read_processing(struct bio_post_read_ctx *ctx)
                }
                ctx->cur_step++;
                /* fall-through */
+       case STEP_VERITY:
+               if (ctx->enabled_steps & (1 << STEP_VERITY)) {
+                       INIT_WORK(&ctx->work, verity_work);
+                       fsverity_enqueue_verify_work(&ctx->work);
+                       return;
+               }
+               ctx->cur_step++;
+               /* fall-through */
        default:
                __read_end_io(ctx->bio);
        }
@@ -643,8 +667,15 @@ out:
        up_write(&io->io_rwsem);
 }
 
+static inline bool f2fs_need_verity(const struct inode *inode, pgoff_t idx)
+{
+       return fsverity_active(inode) &&
+              idx < DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
+}
+
 static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
-                                       unsigned nr_pages, unsigned op_flag)
+                                     unsigned nr_pages, unsigned op_flag,
+                                     pgoff_t first_idx)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct bio *bio;
@@ -660,6 +691,10 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
 
        if (f2fs_encrypted_file(inode))
                post_read_steps |= 1 << STEP_DECRYPT;
+
+       if (f2fs_need_verity(inode, first_idx))
+               post_read_steps |= 1 << STEP_VERITY;
+
        if (post_read_steps) {
                ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
                if (!ctx) {
@@ -681,7 +716,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct bio *bio;
 
-       bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0);
+       bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0, page->index);
        if (IS_ERR(bio))
                return PTR_ERR(bio);
 
@@ -1604,6 +1639,15 @@ out:
        return ret;
 }
 
+static inline loff_t f2fs_readpage_limit(struct inode *inode)
+{
+       if (IS_ENABLED(CONFIG_FS_VERITY) &&
+           (IS_VERITY(inode) || f2fs_verity_in_progress(inode)))
+               return inode->i_sb->s_maxbytes;
+
+       return i_size_read(inode);
+}
+
 static int f2fs_read_single_page(struct inode *inode, struct page *page,
                                        unsigned nr_pages,
                                        struct f2fs_map_blocks *map,
@@ -1622,7 +1666,7 @@ static int f2fs_read_single_page(struct inode *inode, struct page *page,
 
        block_in_file = (sector_t)page_index(page);
        last_block = block_in_file + nr_pages;
-       last_block_in_file = (i_size_read(inode) + blocksize - 1) >>
+       last_block_in_file = (f2fs_readpage_limit(inode) + blocksize - 1) >>
                                                        blkbits;
        if (last_block > last_block_in_file)
                last_block = last_block_in_file;
@@ -1667,6 +1711,11 @@ got_it:
        } else {
 zero_out:
                zero_user_segment(page, 0, PAGE_SIZE);
+               if (f2fs_need_verity(inode, page->index) &&
+                   !fsverity_verify_page(page)) {
+                       ret = -EIO;
+                       goto out;
+               }
                if (!PageUptodate(page))
                        SetPageUptodate(page);
                unlock_page(page);
@@ -1685,7 +1734,7 @@ submit_and_realloc:
        }
        if (bio == NULL) {
                bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
-                               is_readahead ? REQ_RAHEAD : 0);
+                               is_readahead ? REQ_RAHEAD : 0, page->index);
                if (IS_ERR(bio)) {
                        ret = PTR_ERR(bio);
                        bio = NULL;
@@ -2087,7 +2136,7 @@ static int __write_data_page(struct page *page, bool *submitted,
        if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
                goto redirty_out;
 
-       if (page->index < end_index)
+       if (page->index < end_index || f2fs_verity_in_progress(inode))
                goto write;
 
        /*
@@ -2462,7 +2511,8 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
        struct inode *inode = mapping->host;
        loff_t i_size = i_size_read(inode);
 
-       if (to > i_size) {
+       /* In the fs-verity case, f2fs_end_enable_verity() does the truncate */
+       if (to > i_size && !f2fs_verity_in_progress(inode)) {
                down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                down_write(&F2FS_I(inode)->i_mmap_sem);
 
@@ -2493,7 +2543,8 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
         * the block addresses when there is no need to fill the page.
         */
        if (!f2fs_has_inline_data(inode) && len == PAGE_SIZE &&
-                       !is_inode_flag_set(inode, FI_NO_PREALLOC))
+           !is_inode_flag_set(inode, FI_NO_PREALLOC) &&
+           !f2fs_verity_in_progress(inode))
                return 0;
 
        /* f2fs_lock_op avoids race between write CP and convert_inline_page */
@@ -2633,7 +2684,8 @@ repeat:
        if (len == PAGE_SIZE || PageUptodate(page))
                return 0;
 
-       if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode)) {
+       if (!(pos & (PAGE_SIZE - 1)) && (pos + len) >= i_size_read(inode) &&
+           !f2fs_verity_in_progress(inode)) {
                zero_user_segment(page, len, PAGE_SIZE);
                return 0;
        }
@@ -2696,7 +2748,8 @@ static int f2fs_write_end(struct file *file,
 
        set_page_dirty(page);
 
-       if (pos + copied > i_size_read(inode))
+       if (pos + copied > i_size_read(inode) &&
+           !f2fs_verity_in_progress(inode))
                f2fs_i_size_write(inode, pos + copied);
 unlock_out:
        f2fs_put_page(page, 1);
@@ -3140,7 +3193,9 @@ void f2fs_clear_page_cache_dirty_tag(struct page *page)
 
 int __init f2fs_init_post_read_processing(void)
 {
-       bio_post_read_ctx_cache = KMEM_CACHE(bio_post_read_ctx, 0);
+       bio_post_read_ctx_cache =
+               kmem_cache_create("f2fs_bio_post_read_ctx",
+                                 sizeof(struct bio_post_read_ctx), 0, 0, NULL);
        if (!bio_post_read_ctx_cache)
                goto fail;
        bio_post_read_ctx_pool =