f2fs: use generic EFSBADCRC/EFSCORRUPTED
[platform/kernel/linux-rpi.git] / fs / f2fs / data.c
index b7c9b58..9511466 100644 (file)
@@ -80,7 +80,8 @@ static void __read_end_io(struct bio *bio)
                /* PG_error was set if any post_read step failed */
                if (bio->bi_status || PageError(page)) {
                        ClearPageUptodate(page);
-                       SetPageError(page);
+                       /* will re-read again later */
+                       ClearPageError(page);
                } else {
                        SetPageUptodate(page);
                }
@@ -126,12 +127,10 @@ static bool f2fs_bio_post_read_required(struct bio *bio)
 
 static void f2fs_read_end_io(struct bio *bio)
 {
-#ifdef CONFIG_F2FS_FAULT_INJECTION
        if (time_to_inject(F2FS_P_SB(bio_first_page_all(bio)), FAULT_IO)) {
                f2fs_show_injection_info(FAULT_IO);
                bio->bi_status = BLK_STS_IOERR;
        }
-#endif
 
        if (f2fs_bio_post_read_required(bio)) {
                struct bio_post_read_ctx *ctx = bio->bi_private;
@@ -177,6 +176,8 @@ static void f2fs_write_end_io(struct bio *bio)
                                        page->index != nid_of_node(page));
 
                dec_page_count(sbi, type);
+               if (f2fs_in_warm_node_list(sbi, page))
+                       f2fs_del_fsync_node_entry(sbi, page);
                clear_cold_data(page);
                end_page_writeback(page);
        }
@@ -196,12 +197,14 @@ struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi,
        struct block_device *bdev = sbi->sb->s_bdev;
        int i;
 
-       for (i = 0; i < sbi->s_ndevs; i++) {
-               if (FDEV(i).start_blk <= blk_addr &&
-                                       FDEV(i).end_blk >= blk_addr) {
-                       blk_addr -= FDEV(i).start_blk;
-                       bdev = FDEV(i).bdev;
-                       break;
+       if (f2fs_is_multi_device(sbi)) {
+               for (i = 0; i < sbi->s_ndevs; i++) {
+                       if (FDEV(i).start_blk <= blk_addr &&
+                           FDEV(i).end_blk >= blk_addr) {
+                               blk_addr -= FDEV(i).start_blk;
+                               bdev = FDEV(i).bdev;
+                               break;
+                       }
                }
        }
        if (bio) {
@@ -215,6 +218,9 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr)
 {
        int i;
 
+       if (!f2fs_is_multi_device(sbi))
+               return 0;
+
        for (i = 0; i < sbi->s_ndevs; i++)
                if (FDEV(i).start_blk <= blkaddr && FDEV(i).end_blk >= blkaddr)
                        return i;
@@ -264,7 +270,7 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi,
                if (type != DATA && type != NODE)
                        goto submit_io;
 
-               if (f2fs_sb_has_blkzoned(sbi->sb) && current->plug)
+               if (test_opt(sbi, LFS) && current->plug)
                        blk_finish_plug(current->plug);
 
                start = bio->bi_iter.bi_size >> F2FS_BLKSIZE_BITS;
@@ -441,7 +447,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
        struct page *page = fio->encrypted_page ?
                        fio->encrypted_page : fio->page;
 
-       verify_block_addr(fio, fio->new_blkaddr);
+       if (!f2fs_is_valid_blkaddr(fio->sbi, fio->new_blkaddr,
+                       __is_meta_io(fio) ? META_GENERIC : DATA_GENERIC))
+               return -EFSCORRUPTED;
+
        trace_f2fs_submit_page_bio(page, fio);
        f2fs_trace_ios(fio, 0);
 
@@ -453,12 +462,16 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
                bio_put(bio);
                return -EFAULT;
        }
-       bio_set_op_attrs(bio, fio->op, fio->op_flags);
 
-       __submit_bio(fio->sbi, bio, fio->type);
+       if (fio->io_wbc && !is_read_io(fio->op))
+               wbc_account_io(fio->io_wbc, page, PAGE_SIZE);
+
+       bio_set_op_attrs(bio, fio->op, fio->op_flags);
 
        if (!is_read_io(fio->op))
                inc_page_count(fio->sbi, WB_DATA_TYPE(fio->page));
+
+       __submit_bio(fio->sbi, bio, fio->type);
        return 0;
 }
 
@@ -485,7 +498,7 @@ next:
                spin_unlock(&io->io_lock);
        }
 
