f2fs: make gc_urgent and gc_segment_mode sysfs node readable
[linux-2.6-microblaze.git] / fs / f2fs / sysfs.c
index 8408f77..fb950a1 100644 (file)
@@ -41,6 +41,16 @@ enum {
        ATGC_INFO,      /* struct atgc_management */
 };
 
+static const char *gc_mode_names[MAX_GC_MODE] = {
+       "GC_NORMAL",
+       "GC_IDLE_CB",
+       "GC_IDLE_GREEDY",
+       "GC_IDLE_AT",
+       "GC_URGENT_HIGH",
+       "GC_URGENT_LOW",
+       "GC_URGENT_MID"
+};
+
 struct f2fs_attr {
        struct attribute attr;
        ssize_t (*show)(struct f2fs_attr *, struct f2fs_sb_info *, char *);
@@ -118,6 +128,15 @@ static ssize_t sb_status_show(struct f2fs_attr *a,
        return sprintf(buf, "%lx\n", sbi->s_flag);
 }
 
+static ssize_t pending_discard_show(struct f2fs_attr *a,
+               struct f2fs_sb_info *sbi, char *buf)
+{
+       if (!SM_I(sbi)->dcc_info)
+               return -EINVAL;
+       return sprintf(buf, "%llu\n", (unsigned long long)atomic_read(
+                               &SM_I(sbi)->dcc_info->discard_cmd_cnt));
+}
+
 static ssize_t features_show(struct f2fs_attr *a,
                struct f2fs_sb_info *sbi, char *buf)
 {
@@ -307,8 +326,13 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a,
                return sysfs_emit(buf, "%u\n", sbi->compr_new_inode);
 #endif
 
+       if (!strcmp(a->attr.name, "gc_urgent"))
+               return sysfs_emit(buf, "%s\n",
+                               gc_mode_names[sbi->gc_mode]);
+
        if (!strcmp(a->attr.name, "gc_segment_mode"))
-               return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode);
+               return sysfs_emit(buf, "%s\n",
+                               gc_mode_names[sbi->gc_segment_mode]);
 
        if (!strcmp(a->attr.name, "gc_reclaimed_segments")) {
                return sysfs_emit(buf, "%u\n",
@@ -354,7 +378,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
                if (!strlen(name) || strlen(name) >= F2FS_EXTENSION_LEN)
                        return -EINVAL;
 
-               down_write(&sbi->sb_lock);
+               f2fs_down_write(&sbi->sb_lock);
 
                ret = f2fs_update_extension_list(sbi, name, hot, set);
                if (ret)
@@ -364,7 +388,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
                if (ret)
                        f2fs_update_extension_list(sbi, name, hot, !set);
 out:
-               up_write(&sbi->sb_lock);
+               f2fs_up_write(&sbi->sb_lock);
                return ret ? ret : count;
        }
 
@@ -414,7 +438,9 @@ out:
        if (a->struct_type == RESERVED_BLOCKS) {
                spin_lock(&sbi->stat_lock);
                if (t > (unsigned long)(sbi->user_block_count -
-                               F2FS_OPTION(sbi).root_reserved_blocks)) {
+                               F2FS_OPTION(sbi).root_reserved_blocks -
+                               sbi->blocks_per_seg *
+                               SM_I(sbi)->additional_reserved_segments)) {
                        spin_unlock(&sbi->stat_lock);
                        return -EINVAL;
                }
@@ -457,6 +483,13 @@ out:
                        }
                } else if (t == 2) {
                        sbi->gc_mode = GC_URGENT_LOW;
+               } else if (t == 3) {
+                       sbi->gc_mode = GC_URGENT_MID;
+                       if (sbi->gc_thread) {
+                               sbi->gc_thread->gc_wake = 1;
+                               wake_up_interruptible_all(
+                                       &sbi->gc_thread->gc_wait_queue_head);
+                       }
                } else {
                        return -EINVAL;
                }
@@ -470,13 +503,22 @@ out:
                } else if (t == GC_IDLE_AT) {
                        if (!sbi->am.atgc_enabled)
                                return -EINVAL;
-                       sbi->gc_mode = GC_AT;
+                       sbi->gc_mode = GC_IDLE_AT;
                } else {
                        sbi->gc_mode = GC_NORMAL;
                }
                return count;
        }
 
