Merge tag 'nfsd-6.1-6' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
[platform/kernel/linux-starfive.git] / fs / f2fs / gc.c
index 6da21d4..4546e01 100644 (file)
@@ -74,7 +74,8 @@ static int gc_thread_func(void *data)
 
                if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
                        f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
-                       f2fs_stop_checkpoint(sbi, false);
+                       f2fs_stop_checkpoint(sbi, false,
+                                       STOP_CP_REASON_FAULT_INJECT);
                }
 
                if (!sb_start_write_trylock(sbi->sb)) {
@@ -97,14 +98,10 @@ static int gc_thread_func(void *data)
                 */
                if (sbi->gc_mode == GC_URGENT_HIGH) {
                        spin_lock(&sbi->gc_urgent_high_lock);
-                       if (sbi->gc_urgent_high_limited) {
-                               if (!sbi->gc_urgent_high_remaining) {
-                                       sbi->gc_urgent_high_limited = false;
-                                       spin_unlock(&sbi->gc_urgent_high_lock);
-                                       sbi->gc_mode = GC_NORMAL;
-                                       continue;
-                               }
+                       if (sbi->gc_urgent_high_remaining) {
                                sbi->gc_urgent_high_remaining--;
+                               if (!sbi->gc_urgent_high_remaining)
+                                       sbi->gc_mode = GC_NORMAL;
                        }
                        spin_unlock(&sbi->gc_urgent_high_lock);
                }
@@ -285,7 +282,7 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
 
        /* let's select beginning hot/small space first in no_heap mode*/
        if (f2fs_need_rand_seg(sbi))
-               p->offset = prandom_u32() % (MAIN_SECS(sbi) * sbi->segs_per_sec);
+               p->offset = prandom_u32_max(MAIN_SECS(sbi) * sbi->segs_per_sec);
        else if (test_opt(sbi, NOHEAP) &&
                (type == CURSEG_HOT_DATA || IS_NODESEG(type)))
                p->offset = 0;
@@ -1082,7 +1079,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
 {
        struct page *node_page;
        nid_t nid;
-       unsigned int ofs_in_node;
+       unsigned int ofs_in_node, max_addrs;
        block_t source_blkaddr;
 
        nid = le32_to_cpu(sum->nid);
@@ -1108,6 +1105,14 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
                return false;
        }
 
+       max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
+                                               DEF_ADDRS_PER_BLOCK;
+       if (ofs_in_node >= max_addrs) {
+               f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
+                       ofs_in_node, dni->ino, dni->nid, max_addrs);
+               return false;
+       }
+
        *nofs = ofs_of_node(node_page);
        source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node);
        f2fs_put_page(node_page, 1);
@@ -1159,6 +1164,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
                if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr,
                                                DATA_GENERIC_ENHANCE_READ))) {
                        err = -EFSCORRUPTED;
+                       f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                        goto put_page;
                }
                goto got_it;
@@ -1177,6 +1183,7 @@ static int ra_data_block(struct inode *inode, pgoff_t index)
        if (unlikely(!f2fs_is_valid_blkaddr(sbi, dn.data_blkaddr,
                                                DATA_GENERIC_ENHANCE))) {
                err = -EFSCORRUPTED;
+               f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
                goto put_page;
        }
 got_it:
@@ -1206,8 +1213,8 @@ got_it:
        f2fs_put_page(fio.encrypted_page, 0);
        f2fs_put_page(page, 1);
 
-       f2fs_update_iostat(sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
-       f2fs_update_iostat(sbi, FS_GDATA_READ_IO, F2FS_BLKSIZE);
+       f2fs_update_iostat(sbi, inode, FS_DATA_READ_IO, F2FS_BLKSIZE);
+       f2fs_update_iostat(sbi, NULL, FS_GDATA_READ_IO, F2FS_BLKSIZE);
 
        return 0;
 put_encrypted_page:
@@ -1307,8 +1314,10 @@ static int move_data_block(struct inode *inode, block_t bidx,
                        goto up_out;
                }
 
-               f2fs_update_iostat(fio.sbi, FS_DATA_READ_IO, F2FS_BLKSIZE);
-               f2fs_update_iostat(fio.sbi, FS_GDATA_READ_IO, F2FS_BLKSIZE);
+               f2fs_update_iostat(fio.sbi, inode, FS_DATA_READ_IO,
+                                                       F2FS_BLKSIZE);
+               f2fs_update_iostat(fio.sbi, NULL, FS_GDATA_READ_IO,
+                                                       F2FS_BLKSIZE);
 
                lock_page(mpage);
                if (unlikely(mpage->mapping != META_MAPPING(fio.sbi) ||
@@ -1360,7 +1369,7 @@ static int move_data_block(struct inode *inode, block_t bidx,
                goto put_page_out;
        }
 
-       f2fs_update_iostat(fio.sbi, FS_GC_DATA_IO, F2FS_BLKSIZE);
+       f2fs_update_iostat(fio.sbi, NULL, FS_GC_DATA_IO, F2FS_BLKSIZE);
 
        f2fs_update_data_blkaddr(&dn, newaddr);
        set_inode_flag(inode, FI_APPEND_WRITE);
@@ -1706,7 +1715,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
                        f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
                                 segno, type, GET_SUM_TYPE((&sum->footer)));
                        set_sbi_flag(sbi, SBI_NEED_FSCK);
-                       f2fs_stop_checkpoint(sbi, false);
+                       f2fs_stop_checkpoint(sbi, false,
+                               STOP_CP_REASON_CORRUPTED_SUMMARY);
                        goto skip;
                }