Merge tag 'afs-next-20200604' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowel...
[platform/kernel/linux-rpi.git] / fs / ext4 / inode.c
index 2bbb55d..40ec5c7 100644 (file)
@@ -221,6 +221,16 @@ void ext4_evict_inode(struct inode *inode)
        truncate_inode_pages_final(&inode->i_data);
 
        /*
+        * For inodes with journalled data, transaction commit could have
+        * dirtied the inode. Flush worker is ignoring it because of I_FREEING
+        * flag but we still need to remove the inode from the writeback lists.
+        */
+       if (!list_empty_careful(&inode->i_io_list)) {
+               WARN_ON_ONCE(!ext4_should_journal_data(inode));
+               inode_io_list_del(inode);
+       }
+
+       /*
         * Protect us against freezing - iput() caller didn't have to have any
         * protection against it
         */
@@ -432,11 +442,9 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
         */
        down_read(&EXT4_I(inode)->i_data_sem);
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
-               retval = ext4_ext_map_blocks(handle, inode, map, flags &
-                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+               retval = ext4_ext_map_blocks(handle, inode, map, 0);
        } else {
-               retval = ext4_ind_map_blocks(handle, inode, map, flags &
-                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+               retval = ext4_ind_map_blocks(handle, inode, map, 0);
        }
        up_read((&EXT4_I(inode)->i_data_sem));
 
@@ -493,9 +501,8 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 #endif
 
        map->m_flags = 0;
-       ext_debug("ext4_map_blocks(): inode %lu, flag %d, max_blocks %u,"
-                 "logical block %lu\n", inode->i_ino, flags, map->m_len,
-                 (unsigned long) map->m_lblk);
+       ext_debug(inode, "flag 0x%x, max_blocks %u, logical block %lu\n",
+                 flags, map->m_len, (unsigned long) map->m_lblk);
 
        /*
         * ext4_map_blocks returns an int, and m_len is an unsigned int
@@ -541,11 +548,9 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
         */
        down_read(&EXT4_I(inode)->i_data_sem);
        if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
-               retval = ext4_ext_map_blocks(handle, inode, map, flags &
-                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+               retval = ext4_ext_map_blocks(handle, inode, map, 0);
        } else {
-               retval = ext4_ind_map_blocks(handle, inode, map, flags &
-                                            EXT4_GET_BLOCKS_KEEP_SIZE);
+               retval = ext4_ind_map_blocks(handle, inode, map, 0);
        }
        if (retval > 0) {
                unsigned int status;
@@ -726,6 +731,9 @@ out_sem:
                                return ret;
                }
        }
+
+       if (retval < 0)
+               ext_debug(inode, "failed with err %d\n", retval);
        return retval;
 }
 
@@ -1296,7 +1304,7 @@ static int ext4_write_end(struct file *file,
         * filesystems.
         */
        if (i_size_changed || inline_data)
-               ext4_mark_inode_dirty(handle, inode);
+               ret = ext4_mark_inode_dirty(handle, inode);
 
        if (pos + len > inode->i_size && !verity && ext4_can_truncate(inode))
                /* if we have allocated more blocks and copied
@@ -1526,6 +1534,7 @@ struct mpage_da_data {
        struct ext4_map_blocks map;
        struct ext4_io_submit io_submit;        /* IO submission data */
        unsigned int do_map:1;
+       unsigned int scanned_until_end:1;
 };
 
 static void mpage_release_unused_pages(struct mpage_da_data *mpd,
@@ -1541,6 +1550,7 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
        if (mpd->first_page >= mpd->next_page)
                return;
 
+       mpd->scanned_until_end = 0;
        index = mpd->first_page;
        end   = mpd->next_page - 1;
        if (invalidate) {
@@ -1681,8 +1691,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,
                invalid_block = ~0;
 
        map->m_flags = 0;
-       ext_debug("ext4_da_map_blocks(): inode %lu, max_blocks %u,"
-                 "logical block %lu\n", inode->i_ino, map->m_len,
+       ext_debug(inode, "max_blocks %u, logical block %lu\n", map->m_len,
                  (unsigned long) map->m_lblk);
 
        /* Lookup extent status tree firstly */
@@ -2078,7 +2087,7 @@ static int mpage_submit_page(struct mpage_da_data *mpd, struct page *page)
        return err;
 }
 
-#define BH_FLAGS ((1 << BH_Unwritten) | (1 << BH_Delay))
+#define BH_FLAGS (BIT(BH_Unwritten) | BIT(BH_Delay))
 
 /*
  * mballoc gives us at most this number of blocks...
@@ -2188,7 +2197,11 @@ static int mpage_process_page_bufs(struct mpage_da_data *mpd,
                if (err < 0)
                        return err;
        }
-       return lblk < blocks;
+       if (lblk >= blocks) {
+               mpd->scanned_until_end = 1;
+               return 0;
+       }
+       return 1;
 }
 
 /*
@@ -2311,7 +2324,7 @@ static int mpage_map_and_submit_buffers(struct mpage_da_data *mpd)
                         * mapping, or maybe the page was submitted for IO.
                         * So we return to call further extent mapping.
                         */
-                       if (err < 0 || map_bh == true)
+                       if (err < 0 || map_bh)
                                goto out;
                        /* Page fully mapped - let IO run! */
                        err = mpage_submit_page(mpd, page);
@@ -2358,7 +2371,7 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd)
        dioread_nolock = ext4_should_dioread_nolock(inode);
        if (dioread_nolock)
                get_blocks_flags |= EXT4_GET_BLOCKS_IO_CREATE_EXT;
-       if (map->m_flags & (1 << BH_Delay))
+       if (map->m_flags & BIT(BH_Delay))
                get_blocks_flags |= EXT4_GET_BLOCKS_DELALLOC_RESERVE;
 
        err = ext4_map_blocks(handle, inode, map, get_blocks_flags);
@@ -2546,7 +2559,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
                nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
                                tag);
                if (nr_pages == 0)
