Merge tag 'uninit-macro-v5.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / f2fs / data.c
index 3753ba0..5f52707 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pagevec.h>
 #include <linux/blkdev.h>
 #include <linux/bio.h>
+#include <linux/blk-crypto.h>
 #include <linux/swap.h>
 #include <linux/prefetch.h>
 #include <linux/uio.h>
@@ -459,6 +460,33 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
        return bio;
 }
 
+static void f2fs_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,
+                                 pgoff_t first_idx,
+                                 const struct f2fs_io_info *fio,
+                                 gfp_t gfp_mask)
+{
+       /*
+        * The f2fs garbage collector sets ->encrypted_page when it wants to
+        * read/write raw data without encryption.
+        */
+       if (!fio || !fio->encrypted_page)
+               fscrypt_set_bio_crypt_ctx(bio, inode, first_idx, gfp_mask);
+}
+
+static bool f2fs_crypt_mergeable_bio(struct bio *bio, const struct inode *inode,
+                                    pgoff_t next_idx,
+                                    const struct f2fs_io_info *fio)
+{
+       /*
+        * The f2fs garbage collector sets ->encrypted_page when it wants to
+        * read/write raw data without encryption.
+        */
+       if (fio && fio->encrypted_page)
+               return !bio_has_crypt_ctx(bio);
+
+       return fscrypt_mergeable_bio(bio, inode, next_idx);
+}
+
 static inline void __submit_bio(struct f2fs_sb_info *sbi,
                                struct bio *bio, enum page_type type)
 {
@@ -684,6 +712,9 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
        /* Allocate a new bio */
        bio = __bio_alloc(fio, 1);
 
+       f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
+                              fio->page->index, fio, GFP_NOIO);
+
        if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
                bio_put(bio);
                return -EFAULT;
@@ -763,9 +794,10 @@ static void del_bio_entry(struct bio_entry *be)
        kmem_cache_free(bio_entry_slab, be);
 }
 
-static int add_ipu_page(struct f2fs_sb_info *sbi, struct bio **bio,
+static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio,
                                                        struct page *page)
 {
+       struct f2fs_sb_info *sbi = fio->sbi;
        enum temp_type temp;
        bool found = false;
        int ret = -EAGAIN;
@@ -782,13 +814,19 @@ static int add_ipu_page(struct f2fs_sb_info *sbi, struct bio **bio,
 
                        found = true;
 
-                       if (bio_add_page(*bio, page, PAGE_SIZE, 0) ==
-                                                       PAGE_SIZE) {
+                       f2fs_bug_on(sbi, !page_is_mergeable(sbi, *bio,
+                                                           *fio->last_block,
+                                                           fio->new_blkaddr));
+                       if (f2fs_crypt_mergeable_bio(*bio,
+                                       fio->page->mapping->host,
+                                       fio->page->index, fio) &&
+                           bio_add_page(*bio, page, PAGE_SIZE, 0) ==
+                                       PAGE_SIZE) {
                                ret = 0;
                                break;
                        }
 
-                       /* bio is full */
+                       /* page can't be merged into bio; submit the bio */
                        del_bio_entry(be);
                        __submit_bio(sbi, *bio, DATA);
                        break;
@@ -880,11 +918,13 @@ alloc_new:
        if (!bio) {
                bio = __bio_alloc(fio, BIO_MAX_PAGES);
                __attach_io_flag(fio);
+               f2fs_set_bio_crypt_ctx(bio, fio->page->mapping->host,
+                                      fio->page->index, fio, GFP_NOIO);
                bio_set_op_attrs(bio, fio->op, fio->op_flags);
 
                add_bio_entry(fio->sbi, bio, page, fio->temp);
        } else {
-               if (add_ipu_page(fio->sbi, &bio, page))
+               if (add_ipu_page(fio, &bio, page))
                        goto alloc_new;
        }
 
@@ -936,8 +976,11 @@ next:
 
        inc_page_count(sbi, WB_DATA_TYPE(bio_page));
 
-       if (io->bio && !io_is_mergeable(sbi, io->bio, io, fio,
-                       io->last_block_in_bio, fio->new_blkaddr))
+       if (io->bio &&
+           (!io_is_mergeable(sbi, io->bio, io, fio, io->last_block_in_bio,
+                             fio->new_blkaddr) ||
+            !f2fs_crypt_mergeable_bio(io->bio, fio->page->mapping->host,
+                                      bio_page->index, fio)))
                __submit_merged_bio(io);
 alloc_new:
        if (io->bio == NULL) {
@@ -949,6 +992,8 @@ alloc_new:
                        goto skip;
                }
                io->bio = __bio_alloc(fio, BIO_MAX_PAGES);
+               f2fs_set_bio_crypt_ctx(io->bio, fio->page->mapping->host,
+                                      bio_page->index, fio, GFP_NOIO);
                io->fio = *fio;
        }
 
@@ -993,11 +1038,14 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
                                                                for_write);
        if (!bio)
                return ERR_PTR(-ENOMEM);
+
+       f2fs_set_bio_crypt_ctx(bio, inode, first_idx, NULL, GFP_NOFS);
+
        f2fs_target_device(sbi, blkaddr, bio);
        bio->bi_end_io = f2fs_read_end_io;
        bio_set_op_attrs(bio, REQ_OP_READ, op_flag);
 
-       if (f2fs_encrypted_file(inode))
+       if (fscrypt_inode_uses_fs_layer_crypto(inode))
                post_read_steps |= 1 << STEP_DECRYPT;
        if (f2fs_compressed_file(inode))
                post_read_steps |= 1 << STEP_DECOMPRESS_NOWQ;
@@ -2073,8 +2121,9 @@ zero_out:
         * This page will go to BIO.  Do we need to send this
         * BIO off first?
         */
-       if (bio && !page_is_mergeable(F2FS_I_SB(inode), bio,
-                               *last_block_in_bio, block_nr)) {
+       if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio,
+                                      *last_block_in_bio, block_nr) ||
+                   !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
 submit_and_realloc:
                __submit_bio(F2FS_I_SB(inode), bio, DATA);
                bio = NULL;
@@ -2204,8 +2253,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret,
                blkaddr = data_blkaddr(dn.inode, dn.node_page,
                                                dn.ofs_in_node + i + 1);
 
-               if (bio && !page_is_mergeable(sbi, bio,
-                                       *last_block_in_bio, blkaddr)) {
+               if (bio && (!page_is_mergeable(sbi, bio,
+                                       *last_block_in_bio, blkaddr) ||
+                   !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) {
 submit_and_realloc:
                        __submit_bio(sbi, bio, DATA);
                        bio = NULL;
@@ -2421,6 +2471,9 @@ int f2fs_encrypt_one_page(struct f2fs_io_info *fio)
        /* wait for GCed page writeback via META_MAPPING */
        f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
 
+       if (fscrypt_inode_uses_inline_crypto(inode))
+               return 0;
+
 retry_encrypt:
        fio->encrypted_page = fscrypt_encrypt_pagecache_blocks(page,
                                        PAGE_SIZE, 0, gfp_flags);
@@ -2594,7 +2647,7 @@ got_it:
                        f2fs_unlock_op(fio->sbi);
                err = f2fs_inplace_write_data(fio);
                if (err) {
-                       if (f2fs_encrypted_file(inode))
+                       if (fscrypt_inode_uses_fs_layer_crypto(inode))
                                fscrypt_finalize_bounce_page(&fio->encrypted_page);
                        if (PageWriteback(page))
                                end_page_writeback(page);