lkml.org 
[lkml]   [2019]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.19 088/205] f2fs: avoid wrong decrypted data from disk
    Date
    From: Jaegeuk Kim <jaegeuk@kernel.org>

    [ Upstream commit 0ded69f632bb717be9aeea3ae74e29050fcb060c ]

    1. Create a file in an encrypted directory
    2. Do GC & drop caches
    3. Read stale data before its bio for metapage was not issued yet

    Reviewed-by: Chao Yu <yuchao0@huawei.com>
    Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/f2fs/data.c | 18 ++++++++++--------
    fs/f2fs/f2fs.h | 2 +-
    fs/f2fs/file.c | 3 +--
    fs/f2fs/segment.c | 6 +++++-
    4 files changed, 17 insertions(+), 12 deletions(-)

    diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
    index 9511466bc7857..c61beaedf0789 100644
    --- a/fs/f2fs/data.c
    +++ b/fs/f2fs/data.c
    @@ -575,9 +575,6 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
    ctx->bio = bio;
    ctx->enabled_steps = post_read_steps;
    bio->bi_private = ctx;
    -
    - /* wait the page to be moved by cleaning */
    - f2fs_wait_on_block_writeback(sbi, blkaddr);
    }

    return bio;
    @@ -592,6 +589,9 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
    if (IS_ERR(bio))
    return PTR_ERR(bio);

    + /* wait for GCed page writeback via META_MAPPING */
    + f2fs_wait_on_block_writeback(inode, blkaddr);
    +
    if (bio_add_page(bio, page, PAGE_SIZE, 0) < PAGE_SIZE) {
    bio_put(bio);
    return -EFAULT;
    @@ -1569,6 +1569,12 @@ submit_and_realloc:
    }
    }

    + /*
    + * If the page is under writeback, we need to wait for
    + * its completion to see the correct decrypted data.
    + */
    + f2fs_wait_on_block_writeback(inode, block_nr);
    +
    if (bio_add_page(bio, page, blocksize, 0) < blocksize)
    goto submit_and_realloc;

    @@ -1637,7 +1643,7 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
    return 0;

    /* wait for GCed page writeback via META_MAPPING */
    - f2fs_wait_on_block_writeback(fio->sbi, fio->old_blkaddr);
    + f2fs_wait_on_block_writeback(inode, fio->old_blkaddr);

    retry_encrypt:
    fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
    @@ -2402,10 +2408,6 @@ repeat:

    f2fs_wait_on_page_writeback(page, DATA, false);

    - /* wait for GCed page writeback via META_MAPPING */
    - if (f2fs_post_read_required(inode))
    - f2fs_wait_on_block_writeback(sbi, blkaddr);
    -
    if (len == PAGE_SIZE || PageUptodate(page))
    return 0;

    diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
    index fb216488d67a9..6d361c8c61306 100644
    --- a/fs/f2fs/f2fs.h
    +++ b/fs/f2fs/f2fs.h
    @@ -2973,7 +2973,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
    struct f2fs_io_info *fio, bool add_list);
    void f2fs_wait_on_page_writeback(struct page *page,
    enum page_type type, bool ordered);
    -void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr);
    +void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr);
    void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
    void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk);
    int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
    diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
    index 8d1eb8dec6058..6972c6d7c3893 100644
    --- a/fs/f2fs/file.c
    +++ b/fs/f2fs/file.c
    @@ -112,8 +112,7 @@ mapped:
    f2fs_wait_on_page_writeback(page, DATA, false);

    /* wait for GCed page writeback via META_MAPPING */
    - if (f2fs_post_read_required(inode))
    - f2fs_wait_on_block_writeback(sbi, dn.data_blkaddr);
    + f2fs_wait_on_block_writeback(inode, dn.data_blkaddr);

    out_sem:
    up_read(&F2FS_I(inode)->i_mmap_sem);
    diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
    index 10d5dcdb34be6..d78009694f3fd 100644
    --- a/fs/f2fs/segment.c
    +++ b/fs/f2fs/segment.c
    @@ -3214,10 +3214,14 @@ void f2fs_wait_on_page_writeback(struct page *page,
    }
    }

    -void f2fs_wait_on_block_writeback(struct f2fs_sb_info *sbi, block_t blkaddr)
    +void f2fs_wait_on_block_writeback(struct inode *inode, block_t blkaddr)
    {
    + struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
    struct page *cpage;

    + if (!f2fs_post_read_required(inode))
    + return;
    +
    if (!is_valid_data_blkaddr(sbi, blkaddr))
    return;

    --
    2.20.1
    \
     
     \ /
      Last update: 2019-11-08 13:10    [W:4.055 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site