-                       goto out;
+                       break;
 
                for (i = 0; i < nr_pages; i++) {
                        struct page *page = pvec.pages[i];
@@ -2601,6 +2614,7 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
                pagevec_release(&pvec);
                cond_resched();
        }
+       mpd->scanned_until_end = 1;
        return 0;
 out:
        pagevec_release(&pvec);
@@ -2619,7 +2633,6 @@ static int ext4_writepages(struct address_space *mapping,
        struct inode *inode = mapping->host;
        int needed_blocks, rsv_blocks = 0, ret = 0;
        struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
-       bool done;
        struct blk_plug plug;
        bool give_up_on_write = false;
 
@@ -2705,7 +2718,6 @@ static int ext4_writepages(struct address_space *mapping,
 retry:
        if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages)
                tag_pages_for_writeback(mapping, mpd.first_page, mpd.last_page);
-       done = false;
        blk_start_plug(&plug);
 
        /*
@@ -2715,6 +2727,7 @@ retry:
         * started.
         */
        mpd.do_map = 0;
+       mpd.scanned_until_end = 0;
        mpd.io_submit.io_end = ext4_init_io_end(inode, GFP_KERNEL);
        if (!mpd.io_submit.io_end) {
                ret = -ENOMEM;
@@ -2730,7 +2743,7 @@ retry:
        if (ret < 0)
                goto unplug;
 
-       while (!done && mpd.first_page <= mpd.last_page) {
+       while (!mpd.scanned_until_end && wbc->nr_to_write > 0) {
                /* For each extent of pages we use new io_end */
                mpd.io_submit.io_end = ext4_init_io_end(inode, GFP_KERNEL);
                if (!mpd.io_submit.io_end) {
@@ -2765,20 +2778,9 @@ retry:
 
                trace_ext4_da_write_pages(inode, mpd.first_page, mpd.wbc);
                ret = mpage_prepare_extent_to_map(&mpd);
-               if (!ret) {
-                       if (mpd.map.m_len)
-                               ret = mpage_map_and_submit_extent(handle, &mpd,
+               if (!ret && mpd.map.m_len)
+                       ret = mpage_map_and_submit_extent(handle, &mpd,
                                        &give_up_on_write);
-                       else {
-                               /*
-                                * We scanned the whole range (or exhausted
-                                * nr_to_write), submitted what was mapped and
-                                * didn't find anything needing mapping. We are
-                                * done.
-                                */
-                               done = true;
-                       }
-               }
                /*
                 * Caution: If the handle is synchronous,
                 * ext4_journal_stop() can wait for transaction commit
@@ -3077,7 +3079,7 @@ static int ext4_da_write_end(struct file *file,
                         * new_i_size is less that inode->i_size
                         * bu greater than i_disksize.(hint delalloc)
                         */
-                       ext4_mark_inode_dirty(handle, inode);
+                       ret = ext4_mark_inode_dirty(handle, inode);
                }
        }
 
@@ -3094,7 +3096,7 @@ static int ext4_da_write_end(struct file *file,
        if (ret2 < 0)
                ret = ret2;
        ret2 = ext4_journal_stop(handle);
-       if (!ret)
+       if (unlikely(ret2 && !ret))
                ret = ret2;
 
        return ret ? ret : copied;
@@ -3224,23 +3226,20 @@ static int ext4_readpage(struct file *file, struct page *page)
                ret = ext4_readpage_inline(inode, page);
 
        if (ret == -EAGAIN)
-               return ext4_mpage_readpages(page->mapping, NULL, page, 1,
-                                               false);
+               return ext4_mpage_readpages(inode, NULL, page);
 
        return ret;
 }
 
-static int
-ext4_readpages(struct file *file, struct address_space *mapping,
-               struct list_head *pages, unsigned nr_pages)
+static void ext4_readahead(struct readahead_control *rac)
 {
-       struct inode *inode = mapping->host;
+       struct inode *inode = rac->mapping->host;
 
-       /* If the file has inline data, no need to do readpages. */
+       /* If the file has inline data, no need to do readahead. */
        if (ext4_has_inline_data(inode))
-               return 0;
+               return;
 
-       return ext4_mpage_readpages(mapping, pages, NULL, nr_pages, true);
+       ext4_mpage_readpages(inode, rac, NULL);
 }
 
 static void ext4_invalidatepage(struct page *page, unsigned int offset,
@@ -3605,7 +3604,7 @@ static int ext4_set_page_dirty(struct page *page)
 
 static const struct address_space_operations ext4_aops = {
        .readpage               = ext4_readpage,
-       .readpages              = ext4_readpages,
+       .readahead              = ext4_readahead,
        .writepage              = ext4_writepage,
        .writepages             = ext4_writepages,
        .write_begin            = ext4_write_begin,
@@ -3622,7 +3621,7 @@ static const struct address_space_operations ext4_aops = {
 
 static const struct address_space_operations ext4_journalled_aops = {
        .readpage               = ext4_readpage,
-       .readpages              = ext4_readpages,
+       .readahead              = ext4_readahead,
        .writepage              = ext4_writepage,
        .writepages             = ext4_writepages,
        .write_begin            = ext4_write_begin,
@@ -3638,7 +3637,7 @@ static const struct address_space_operations ext4_journalled_aops = {
 
 static const struct address_space_operations ext4_da_aops = {
        .readpage               = ext4_readpage,
-       .readpages              = ext4_readpages,
+       .readahead              = ext4_readahead,
        .writepage              = ext4_writepage,
        .writepages             = ext4_writepages,
        .write_begin            = ext4_da_write_begin,
@@ -3886,6 +3885,8 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
                                      loff_t len)
 {
        handle_t *handle;
+       int ret;
+
        loff_t size = i_size_read(inode);
 
        WARN_ON(!inode_is_locked(inode));
@@ -3899,10 +3900,10 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ext4_update_i_disksize(inode, size);
-       ext4_mark_inode_dirty(handle, inode);
+       ret = ext4_mark_inode_dirty(handle, inode);
        ext4_journal_stop(handle);
 
-       return 0;
+       return ret;
 }
 
 static void ext4_wait_dax_page(struct ext4_inode_info *ei)
@@ -3954,7 +3955,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
        loff_t first_block_offset, last_block_offset;
        handle_t *handle;
        unsigned int credits;
-       int ret = 0;
+       int ret = 0, ret2 = 0;
 
        trace_ext4_punch_hole(inode, offset, length, 0);
 
@@ -4077,7 +4078,9 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
                ext4_handle_sync(handle);
 
        inode->i_mtime = inode->i_ctime = current_time(inode);
-       ext4_mark_inode_dirty(handle, inode);
+       ret2 = ext4_mark_inode_dirty(handle, inode);
+       if (unlikely(ret2))
+               ret = ret2;
        if (ret >= 0)
                ext4_update_inode_fsync_trans(handle, inode, 1);
 out_stop:
@@ -4146,7 +4149,7 @@ int ext4_truncate(struct inode *inode)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
        unsigned int credits;
-       int err = 0;
+       int err = 0, err2;
        handle_t *handle;
        struct address_space *mapping = inode->i_mapping;
 
@@ -4234,7 +4237,9 @@ out_stop:
                ext4_orphan_del(handle, inode);
 
        inode->i_mtime = inode->i_ctime = current_time(inode);
-       ext4_mark_inode_dirty(handle, inode);
+       err2 = ext4_mark_inode_dirty(handle, inode);
+       if (unlikely(err2 && !err))
+               err = err2;
        ext4_journal_stop(handle);
 
        trace_ext4_truncate_exit(inode);
@@ -5292,6 +5297,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        inode->i_gid = attr->ia_gid;
                error = ext4_mark_inode_dirty(handle, inode);
                ext4_journal_stop(handle);
+               if (unlikely(error))
+                       return error;
        }
 
        if (attr->ia_valid & ATTR_SIZE) {
@@ -5777,7 +5784,8 @@ out_unlock:
  * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync)
  * we start and wait on commits.
  */
-int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
+int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
+                               const char *func, unsigned int line)
 {
        struct ext4_iloc iloc;
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -5787,13 +5795,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
        trace_ext4_mark_inode_dirty(inode, _RET_IP_);
        err = ext4_reserve_inode_write(handle, inode, &iloc);
        if (err)
-               return err;
+               goto out;
 
        if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
                ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
                                               iloc, handle);
 
-       return ext4_mark_iloc_dirty(handle, inode, &iloc);
+       err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+out:
+       if (unlikely(err))
+               ext4_error_inode_err(inode, func, line, 0, err,
+                                       "mark_inode_dirty error");
+       return err;
 }
 
 /*