-       if (is_valid_blkaddr(fio->old_blkaddr))
+       if (__is_valid_data_blkaddr(fio->old_blkaddr))
                verify_block_addr(fio, fio->old_blkaddr);
        verify_block_addr(fio, fio->new_blkaddr);
 
@@ -534,19 +547,22 @@ out:
 }
 
 static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
-                                                        unsigned nr_pages)
+                                       unsigned nr_pages, unsigned op_flag)
 {
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct bio *bio;
        struct bio_post_read_ctx *ctx;
        unsigned int post_read_steps = 0;
 
+       if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC))
+               return ERR_PTR(-EFAULT);
+
        bio = f2fs_bio_alloc(sbi, min_t(int, nr_pages, BIO_MAX_PAGES), false);
        if (!bio)
                return ERR_PTR(-ENOMEM);
        f2fs_target_device(sbi, blkaddr, bio);
        bio->bi_end_io = f2fs_read_end_io;
-       bio_set_op_attrs(bio, REQ_OP_READ, 0);
+       bio_set_op_attrs(bio, REQ_OP_READ, op_flag);
 
        if (f2fs_encrypted_file(inode))
                post_read_steps |= 1 << STEP_DECRYPT;
@@ -571,7 +587,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,
 static int f2fs_submit_page_read(struct inode *inode, struct page *page,
                                                        block_t blkaddr)
 {
-       struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1);
+       struct bio *bio = f2fs_grab_read_bio(inode, blkaddr, 1, 0);
 
        if (IS_ERR(bio))
                return PTR_ERR(bio);
@@ -580,6 +596,7 @@ static int f2fs_submit_page_read(struct inode *inode, struct page *page,
                bio_put(bio);
                return -EFAULT;
        }
+       ClearPageError(page);
        __submit_bio(F2FS_I_SB(inode), bio, DATA);
        return 0;
 }
@@ -869,6 +886,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
        struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
        struct f2fs_summary sum;
        struct node_info ni;
+       block_t old_blkaddr;
        pgoff_t fofs;
        blkcnt_t count = 1;
        int err;
@@ -876,6 +894,10 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
        if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC)))
                return -EPERM;
 
+       err = f2fs_get_node_info(sbi, dn->nid, &ni);
+       if (err)
+               return err;
+
        dn->data_blkaddr = datablock_addr(dn->inode,
                                dn->node_page, dn->ofs_in_node);
        if (dn->data_blkaddr == NEW_ADDR)
@@ -885,11 +907,13 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
                return err;
 
 alloc:
-       f2fs_get_node_info(sbi, dn->nid, &ni);
        set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
-
-       f2fs_allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
+       old_blkaddr = dn->data_blkaddr;
+       f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr,
                                        &sum, seg_type, NULL, false);
+       if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO)
+               invalidate_mapping_pages(META_MAPPING(sbi),
+                                       old_blkaddr, old_blkaddr);
        f2fs_set_data_blkaddr(dn);
 
        /* update i_size */
@@ -1045,7 +1069,13 @@ next_dnode:
 next_block:
        blkaddr = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node);
 