+       if (!strcmp(a->attr.name, "gc_urgent_high_remaining")) {
+               spin_lock(&sbi->gc_urgent_high_lock);
+               sbi->gc_urgent_high_limited = t != 0;
+               sbi->gc_urgent_high_remaining = t;
+               spin_unlock(&sbi->gc_urgent_high_lock);
+
+               return count;
+       }
+
 #ifdef CONFIG_F2FS_IOSTAT
        if (!strcmp(a->attr.name, "iostat_enable")) {
                sbi->iostat_enable = !!t;
@@ -696,6 +738,10 @@ F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_idle, gc_mode);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent, gc_mode);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_small_discards, max_discards);
+F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_request, max_discard_request);
+F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, min_discard_issue_time, min_discard_issue_time);
+F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, mid_discard_issue_time, mid_discard_issue_time);
+F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, max_discard_issue_time, max_discard_issue_time);
 F2FS_RW_ATTR(DCC_INFO, discard_cmd_control, discard_granularity, discard_granularity);
 F2FS_RW_ATTR(RESERVED_BLOCKS, f2fs_sb_info, reserved_blocks, reserved_blocks);
 F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections);
@@ -708,6 +754,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ssr_sections, min_ssr_sections);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages);
 F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio);
+F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, max_roll_forward_node_blocks, max_rf_node_blocks);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, max_victim_search, max_victim_search);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, migration_granularity, migration_granularity);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, dir_level, dir_level);
@@ -732,6 +779,7 @@ F2FS_RW_ATTR(FAULT_INFO_TYPE, f2fs_fault_info, inject_type, inject_type);
 #endif
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, data_io_flag, data_io_flag);
 F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, node_io_flag, node_io_flag);
+F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_urgent_high_remaining, gc_urgent_high_remaining);
 F2FS_RW_ATTR(CPRC_INFO, ckpt_req_control, ckpt_thread_ioprio, ckpt_thread_ioprio);
 F2FS_GENERAL_RO_ATTR(dirty_segments);
 F2FS_GENERAL_RO_ATTR(free_segments);
@@ -743,6 +791,7 @@ F2FS_GENERAL_RO_ATTR(unusable);
 F2FS_GENERAL_RO_ATTR(encoding);
 F2FS_GENERAL_RO_ATTR(mounted_time_sec);
 F2FS_GENERAL_RO_ATTR(main_blkaddr);
+F2FS_GENERAL_RO_ATTR(pending_discard);
 #ifdef CONFIG_F2FS_STAT_FS
 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_foreground_calls, cp_count);
 F2FS_STAT_ATTR(STAT_INFO, f2fs_stat_info, cp_background_calls, bg_cp_count);
@@ -810,7 +859,12 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(reclaim_segments),
        ATTR_LIST(main_blkaddr),
        ATTR_LIST(max_small_discards),
+       ATTR_LIST(max_discard_request),
+       ATTR_LIST(min_discard_issue_time),
+       ATTR_LIST(mid_discard_issue_time),
+       ATTR_LIST(max_discard_issue_time),
        ATTR_LIST(discard_granularity),
+       ATTR_LIST(pending_discard),
        ATTR_LIST(batched_trim_sections),
        ATTR_LIST(ipu_policy),
        ATTR_LIST(min_ipu_util),
@@ -824,6 +878,7 @@ static struct attribute *f2fs_attrs[] = {
        ATTR_LIST(ram_thresh),
        ATTR_LIST(ra_nid_pages),
        ATTR_LIST(dirty_nats_ratio),
+       ATTR_LIST(max_roll_forward_node_blocks),
        ATTR_LIST(cp_interval),
        ATTR_LIST(idle_interval),
        ATTR_LIST(discard_idle_interval),
@@ -843,6 +898,7 @@ static struct attribute *f2fs_attrs[] = {
 #endif
        ATTR_LIST(data_io_flag),
        ATTR_LIST(node_io_flag),
+       ATTR_LIST(gc_urgent_high_remaining),
        ATTR_LIST(ckpt_thread_ioprio),
        ATTR_LIST(dirty_segments),
        ATTR_LIST(free_segments),