[RAMEN9610-8702][COMMON] f2fs: support fmp encryption
authorBoojin Kim <boojin.kim@samsung.com>
Thu, 25 Oct 2018 03:20:58 +0000 (12:20 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:07 +0000 (20:23 +0300)
Change-Id: I9ce6fdb2367c031a0b776cb77fb54fac3944a43a
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
fs/f2fs/data.c
fs/f2fs/f2fs.h

index 17eaa739d95bb85b1ac694be047ad0d3c61fa61a..46c412c5df3ba0397a00080fc60eaf9bb7b16170 100644 (file)
@@ -83,6 +83,37 @@ struct bio_post_read_ctx {
        unsigned int enabled_steps;
 };
 
+static inline bool f2fs_may_encrypt_bio(struct inode *inode,
+               struct f2fs_io_info *fio)
+{
+       if (fio && (fio->type != DATA || fio->encrypted_page))
+               return false;
+
+       return (f2fs_encrypted_file(inode) &&
+                       fscrypt_disk_encrypted(inode));
+}
+
+static inline bool f2fs_bio_disk_encrypted(unsigned int bi_opf)
+{
+       if (bi_opf & REQ_CRYPT)
+               return true;
+       else
+               return false;
+}
+
+static bool f2fs_mergeable_bio(struct bio *bio, void *ci, bool bio_encrypted)
+{
+       if (!bio)
+               return true;
+
+       /* if both of them are not encrypted, no further check is needed */
+       if (!f2fs_bio_disk_encrypted(bio->bi_opf) && !bio_encrypted)
+               return true;
+
+       /* ICE allows only consecutive iv_key stream. */
+       return bio->bi_aux_private == ci;
+}
+
 static void __read_end_io(struct bio *bio)
 {
        struct page *page;
@@ -150,6 +181,9 @@ static void f2fs_read_end_io(struct bio *bio)
                bio->bi_status = BLK_STS_IOERR;
        }
 
+       if(f2fs_bio_disk_encrypted(bio->bi_opf))
+               goto end_io;
+
        if (f2fs_bio_post_read_required(bio)) {
                struct bio_post_read_ctx *ctx = bio->bi_private;
 
@@ -165,6 +199,7 @@ static void f2fs_read_end_io(struct bio *bio)
                                                bio->bi_iter.bi_size);
        }
 
+end_io:
        __read_end_io(bio);
 }
 
@@ -371,7 +406,10 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
        if (!io->bio)
                return;
 
-       bio_set_op_attrs(io->bio, fio->op, fio->op_flags);
+       if (f2fs_bio_disk_encrypted(io->bio->bi_opf))
+               bio_set_op_attrs(io->bio, fio->op, fio->op_flags | REQ_CRYPT);
+       else
+               bio_set_op_attrs(io->bio, fio->op, fio->op_flags);
 
        if (is_read_io(fio->op))
                trace_f2fs_prepare_read_bio(io->sbi->sb, fio->type, io->bio);
@@ -486,6 +524,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
        struct bio *bio;
        struct page *page = fio->encrypted_page ?
                        fio->encrypted_page : fio->page;
+       struct inode *inode = fio->page->mapping->host;
 
        if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
                        __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC))
@@ -509,6 +548,9 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
        fio->op_flags |= fio->encrypted_page ? REQ_NOENCRYPT : 0;
        bio_set_op_attrs(bio, fio->op, fio->op_flags);
 
+       if (f2fs_may_encrypt_bio(inode, fio))
+               fscrypt_set_bio(inode, bio);
+
        inc_page_count(fio->sbi, is_read_io(fio->op) ?
                        __read_io_type(page): WB_DATA_TYPE(fio->page));
 
@@ -522,6 +564,8 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio)
        enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
        struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp;
        struct page *bio_page;
+       struct inode *inode;
+       bool bio_encrypted;
 
        f2fs_bug_on(sbi, is_read_io(fio->op));
 