-       if (!is_valid_blkaddr(blkaddr)) {
+       if (__is_valid_data_blkaddr(blkaddr) &&
+               !f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC)) {
+               err = -EFSCORRUPTED;
+               goto sync_out;
+       }
+
+       if (!is_valid_data_blkaddr(sbi, blkaddr)) {
                if (create) {
                        if (unlikely(f2fs_cp_error(sbi))) {
                                err = -EIO;
@@ -1282,7 +1312,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               f2fs_get_node_info(sbi, inode->i_ino, &ni);
+               err = f2fs_get_node_info(sbi, inode->i_ino, &ni);
+               if (err) {
+                       f2fs_put_page(page, 1);
+                       return err;
+               }
 
                phys = (__u64)blk_to_logical(inode, ni.blk_addr);
                offset = offsetof(struct f2fs_inode, i_addr) +
@@ -1309,7 +1343,11 @@ static int f2fs_xattr_fiemap(struct inode *inode,
                if (!page)
                        return -ENOMEM;
 
-               f2fs_get_node_info(sbi, xnid, &ni);
+               err = f2fs_get_node_info(sbi, xnid, &ni);
+               if (err) {
+                       f2fs_put_page(page, 1);
+                       return err;
+               }
 
                phys = (__u64)blk_to_logical(inode, ni.blk_addr);
                len = inode->i_sb->s_blocksize;
@@ -1425,11 +1463,11 @@ out:
  * Note that the aops->readpages() function is ONLY used for read-ahead. If
  * this function ever deviates from doing just read-ahead, it should either
  * use ->readpage() or do the necessary surgery to decouple ->readpages()
- * readom read-ahead.
+ * from read-ahead.
  */
 static int f2fs_mpage_readpages(struct address_space *mapping,
                        struct list_head *pages, struct page *page,
-                       unsigned nr_pages)
+                       unsigned nr_pages, bool is_readahead)
 {
        struct bio *bio = NULL;
        sector_t last_block_in_bio = 0;
@@ -1500,6 +1538,10 @@ got_it:
                                SetPageUptodate(page);
                                goto confused;
                        }
+
+                       if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr,
+                                                               DATA_GENERIC))
+                               goto set_error_page;
                } else {
                        zero_user_segment(page, 0, PAGE_SIZE);
                        if (!PageUptodate(page))
@@ -1519,7 +1561,8 @@ submit_and_realloc:
                        bio = NULL;
                }
                if (bio == NULL) {
-                       bio = f2fs_grab_read_bio(inode, block_nr, nr_pages);
+                       bio = f2fs_grab_read_bio(inode, block_nr, nr_pages,
+                                       is_readahead ? REQ_RAHEAD : 0);
                        if (IS_ERR(bio)) {
                                bio = NULL;
                                goto set_error_page;
@@ -1529,6 +1572,7 @@ submit_and_realloc:
                if (bio_add_page(bio, page, blocksize, 0) < blocksize)
                        goto submit_and_realloc;
 
+               ClearPageError(page);
                last_block_in_bio = block_nr;
                goto next_page;
 set_error_page:
@@ -1563,7 +1607,7 @@ static int f2fs_read_data_page(struct file *file, struct page *page)
        if (f2fs_has_inline_data(inode))
                ret = f2fs_read_inline_data(inode, page);
        if (ret == -EAGAIN)
-               ret = f2fs_mpage_readpages(page->mapping, NULL, page, 1);
+               ret = f2fs_mpage_readpages(page->mapping, NULL, page, 1, false);
        return ret;
 }
 
@@ -1580,12 +1624,13 @@ static int f2fs_read_data_pages(struct file *file,
        if (f2fs_has_inline_data(inode))
                return 0;
 
-       return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages);
+       return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages, true);
 }
 
 static int encrypt_one_page(struct f2fs_io_info *fio)
 {
        struct inode *inode = fio->page->mapping->host;
+       struct page *mpage;
        gfp_t gfp_flags = GFP_NOFS;
 
        if (!f2fs_encrypted_file(inode))
@@ -1597,17 +1642,25 @@ static int encrypt_one_page(struct f2fs_io_info *fio)
 retry_encrypt:
        fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page,
                        PAGE_SIZE, 0, fio->page->index, gfp_flags);
-       if (!IS_ERR(fio->encrypted_page))
-               return 0;
+       if (IS_ERR(fio->encrypted_page)) {
+               /* flush pending IOs and wait for a while in the ENOMEM case */
+               if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
+                       f2fs_flush_merged_writes(fio->sbi);
+                       congestion_wait(BLK_RW_ASYNC, HZ/50);
+                       gfp_flags |= __GFP_NOFAIL;
+                       goto retry_encrypt;
+               }
+               return PTR_ERR(fio->encrypted_page);
+       }
 
-       /* flush pending IOs and wait for a while in the ENOMEM case */
-       if (PTR_ERR(fio->encrypted_page) == -ENOMEM) {
-               f2fs_flush_merged_writes(fio->sbi);
-               congestion_wait(BLK_RW_ASYNC, HZ/50);
-               gfp_flags |= __GFP_NOFAIL;
-               goto retry_encrypt;
+       mpage = find_lock_page(META_MAPPING(fio->sbi), fio->old_blkaddr);
+       if (mpage) {
+               if (PageUptodate(mpage))
+                       memcpy(page_address(mpage),
+                               page_address(fio->encrypted_page), PAGE_SIZE);
+               f2fs_put_page(mpage, 1);
        }
-       return PTR_ERR(fio->encrypted_page);
+       return 0;
 }
 
 static inline bool check_inplace_update_policy(struct inode *inode,
@@ -1691,6 +1744,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
        struct inode *inode = page->mapping->host;
        struct dnode_of_data dn;
        struct extent_info ei = {0,0,0};
+       struct node_info ni;
        bool ipu_force = false;
        int err = 0;
 
@@ -1699,11 +1753,13 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
                        f2fs_lookup_extent_cache(inode, page->index, &ei)) {
                fio->old_blkaddr = ei.blk + page->index - ei.fofs;
 
-               if (is_valid_blkaddr(fio->old_blkaddr)) {
-                       ipu_force = true;
-                       fio->need_lock = LOCK_DONE;
-                       goto got_it;
-               }
+               if (!f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
+                                                       DATA_GENERIC))
+                       return -EFSCORRUPTED;
+
+               ipu_force = true;
+               fio->need_lock = LOCK_DONE;
+               goto got_it;
        }
 
        /* Deadlock due to between page->lock and f2fs_lock_op */
@@ -1722,11 +1778,17 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio)
                goto out_writepage;
        }
 got_it:
+       if (__is_valid_data_blkaddr(fio->old_blkaddr) &&
+               !f2fs_is_valid_blkaddr(fio->sbi, fio->old_blkaddr,
+                                                       DATA_GENERIC)) {
+               err = -EFSCORRUPTED;
+               goto out_writepage;
+       }
        /*
         * If current allocation needs SSR,
         * it had better in-place writes for updated data.
         */
-       if (ipu_force || (is_valid_blkaddr(fio->old_blkaddr) &&
+       if (ipu_force || (is_valid_data_blkaddr(fio->sbi, fio->old_blkaddr) &&
                                        need_inplace_update(fio))) {
                err = encrypt_one_page(fio);
                if (err)
@@ -1751,6 +1813,12 @@ got_it:
                fio->need_lock = LOCK_REQ;
        }
 
+       err = f2fs_get_node_info(fio->sbi, dn.nid, &ni);
+       if (err)
+               goto out_writepage;
+
+       fio->version = ni.version;
+
        err = encrypt_one_page(fio);
        if (err)
                goto out_writepage;
@@ -2079,6 +2147,18 @@ continue_unlock:
        return ret;
 }
 
+static inline bool __should_serialize_io(struct inode *inode,
+                                       struct writeback_control *wbc)
+{
+       if (!S_ISREG(inode->i_mode))
+               return false;
+       if (wbc->sync_mode != WB_SYNC_ALL)
+               return true;
+       if (get_dirty_pages(inode) >= SM_I(F2FS_I_SB(inode))->min_seq_blocks)
+               return true;
+       return false;
+}
+
 static int __f2fs_write_data_pages(struct address_space *mapping,
                                                struct writeback_control *wbc,
                                                enum iostat_type io_type)
@@ -2087,6 +2167,7 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
        struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
        struct blk_plug plug;
        int ret;
+       bool locked = false;
 
        /* deal with chardevs and other special file */
        if (!mapping->a_ops->writepage)
@@ -2117,10 +2198,18 @@ static int __f2fs_write_data_pages(struct address_space *mapping,
        else if (atomic_read(&sbi->wb_sync_req[DATA]))
                goto skip_write;
 
+       if (__should_serialize_io(inode, wbc)) {
+               mutex_lock(&sbi->writepages);
+               locked = true;
+       }
+
        blk_start_plug(&plug);
        ret = f2fs_write_cache_pages(mapping, wbc, io_type);
        blk_finish_plug(&plug);
 
+       if (locked)
+               mutex_unlock(&sbi->writepages);
+
        if (wbc->sync_mode == WB_SYNC_ALL)
                atomic_dec(&sbi->wb_sync_req[DATA]);
        /*
@@ -2153,10 +2242,14 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to)
        loff_t i_size = i_size_read(inode);
 
        if (to > i_size) {
+               down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
                down_write(&F2FS_I(inode)->i_mmap_sem);
+
                truncate_pagecache(inode, i_size);
                f2fs_truncate_blocks(inode, i_size, true);
+
                up_write(&F2FS_I(inode)->i_mmap_sem);
+               up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
        }
 }
 
@@ -2171,6 +2264,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
        bool locked = false;
        struct extent_info ei = {0,0,0};
        int err = 0;
+       int flag;
 
        /*
         * we already allocated all the blocks, so we don't need to get
@@ -2180,9 +2274,15 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
                        !is_inode_flag_set(inode, FI_NO_PREALLOC))
                return 0;
 
+       /* f2fs_lock_op avoids race between write CP and convert_inline_page */
+       if (f2fs_has_inline_data(inode) && pos + len > MAX_INLINE_DATA(inode))
+               flag = F2FS_GET_BLOCK_DEFAULT;
+       else
+               flag = F2FS_GET_BLOCK_PRE_AIO;
+
        if (f2fs_has_inline_data(inode) ||
                        (pos & PAGE_MASK) >= i_size_read(inode)) {
-               __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, true);
+               __do_map_lock(sbi, flag, true);
                locked = true;
        }
 restart:
@@ -2220,6 +2320,7 @@ restart:
                                f2fs_put_dnode(&dn);
                                __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO,
                                                                true);