@@ -544,6 +588,8 @@ next:
        verify_block_addr(fio, fio->new_blkaddr);
 
        bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;
+       inode = fio->page->mapping->host;
+       bio_encrypted = f2fs_may_encrypt_bio(inode, fio);
        fio->op_flags |= fio->encrypted_page ? REQ_NOENCRYPT : 0;
 
        /* set submitted = true as a return value */
@@ -555,6 +601,10 @@ next:
            (io->fio.op != fio->op || io->fio.op_flags != fio->op_flags) ||
                        !__same_bdev(sbi, fio->new_blkaddr, io->bio)))
                __submit_merged_bio(io);
+
+       if (!f2fs_mergeable_bio(io->bio, fscrypt_get_diskcipher(inode), bio_encrypted))
+               __submit_merged_bio(io);
+
 alloc_new:
        if (io->bio == NULL) {
                if ((fio->type == DATA || fio->type == NODE) &&
@@ -566,6 +616,9 @@ alloc_new:
                io->bio = __bio_alloc(sbi, fio->new_blkaddr, fio->io_wbc,
                                                BIO_MAX_PAGES, false,
                                                fio->type, fio->temp);
+               if (bio_encrypted)
+                       fscrypt_set_bio(inode, io->bio);
+
                io->fio = *fio;
        }
 
@@ -609,7 +662,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
        bio->bi_end_io = f2fs_read_end_io;
        bio_set_op_attrs(bio, REQ_OP_READ, op_flag);
 
-       if (f2fs_encrypted_file(inode))
+       if (f2fs_encrypted_file(inode) && !fscrypt_disk_encrypted(inode))
                post_read_steps |= 1 << STEP_DECRYPT;
        if (post_read_steps) {
                ctx = mempool_alloc(bio_post_read_ctx_pool, GFP_NOFS);
@@ -645,6 +698,10 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
                bio_put(bio);
                return -EFAULT;
        }
+
+       if (f2fs_may_encrypt_bio(inode, NULL))
+               fscrypt_set_bio(inode, bio);
+
        ClearPageError(page);
        inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
        __f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
@@ -1568,6 +1625,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
        sector_t last_block_in_file;
        sector_t block_nr;
        struct f2fs_map_blocks map;
+       bool bio_encrypted;
 
        map.m_pblk = 0;
        map.m_lblk = 0;
@@ -1649,6 +1707,13 @@ submit_and_realloc:
                        __f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
                        bio = NULL;
                }
+
+               bio_encrypted = f2fs_may_encrypt_bio(inode, NULL);
+               if (!f2fs_mergeable_bio(bio, fscrypt_get_diskcipher(inode), bio_encrypted)) {
+                       __submit_bio(F2FS_I_SB(inode), bio, DATA);
+                       bio = NULL;
+               }
+
                if (bio == NULL) {
                        bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
                                        is_readahead ? REQ_RAHEAD : 0);
@@ -1656,6 +1721,8 @@ submit_and_realloc:
                                bio = NULL;
                                goto set_error_page;
                        }
+                       if (f2fs_may_encrypt_bio(inode, NULL))
+                               fscrypt_set_bio(inode, bio);
                }
 
                /*
@@ -1736,6 +1803,9 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
        f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);
 
 retry_encrypt:
+       if (fscrypt_disk_encrypted(inode))
+               return 0;
+
        fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
                        PAGE_SIZE, 0, fio->page->index, gfp_flags);
        if (IS_ERR(fio->encrypted_page)) {
index 0ae019b79e0c4a20b66277558b9a7a9ade8a19a3..889a797b4312123f4ae3cd6eadb9e2ae33540a28 100644 (file)
@@ -3639,7 +3639,8 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        int rw = iov_iter_rw(iter);
 
-       if (f2fs_post_read_required(inode))
+       if (f2fs_post_read_required(inode) &&
+               !fscrypt_disk_encrypted(inode))
                return true;
        if (sbi->s_ndevs)
                return true;