+                               WARN_ON(flag != F2FS_GET_BLOCK_PRE_AIO);
                                locked = true;
                                goto restart;
                        }
@@ -2233,7 +2334,7 @@ out:
        f2fs_put_dnode(&dn);
 unlock_out:
        if (locked)
-               __do_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO, false);
+               __do_map_lock(sbi, flag, false);
        return err;
 }
 
@@ -2251,8 +2352,9 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
 
        trace_f2fs_write_begin(inode, pos, len, flags);
 
-       if (f2fs_is_atomic_file(inode) &&
-                       !f2fs_available_free_memory(sbi, INMEM_PAGES)) {
+       if ((f2fs_is_atomic_file(inode) &&
+                       !f2fs_available_free_memory(sbi, INMEM_PAGES)) ||
+                       is_inode_flag_set(inode, FI_ATOMIC_REVOKE_REQUEST)) {
                err = -ENOMEM;
                drop_atomic = true;
                goto fail;
@@ -2376,14 +2478,20 @@ unlock_out:
 static int check_direct_IO(struct inode *inode, struct iov_iter *iter,
                           loff_t offset)
 {
-       unsigned blocksize_mask = inode->i_sb->s_blocksize - 1;
-
-       if (offset & blocksize_mask)
-               return -EINVAL;
-
-       if (iov_iter_alignment(iter) & blocksize_mask)
-               return -EINVAL;
-
+       unsigned i_blkbits = READ_ONCE(inode->i_blkbits);
+       unsigned blkbits = i_blkbits;
+       unsigned blocksize_mask = (1 << blkbits) - 1;
+       unsigned long align = offset | iov_iter_alignment(iter);
+       struct block_device *bdev = inode->i_sb->s_bdev;
+
+       if (align & blocksize_mask) {
+               if (bdev)
+                       blkbits = blksize_bits(bdev_logical_block_size(bdev));
+               blocksize_mask = (1 << blkbits) - 1;
+               if (align & blocksize_mask)
+                       return -EINVAL;
+               return 1;
+       }
        return 0;
 }
 
@@ -2401,7 +2509,7 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
        err = check_direct_IO(inode, iter, offset);
        if (err)
-               return err;
+               return err < 0 ? err : 0;
 
        if (f2fs_force_buffered_io(inode, rw))
                return 0;