For LFS mode, it should update outplace and no need inplace update.
When using LFS mode for small-volume devices, IPU will not be used,
and the OPU writing method is actually used, but F2FS_IPU_FORCE can
be read from the ipu_policy node, which is different from the actual
situation. And after remount, ipu should be disabled when convert to
lfs mode, let's fix it.
commit bdc48fa11e46 ("checkpatch/coding-style: deprecate 80-column
warning") increased the limit to 100 columns. BTW modify some unnecessary
newlines.
Fixes: 84b89e5d943d ("f2fs: add auto tuning for small devices")
Signed-off-by: Yangtao Li <[email protected]>
---
fs/f2fs/segment.h | 2 ++
fs/f2fs/super.c | 20 +++++++++-----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index ad6a9c19f46a..0b0eb8f03cba 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -670,6 +670,8 @@ static inline int utilization(struct f2fs_sb_info *sbi)
#define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */
+#define F2FS_IPU_DISABLE 0
+
enum {
F2FS_IPU_FORCE,
F2FS_IPU_SSR,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d8a65645ee48..ebc76683f05d 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2272,6 +2272,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
if (err)
goto restore_opts;
+ if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)
+ SM_I(sbi)->ipu_policy = F2FS_IPU_DISABLE;
+
/*
* Previous and new state of filesystem is RO,
* so skip checking GC and FLUSH_MERGE conditions.
@@ -4080,10 +4083,9 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
/* adjust parameters according to the volume size */
if (MAIN_SEGS(sbi) <= SMALL_VOLUME_SEGMENTS) {
if (f2fs_block_unit_discard(sbi))
- SM_I(sbi)->dcc_info->discard_granularity =
- MIN_DISCARD_GRANULARITY;
- SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) |
- BIT(F2FS_IPU_HONOR_OPU_WRITE);
+ SM_I(sbi)->dcc_info->discard_granularity = MIN_DISCARD_GRANULARITY;
+ if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS)
+ SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | BIT(F2FS_IPU_HONOR_OPU_WRITE);
}
sbi->readdir_ra = true;
@@ -4310,9 +4312,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
test_opt(sbi, MERGE_CHECKPOINT)) {
err = f2fs_start_ckpt_thread(sbi);
if (err) {
- f2fs_err(sbi,
- "Failed to start F2FS issue_checkpoint_thread (%d)",
- err);
+ f2fs_err(sbi, "Failed to start F2FS issue_checkpoint_thread (%d)", err);
goto stop_ckpt_thread;
}
}
@@ -4320,14 +4320,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
/* setup f2fs internal modules */
err = f2fs_build_segment_manager(sbi);
if (err) {
- f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)",
- err);
+ f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)", err);
goto free_sm;
}
err = f2fs_build_node_manager(sbi);
if (err) {
- f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)",
- err);
+ f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)", err);
goto free_nm;
}
--
2.25.1
Disallow the value set beyond the range, and disallow to change
the value in lfs mode.
BTW, convert open code to use BIT().
Signed-off-by: Yangtao Li <[email protected]>
---
fs/f2fs/segment.h | 1 +
fs/f2fs/sysfs.c | 11 ++++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 0b0eb8f03cba..d73e988566a5 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -681,6 +681,7 @@ enum {
F2FS_IPU_ASYNC,
F2FS_IPU_NOCACHE,
F2FS_IPU_HONOR_OPU_WRITE,
+ F2FS_IPU_MAX,
};
#define F2FS_IPU_POLICY(name) \
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index bdc761f36310..576e6416ffb9 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -452,7 +452,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
if (ret < 0)
return ret;
#ifdef CONFIG_F2FS_FAULT_INJECTION
- if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX))
+ if (a->struct_type == FAULT_INFO_TYPE && t >= BIT(FAULT_MAX))
return -EINVAL;
if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX)
return -EINVAL;
@@ -706,6 +706,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
return count;
}
+ if (!strcmp(a->attr.name, "ipu_policy")) {
+ if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)
+ return -EINVAL;
+ if (t >= BIT(F2FS_IPU_MAX))
+ return -EINVAL;
+ SM_I(sbi)->ipu_policy = (unsigned int)t;
+ return count;
+ }
+
*ui = (unsigned int)t;
return count;
--
2.25.1
Add a ipu_mode sysfs node to show the current ipu policy as a string.
Since we use ipu_policy as a bitmap, and the bitmap API parameter is
unsigned long type data, let's change ipu_policy to unsigned long type.
Signed-off-by: Yangtao Li <[email protected]>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++
fs/f2fs/f2fs.h | 4 ++--
fs/f2fs/segment.h | 1 +
fs/f2fs/sysfs.c | 26 +++++++++++++++++++++++++
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 0f17adc80488..64b15a28fe30 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -722,3 +722,9 @@ What: /sys/fs/f2fs/<disk>/last_age_weight
Date: January 2023
Contact: "Ping Xiong" <[email protected]>
Description: When DATA SEPARATION is on, it controls the weight of last data block age.
+
+What: /sys/fs/f2fs/<disk>/ipu_mode
+Date: January 2023
+Contact: "Yangtao Li" <[email protected]>
+Description: Show the current ipu policy as a string.
+ This is a read-only entry.
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9edad9ccc2cd..b221a3bdb3fe 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1071,7 +1071,7 @@ struct f2fs_sm_info {
struct list_head sit_entry_set; /* sit entry set list */
- unsigned int ipu_policy; /* in-place-update policy */
+ unsigned long ipu_policy; /* in-place-update policy */
unsigned int min_ipu_util; /* in-place-update threshold */
unsigned int min_fsync_blocks; /* threshold for fsync */
unsigned int min_seq_blocks; /* threshold for sequential blocks */
@@ -1323,7 +1323,7 @@ enum {
MAX_TIME,
};
-/* Note that you need to keep synchronization with this gc_mode_names array */
+/* Modification on enum should be synchronized with gc_mode_names array */
enum {
GC_NORMAL,
GC_IDLE_CB,
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index d73e988566a5..50c63155ad56 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -672,6 +672,7 @@ static inline int utilization(struct f2fs_sb_info *sbi)
#define F2FS_IPU_DISABLE 0
+/* Modification on enum should be synchronized with ipu_mode_names array */
enum {
F2FS_IPU_FORCE,
F2FS_IPU_SSR,
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 576e6416ffb9..aaf5d8650518 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -51,6 +51,17 @@ static const char *gc_mode_names[MAX_GC_MODE] = {
"GC_URGENT_MID"
};
+static const char *ipu_mode_names[F2FS_IPU_MAX] = {
+ "FORCE",
+ "SSR",
+ "UTIL",
+ "SSR_UTIL",
+ "FSYNC",
+ "ASYNC",
+ "NOCACHE",
+ "HONOR_OPU_WRITE",
+};
+
struct f2fs_attr {
struct attribute attr;
ssize_t (*show)(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf);
@@ -149,6 +160,19 @@ static ssize_t gc_mode_show(struct f2fs_attr *a,
return sysfs_emit(buf, "%s\n", gc_mode_names[sbi->gc_mode]);
}
+static ssize_t ipu_mode_show(struct f2fs_attr *a,
+ struct f2fs_sb_info *sbi, char *buf)
+{
+ int len = 0, i = 0;
+
+ if (SM_I(sbi)->ipu_policy == F2FS_IPU_DISABLE)
+ return sysfs_emit(buf, "DISABLE\n");
+
+ for_each_set_bit(i, &SM_I(sbi)->ipu_policy, F2FS_IPU_MAX)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", ipu_mode_names[i]);
+ return len;
+}
+
static ssize_t features_show(struct f2fs_attr *a,
struct f2fs_sb_info *sbi, char *buf)
{
@@ -907,6 +931,7 @@ F2FS_GENERAL_RO_ATTR(mounted_time_sec);
F2FS_GENERAL_RO_ATTR(main_blkaddr);
F2FS_GENERAL_RO_ATTR(pending_discard);
F2FS_GENERAL_RO_ATTR(gc_mode);
+F2FS_GENERAL_RO_ATTR(ipu_mode);
#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);
@@ -997,6 +1022,7 @@ static struct attribute *f2fs_attrs[] = {
ATTR_LIST(max_ordered_discard),
ATTR_LIST(pending_discard),
ATTR_LIST(gc_mode),
+ ATTR_LIST(ipu_mode),
ATTR_LIST(ipu_policy),
ATTR_LIST(min_ipu_util),
ATTR_LIST(min_fsync_blocks),
--
2.25.1
User can control f2fs ipu policy through /sys/fs/f2fs/<disk>/ipu_policy,
export related definitions and introduce new macro to make it more
convenient for users to use.
Signed-off-by: Yangtao Li <[email protected]>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 25 ++++++------
fs/f2fs/segment.c | 2 +-
fs/f2fs/segment.h | 37 ++---------------
fs/f2fs/super.c | 2 +-
fs/f2fs/sysfs.c | 2 +-
include/uapi/linux/f2fs.h | 54 +++++++++++++++++++++++++
6 files changed, 73 insertions(+), 49 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 64b15a28fe30..d05ad2bc56d1 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -49,18 +49,19 @@ Contact: "Jaegeuk Kim" <[email protected]>
Description: Controls the in-place-update policy.
updates in f2fs. User can set:
- ==== =================
- 0x01 F2FS_IPU_FORCE
- 0x02 F2FS_IPU_SSR
- 0x04 F2FS_IPU_UTIL
- 0x08 F2FS_IPU_SSR_UTIL
- 0x10 F2FS_IPU_FSYNC
- 0x20 F2FS_IPU_ASYNC
- 0x40 F2FS_IPU_NOCACHE
- 0x80 F2FS_IPU_HONOR_OPU_WRITE
- ==== =================
-
- Refer segment.h for details.
+ ==== ============================
+ 0x00 SET_F2FS_IPU_DISABLE
+ 0x01 SET_F2FS_IPU_FORCE
+ 0x02 SET_F2FS_IPU_SSR
+ 0x04 SET_F2FS_IPU_UTIL
+ 0x08 SET_F2FS_IPU_SSR_UTIL
+ 0x10 SET_F2FS_IPU_FSYNC
+ 0x20 SET_F2FS_IPU_ASYNC
+ 0x40 SET_F2FS_IPU_NOCACHE
+ 0x80 SET_F2FS_IPU_HONOR_OPU_WRITE
+ ==== ============================
+
+ Refer include/uapi/linux/f2fs.h for details.
What: /sys/fs/f2fs/<disk>/min_ipu_util
Date: November 2013
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index a007f5084e84..c56f5a80d3a6 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -5138,7 +5138,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
sm_info->rec_prefree_segments = DEF_MAX_RECLAIM_PREFREE_SEGMENTS;
if (!f2fs_lfs_mode(sbi))
- sm_info->ipu_policy = BIT(F2FS_IPU_FSYNC);
+ sm_info->ipu_policy = SET_F2FS_IPU_FSYNC;
sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;
sm_info->min_seq_blocks = sbi->blocks_per_seg;
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 50c63155ad56..c064ddffe91b 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -7,6 +7,7 @@
*/
#include <linux/blkdev.h>
#include <linux/backing-dev.h>
+#include <uapi/linux/f2fs.h>
/* constant macro */
#define NULL_SEGNO ((unsigned int)(~0))
@@ -646,51 +647,19 @@ static inline int utilization(struct f2fs_sb_info *sbi)
sbi->user_block_count);
}
-/*
- * Sometimes f2fs may be better to drop out-of-place update policy.
- * And, users can control the policy through sysfs entries.
- * There are five policies with triggering conditions as follows.
- * F2FS_IPU_FORCE - all the time,
- * F2FS_IPU_SSR - if SSR mode is activated,
- * F2FS_IPU_UTIL - if FS utilization is over threashold,
- * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
- * threashold,
- * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash
- * storages. IPU will be triggered only if the # of dirty
- * pages over min_fsync_blocks. (=default option)
- * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests.
- * F2FS_IPU_NOCACHE - disable IPU bio cache.
- * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has
- * FI_OPU_WRITE flag.
- * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode)
- */
#define DEF_MIN_IPU_UTIL 70
#define DEF_MIN_FSYNC_BLOCKS 8
#define DEF_MIN_HOT_BLOCKS 16
#define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */
-#define F2FS_IPU_DISABLE 0
-
-/* Modification on enum should be synchronized with ipu_mode_names array */
-enum {
- F2FS_IPU_FORCE,
- F2FS_IPU_SSR,
- F2FS_IPU_UTIL,
- F2FS_IPU_SSR_UTIL,
- F2FS_IPU_FSYNC,
- F2FS_IPU_ASYNC,
- F2FS_IPU_NOCACHE,
- F2FS_IPU_HONOR_OPU_WRITE,
- F2FS_IPU_MAX,
-};
-
#define F2FS_IPU_POLICY(name) \
static inline int IS_##name(struct f2fs_sb_info *sbi) \
{ \
- return SM_I(sbi)->ipu_policy & BIT(name); \
+ return TEST_##name(SM_I(sbi)->ipu_policy); \
}
+F2FS_IPU_POLICY(F2FS_IPU_DISABLE);
F2FS_IPU_POLICY(F2FS_IPU_FORCE);
F2FS_IPU_POLICY(F2FS_IPU_SSR);
F2FS_IPU_POLICY(F2FS_IPU_UTIL);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ebc76683f05d..b19085fa335a 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4085,7 +4085,7 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
if (f2fs_block_unit_discard(sbi))
SM_I(sbi)->dcc_info->discard_granularity = MIN_DISCARD_GRANULARITY;
if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS)
- SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | BIT(F2FS_IPU_HONOR_OPU_WRITE);
+ SM_I(sbi)->ipu_policy = SET_F2FS_IPU_FORCE | SET_F2FS_IPU_HONOR_OPU_WRITE;
}
sbi->readdir_ra = true;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index aaf5d8650518..375ace5f330d 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -165,7 +165,7 @@ static ssize_t ipu_mode_show(struct f2fs_attr *a,
{
int len = 0, i = 0;
- if (SM_I(sbi)->ipu_policy == F2FS_IPU_DISABLE)
+ if (IS_F2FS_IPU_DISABLE(sbi))
return sysfs_emit(buf, "DISABLE\n");
for_each_set_bit(i, &SM_I(sbi)->ipu_policy, F2FS_IPU_MAX)
diff --git a/include/uapi/linux/f2fs.h b/include/uapi/linux/f2fs.h
index 955d440be104..1b672fb6af91 100644
--- a/include/uapi/linux/f2fs.h
+++ b/include/uapi/linux/f2fs.h
@@ -5,6 +5,60 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+/*
+ * For /sys/fs/f2fs/<disk>/ipu_policy entry
+ *
+ * Sometimes f2fs may be better to drop out-of-place update policy.
+ * And, users can control the policy through sysfs entries.
+ * There are five policies with triggering conditions as follows.
+ * F2FS_IPU_FORCE - all the time,
+ * F2FS_IPU_SSR - if SSR mode is activated,
+ * F2FS_IPU_UTIL - if FS utilization is over threashold,
+ * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
+ * threashold,
+ * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash
+ * storages. IPU will be triggered only if the # of dirty
+ * pages over min_fsync_blocks. (=default option)
+ * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests.
+ * F2FS_IPU_NOCACHE - disable IPU bio cache.
+ * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has
+ * FI_OPU_WRITE flag.
+ * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode)
+ */
+#define F2FS_IPU_DISABLE 0
+/* Modification on enum should be synchronized with ipu_mode_names array */
+enum {
+ F2FS_IPU_FORCE,
+ F2FS_IPU_SSR,
+ F2FS_IPU_UTIL,
+ F2FS_IPU_SSR_UTIL,
+ F2FS_IPU_FSYNC,
+ F2FS_IPU_ASYNC,
+ F2FS_IPU_NOCACHE,
+ F2FS_IPU_HONOR_OPU_WRITE,
+ F2FS_IPU_MAX,
+};
+
+#define SET_F2FS_IPU_DISABLE F2FS_IPU_DISABLE
+#define SET_F2FS_IPU_FORCE BIT(F2FS_IPU_FORCE)
+#define SET_F2FS_IPU_SSR BIT(F2FS_IPU_SSR)
+#define SET_F2FS_IPU_UTIL BIT(F2FS_IPU_UTIL)
+#define SET_F2FS_IPU_SSR_UTIL BIT(F2FS_IPU_SSR_UTIL)
+#define SET_F2FS_IPU_FSYNC BIT(F2FS_IPU_FSYNC)
+#define SET_F2FS_IPU_ASYNC BIT(F2FS_IPU_ASYNC)
+#define SET_F2FS_IPU_NOCACHE BIT(F2FS_IPU_NOCACHE)
+#define SET_F2FS_IPU_HONOR_OPU_WRITE BIT(F2FS_IPU_HONOR_OPU_WRITE)
+
+#define TEST_F2FS_IPU_DISABLE(val) ((val) == F2FS_IPU_DISABLE)
+#define TEST_F2FS_IPU_FORCE(val) ((val) & BIT(F2FS_IPU_FORCE))
+#define TEST_F2FS_IPU_SSR(val) ((val) & BIT(F2FS_IPU_SSR))
+#define TEST_F2FS_IPU_UTIL(val) ((val) & BIT(F2FS_IPU_UTIL))
+#define TEST_F2FS_IPU_SSR_UTIL(val) ((val) & BIT(F2FS_IPU_SSR_UTIL))
+#define TEST_F2FS_IPU_FSYNC(val) ((val) & BIT(F2FS_IPU_FSYNC))
+#define TEST_F2FS_IPU_ASYNC(val) ((val) & BIT(F2FS_IPU_ASYNC))
+#define TEST_F2FS_IPU_NOCACHE(val) ((val) & BIT(F2FS_IPU_NOCACHE))
+#define TEST_F2FS_IPU_HONOR_OPU_WRITE(val) ((val) & BIT(F2FS_IPU_HONOR_OPU_WRITE))
+
/*
* f2fs-specific ioctl commands
*/
--
2.25.1
On 2023/1/20 21:40, Yangtao Li wrote:
> For LFS mode, it should update outplace and no need inplace update.
> When using LFS mode for small-volume devices, IPU will not be used,
> and the OPU writing method is actually used, but F2FS_IPU_FORCE can
> be read from the ipu_policy node, which is different from the actual
> situation. And after remount, ipu should be disabled when convert to
> lfs mode, let's fix it.
>
> commit bdc48fa11e46 ("checkpatch/coding-style: deprecate 80-column
> warning") increased the limit to 100 columns. BTW modify some unnecessary
> newlines.
>
> Fixes: 84b89e5d943d ("f2fs: add auto tuning for small devices")
> Signed-off-by: Yangtao Li <[email protected]>
> ---
> fs/f2fs/segment.h | 2 ++
> fs/f2fs/super.c | 20 +++++++++-----------
> 2 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index ad6a9c19f46a..0b0eb8f03cba 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -670,6 +670,8 @@ static inline int utilization(struct f2fs_sb_info *sbi)
>
> #define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */
>
> +#define F2FS_IPU_DISABLE 0
> +
> enum {
> F2FS_IPU_FORCE,
> F2FS_IPU_SSR,
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index d8a65645ee48..ebc76683f05d 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -2272,6 +2272,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
> if (err)
> goto restore_opts;
>
> + if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)
if (f2fs_lfs_mode())
> + SM_I(sbi)->ipu_policy = F2FS_IPU_DISABLE;
How about adding such restriction to f2fs_tuning_parameters()? For
f2fs_remount() and __sbi_store() cases, how about returning -EINVAL if
there is a conflict?
Thanks,
> +
> /*
> * Previous and new state of filesystem is RO,
> * so skip checking GC and FLUSH_MERGE conditions.
> @@ -4080,10 +4083,9 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
> /* adjust parameters according to the volume size */
> if (MAIN_SEGS(sbi) <= SMALL_VOLUME_SEGMENTS) {
> if (f2fs_block_unit_discard(sbi))
> - SM_I(sbi)->dcc_info->discard_granularity =
> - MIN_DISCARD_GRANULARITY;
> - SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) |
> - BIT(F2FS_IPU_HONOR_OPU_WRITE);
> + SM_I(sbi)->dcc_info->discard_granularity = MIN_DISCARD_GRANULARITY;
> + if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS)
> + SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | BIT(F2FS_IPU_HONOR_OPU_WRITE);
> }
>
> sbi->readdir_ra = true;
> @@ -4310,9 +4312,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
> test_opt(sbi, MERGE_CHECKPOINT)) {
> err = f2fs_start_ckpt_thread(sbi);
> if (err) {
> - f2fs_err(sbi,
> - "Failed to start F2FS issue_checkpoint_thread (%d)",
> - err);
> + f2fs_err(sbi, "Failed to start F2FS issue_checkpoint_thread (%d)", err);
> goto stop_ckpt_thread;
> }
> }
> @@ -4320,14 +4320,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
> /* setup f2fs internal modules */
> err = f2fs_build_segment_manager(sbi);
> if (err) {
> - f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)",
> - err);
> + f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)", err);
> goto free_sm;
> }
> err = f2fs_build_node_manager(sbi);
> if (err) {
> - f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)",
> - err);
> + f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)", err);
> goto free_nm;
> }
>
On 2023/1/20 21:40, Yangtao Li wrote:
> Disallow the value set beyond the range, and disallow to change
> the value in lfs mode.
IMO, it's better to merge this patch into 1/4.
>
> BTW, convert open code to use BIT().
How about using one patch to change 1 << xx to BIT(xx) for all cases
of f2fs rather than one by one?
Thanks,
>
> Signed-off-by: Yangtao Li <[email protected]>
> ---
> fs/f2fs/segment.h | 1 +
> fs/f2fs/sysfs.c | 11 ++++++++++-
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index 0b0eb8f03cba..d73e988566a5 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -681,6 +681,7 @@ enum {
> F2FS_IPU_ASYNC,
> F2FS_IPU_NOCACHE,
> F2FS_IPU_HONOR_OPU_WRITE,
> + F2FS_IPU_MAX,
> };
>
> #define F2FS_IPU_POLICY(name) \
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index bdc761f36310..576e6416ffb9 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -452,7 +452,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
> if (ret < 0)
> return ret;
> #ifdef CONFIG_F2FS_FAULT_INJECTION
> - if (a->struct_type == FAULT_INFO_TYPE && t >= (1 << FAULT_MAX))
> + if (a->struct_type == FAULT_INFO_TYPE && t >= BIT(FAULT_MAX))
> return -EINVAL;
> if (a->struct_type == FAULT_INFO_RATE && t >= UINT_MAX)
> return -EINVAL;
> @@ -706,6 +706,15 @@ static ssize_t __sbi_store(struct f2fs_attr *a,
> return count;
> }
>
> + if (!strcmp(a->attr.name, "ipu_policy")) {
> + if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)
> + return -EINVAL;
> + if (t >= BIT(F2FS_IPU_MAX))
> + return -EINVAL;
> + SM_I(sbi)->ipu_policy = (unsigned int)t;
> + return count;
> + }
> +
> *ui = (unsigned int)t;
>
> return count;
On 2023/1/20 21:40, Yangtao Li wrote:
> Add a ipu_mode sysfs node to show the current ipu policy as a string.
Why do we need to add another sysfs entry for ipu_policy? we can check
the description of ipu_policy bits in below sysfs document.
What: /sys/fs/f2fs/<disk>/ipu_policy
Date: November 2013
Contact: "Jaegeuk Kim" <[email protected]>
Description: Controls the in-place-update policy.
updates in f2fs. User can set:
==== =================
0x01 F2FS_IPU_FORCE
0x02 F2FS_IPU_SSR
0x04 F2FS_IPU_UTIL
0x08 F2FS_IPU_SSR_UTIL
0x10 F2FS_IPU_FSYNC
0x20 F2FS_IPU_ASYNC
0x40 F2FS_IPU_NOCACHE
0x80 F2FS_IPU_HONOR_OPU_WRITE
==== =================
Refer segment.h for details.
Thanks,
> Since we use ipu_policy as a bitmap, and the bitmap API parameter is
> unsigned long type data, let's change ipu_policy to unsigned long type.
>
> Signed-off-by: Yangtao Li <[email protected]>
> ---
> Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++++++
> fs/f2fs/f2fs.h | 4 ++--
> fs/f2fs/segment.h | 1 +
> fs/f2fs/sysfs.c | 26 +++++++++++++++++++++++++
> 4 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> index 0f17adc80488..64b15a28fe30 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -722,3 +722,9 @@ What: /sys/fs/f2fs/<disk>/last_age_weight
> Date: January 2023
> Contact: "Ping Xiong" <[email protected]>
> Description: When DATA SEPARATION is on, it controls the weight of last data block age.
> +
> +What: /sys/fs/f2fs/<disk>/ipu_mode
> +Date: January 2023
> +Contact: "Yangtao Li" <[email protected]>
> +Description: Show the current ipu policy as a string.
> + This is a read-only entry.
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 9edad9ccc2cd..b221a3bdb3fe 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1071,7 +1071,7 @@ struct f2fs_sm_info {
>
> struct list_head sit_entry_set; /* sit entry set list */
>
> - unsigned int ipu_policy; /* in-place-update policy */
> + unsigned long ipu_policy; /* in-place-update policy */
> unsigned int min_ipu_util; /* in-place-update threshold */
> unsigned int min_fsync_blocks; /* threshold for fsync */
> unsigned int min_seq_blocks; /* threshold for sequential blocks */
> @@ -1323,7 +1323,7 @@ enum {
> MAX_TIME,
> };
>
> -/* Note that you need to keep synchronization with this gc_mode_names array */
> +/* Modification on enum should be synchronized with gc_mode_names array */
> enum {
> GC_NORMAL,
> GC_IDLE_CB,
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index d73e988566a5..50c63155ad56 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -672,6 +672,7 @@ static inline int utilization(struct f2fs_sb_info *sbi)
>
> #define F2FS_IPU_DISABLE 0
>
> +/* Modification on enum should be synchronized with ipu_mode_names array */
> enum {
> F2FS_IPU_FORCE,
> F2FS_IPU_SSR,
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index 576e6416ffb9..aaf5d8650518 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -51,6 +51,17 @@ static const char *gc_mode_names[MAX_GC_MODE] = {
> "GC_URGENT_MID"
> };
>
> +static const char *ipu_mode_names[F2FS_IPU_MAX] = {
> + "FORCE",
> + "SSR",
> + "UTIL",
> + "SSR_UTIL",
> + "FSYNC",
> + "ASYNC",
> + "NOCACHE",
> + "HONOR_OPU_WRITE",
> +};
> +
> struct f2fs_attr {
> struct attribute attr;
> ssize_t (*show)(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf);
> @@ -149,6 +160,19 @@ static ssize_t gc_mode_show(struct f2fs_attr *a,
> return sysfs_emit(buf, "%s\n", gc_mode_names[sbi->gc_mode]);
> }
>
> +static ssize_t ipu_mode_show(struct f2fs_attr *a,
> + struct f2fs_sb_info *sbi, char *buf)
> +{
> + int len = 0, i = 0;
> +
> + if (SM_I(sbi)->ipu_policy == F2FS_IPU_DISABLE)
> + return sysfs_emit(buf, "DISABLE\n");
> +
> + for_each_set_bit(i, &SM_I(sbi)->ipu_policy, F2FS_IPU_MAX)
> + len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", ipu_mode_names[i]);
> + return len;
> +}
> +
> static ssize_t features_show(struct f2fs_attr *a,
> struct f2fs_sb_info *sbi, char *buf)
> {
> @@ -907,6 +931,7 @@ F2FS_GENERAL_RO_ATTR(mounted_time_sec);
> F2FS_GENERAL_RO_ATTR(main_blkaddr);
> F2FS_GENERAL_RO_ATTR(pending_discard);
> F2FS_GENERAL_RO_ATTR(gc_mode);
> +F2FS_GENERAL_RO_ATTR(ipu_mode);
> #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);
> @@ -997,6 +1022,7 @@ static struct attribute *f2fs_attrs[] = {
> ATTR_LIST(max_ordered_discard),
> ATTR_LIST(pending_discard),
> ATTR_LIST(gc_mode),
> + ATTR_LIST(ipu_mode),
> ATTR_LIST(ipu_policy),
> ATTR_LIST(min_ipu_util),
> ATTR_LIST(min_fsync_blocks),
On 2023/1/20 21:40, Yangtao Li wrote:
> User can control f2fs ipu policy through /sys/fs/f2fs/<disk>/ipu_policy,
> export related definitions and introduce new macro to make it more
> convenient for users to use.
>
> Signed-off-by: Yangtao Li <[email protected]>
> ---
> Documentation/ABI/testing/sysfs-fs-f2fs | 25 ++++++------
> fs/f2fs/segment.c | 2 +-
> fs/f2fs/segment.h | 37 ++---------------
> fs/f2fs/super.c | 2 +-
> fs/f2fs/sysfs.c | 2 +-
> include/uapi/linux/f2fs.h | 54 +++++++++++++++++++++++++
> 6 files changed, 73 insertions(+), 49 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
> index 64b15a28fe30..d05ad2bc56d1 100644
> --- a/Documentation/ABI/testing/sysfs-fs-f2fs
> +++ b/Documentation/ABI/testing/sysfs-fs-f2fs
> @@ -49,18 +49,19 @@ Contact: "Jaegeuk Kim" <[email protected]>
> Description: Controls the in-place-update policy.
> updates in f2fs. User can set:
>
> - ==== =================
> - 0x01 F2FS_IPU_FORCE
> - 0x02 F2FS_IPU_SSR
> - 0x04 F2FS_IPU_UTIL
> - 0x08 F2FS_IPU_SSR_UTIL
> - 0x10 F2FS_IPU_FSYNC
> - 0x20 F2FS_IPU_ASYNC
> - 0x40 F2FS_IPU_NOCACHE
> - 0x80 F2FS_IPU_HONOR_OPU_WRITE
> - ==== =================
> -
> - Refer segment.h for details.
> + ==== ============================
> + 0x00 SET_F2FS_IPU_DISABLE
> + 0x01 SET_F2FS_IPU_FORCE
> + 0x02 SET_F2FS_IPU_SSR
> + 0x04 SET_F2FS_IPU_UTIL
> + 0x08 SET_F2FS_IPU_SSR_UTIL
> + 0x10 SET_F2FS_IPU_FSYNC
> + 0x20 SET_F2FS_IPU_ASYNC
> + 0x40 SET_F2FS_IPU_NOCACHE
> + 0x80 SET_F2FS_IPU_HONOR_OPU_WRITE
> + ==== ============================
> +
> + Refer include/uapi/linux/f2fs.h for details.
>
> What: /sys/fs/f2fs/<disk>/min_ipu_util
> Date: November 2013
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index a007f5084e84..c56f5a80d3a6 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -5138,7 +5138,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi)
> sm_info->rec_prefree_segments = DEF_MAX_RECLAIM_PREFREE_SEGMENTS;
>
> if (!f2fs_lfs_mode(sbi))
> - sm_info->ipu_policy = BIT(F2FS_IPU_FSYNC);
> + sm_info->ipu_policy = SET_F2FS_IPU_FSYNC;
> sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
> sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;
> sm_info->min_seq_blocks = sbi->blocks_per_seg;
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index 50c63155ad56..c064ddffe91b 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -7,6 +7,7 @@
> */
> #include <linux/blkdev.h>
> #include <linux/backing-dev.h>
> +#include <uapi/linux/f2fs.h>
>
> /* constant macro */
> #define NULL_SEGNO ((unsigned int)(~0))
> @@ -646,51 +647,19 @@ static inline int utilization(struct f2fs_sb_info *sbi)
> sbi->user_block_count);
> }
>
> -/*
> - * Sometimes f2fs may be better to drop out-of-place update policy.
> - * And, users can control the policy through sysfs entries.
> - * There are five policies with triggering conditions as follows.
> - * F2FS_IPU_FORCE - all the time,
> - * F2FS_IPU_SSR - if SSR mode is activated,
> - * F2FS_IPU_UTIL - if FS utilization is over threashold,
> - * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
> - * threashold,
> - * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash
> - * storages. IPU will be triggered only if the # of dirty
> - * pages over min_fsync_blocks. (=default option)
> - * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests.
> - * F2FS_IPU_NOCACHE - disable IPU bio cache.
> - * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has
> - * FI_OPU_WRITE flag.
> - * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode)
> - */
IMO, we'd better to move these comments into sysfs-fs-f2fs as ipu_policy
interface's documents.
> #define DEF_MIN_IPU_UTIL 70
> #define DEF_MIN_FSYNC_BLOCKS 8
> #define DEF_MIN_HOT_BLOCKS 16
>
> #define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */
>
> -#define F2FS_IPU_DISABLE 0
> -
> -/* Modification on enum should be synchronized with ipu_mode_names array */
> -enum {
> - F2FS_IPU_FORCE,
> - F2FS_IPU_SSR,
> - F2FS_IPU_UTIL,
> - F2FS_IPU_SSR_UTIL,
> - F2FS_IPU_FSYNC,
> - F2FS_IPU_ASYNC,
> - F2FS_IPU_NOCACHE,
> - F2FS_IPU_HONOR_OPU_WRITE,
> - F2FS_IPU_MAX,
> -};
> -
> #define F2FS_IPU_POLICY(name) \
> static inline int IS_##name(struct f2fs_sb_info *sbi) \
> { \
> - return SM_I(sbi)->ipu_policy & BIT(name); \
> + return TEST_##name(SM_I(sbi)->ipu_policy); \
> }
>
> +F2FS_IPU_POLICY(F2FS_IPU_DISABLE);
> F2FS_IPU_POLICY(F2FS_IPU_FORCE);
> F2FS_IPU_POLICY(F2FS_IPU_SSR);
> F2FS_IPU_POLICY(F2FS_IPU_UTIL);
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index ebc76683f05d..b19085fa335a 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4085,7 +4085,7 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
> if (f2fs_block_unit_discard(sbi))
> SM_I(sbi)->dcc_info->discard_granularity = MIN_DISCARD_GRANULARITY;
> if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS)
> - SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | BIT(F2FS_IPU_HONOR_OPU_WRITE);
> + SM_I(sbi)->ipu_policy = SET_F2FS_IPU_FORCE | SET_F2FS_IPU_HONOR_OPU_WRITE;
> }
>
> sbi->readdir_ra = true;
> diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
> index aaf5d8650518..375ace5f330d 100644
> --- a/fs/f2fs/sysfs.c
> +++ b/fs/f2fs/sysfs.c
> @@ -165,7 +165,7 @@ static ssize_t ipu_mode_show(struct f2fs_attr *a,
> {
> int len = 0, i = 0;
>
> - if (SM_I(sbi)->ipu_policy == F2FS_IPU_DISABLE)
> + if (IS_F2FS_IPU_DISABLE(sbi))
> return sysfs_emit(buf, "DISABLE\n");
>
> for_each_set_bit(i, &SM_I(sbi)->ipu_policy, F2FS_IPU_MAX)
> diff --git a/include/uapi/linux/f2fs.h b/include/uapi/linux/f2fs.h
> index 955d440be104..1b672fb6af91 100644
> --- a/include/uapi/linux/f2fs.h
> +++ b/include/uapi/linux/f2fs.h
> @@ -5,6 +5,60 @@
> #include <linux/types.h>
> #include <linux/ioctl.h>
>
> +/*
> + * For /sys/fs/f2fs/<disk>/ipu_policy entry
> + *
> + * Sometimes f2fs may be better to drop out-of-place update policy.
> + * And, users can control the policy through sysfs entries.
> + * There are five policies with triggering conditions as follows.
> + * F2FS_IPU_FORCE - all the time,
> + * F2FS_IPU_SSR - if SSR mode is activated,
> + * F2FS_IPU_UTIL - if FS utilization is over threashold,
> + * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
> + * threashold,
> + * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash
> + * storages. IPU will be triggered only if the # of dirty
> + * pages over min_fsync_blocks. (=default option)
> + * F2FS_IPU_ASYNC - do IPU given by asynchronous write requests.
> + * F2FS_IPU_NOCACHE - disable IPU bio cache.
> + * F2FS_IPU_HONOR_OPU_WRITE - use OPU write prior to IPU write if inode has
> + * FI_OPU_WRITE flag.
> + * F2FS_IPU_DISABLE - disable IPU. (=default option in LFS mode)
> + */
> +#define F2FS_IPU_DISABLE 0
> +/* Modification on enum should be synchronized with ipu_mode_names array */
> +enum {
> + F2FS_IPU_FORCE,
> + F2FS_IPU_SSR,
> + F2FS_IPU_UTIL,
> + F2FS_IPU_SSR_UTIL,
> + F2FS_IPU_FSYNC,
> + F2FS_IPU_ASYNC,
> + F2FS_IPU_NOCACHE,
> + F2FS_IPU_HONOR_OPU_WRITE,
> + F2FS_IPU_MAX,
> +};
> +
> +#define SET_F2FS_IPU_DISABLE F2FS_IPU_DISABLE
> +#define SET_F2FS_IPU_FORCE BIT(F2FS_IPU_FORCE)
> +#define SET_F2FS_IPU_SSR BIT(F2FS_IPU_SSR)
> +#define SET_F2FS_IPU_UTIL BIT(F2FS_IPU_UTIL)
> +#define SET_F2FS_IPU_SSR_UTIL BIT(F2FS_IPU_SSR_UTIL)
> +#define SET_F2FS_IPU_FSYNC BIT(F2FS_IPU_FSYNC)
> +#define SET_F2FS_IPU_ASYNC BIT(F2FS_IPU_ASYNC)
> +#define SET_F2FS_IPU_NOCACHE BIT(F2FS_IPU_NOCACHE)
> +#define SET_F2FS_IPU_HONOR_OPU_WRITE BIT(F2FS_IPU_HONOR_OPU_WRITE)
> +
> +#define TEST_F2FS_IPU_DISABLE(val) ((val) == F2FS_IPU_DISABLE)
> +#define TEST_F2FS_IPU_FORCE(val) ((val) & BIT(F2FS_IPU_FORCE))
> +#define TEST_F2FS_IPU_SSR(val) ((val) & BIT(F2FS_IPU_SSR))
> +#define TEST_F2FS_IPU_UTIL(val) ((val) & BIT(F2FS_IPU_UTIL))
> +#define TEST_F2FS_IPU_SSR_UTIL(val) ((val) & BIT(F2FS_IPU_SSR_UTIL))
> +#define TEST_F2FS_IPU_FSYNC(val) ((val) & BIT(F2FS_IPU_FSYNC))
> +#define TEST_F2FS_IPU_ASYNC(val) ((val) & BIT(F2FS_IPU_ASYNC))
> +#define TEST_F2FS_IPU_NOCACHE(val) ((val) & BIT(F2FS_IPU_NOCACHE))
> +#define TEST_F2FS_IPU_HONOR_OPU_WRITE(val) ((val) & BIT(F2FS_IPU_HONOR_OPU_WRITE))
I don't see any strong reason to add these sysfs related definition to uapi,
according to other filesystems' implementation, I guess describing the usage
of ipu_policy clearly is enough.
Thanks,
> +
> /*
> * f2fs-specific ioctl commands
> */
Please adjust the comments based on v2.
On 01/28, Chao Yu wrote:
> On 2023/1/20 21:40, Yangtao Li wrote:
> > For LFS mode, it should update outplace and no need inplace update.
> > When using LFS mode for small-volume devices, IPU will not be used,
> > and the OPU writing method is actually used, but F2FS_IPU_FORCE can
> > be read from the ipu_policy node, which is different from the actual
> > situation. And after remount, ipu should be disabled when convert to
> > lfs mode, let's fix it.
> >
> > commit bdc48fa11e46 ("checkpatch/coding-style: deprecate 80-column
> > warning") increased the limit to 100 columns. BTW modify some unnecessary
> > newlines.
> >
> > Fixes: 84b89e5d943d ("f2fs: add auto tuning for small devices")
> > Signed-off-by: Yangtao Li <[email protected]>
> > ---
> > fs/f2fs/segment.h | 2 ++
> > fs/f2fs/super.c | 20 +++++++++-----------
> > 2 files changed, 11 insertions(+), 11 deletions(-)
> >
> > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> > index ad6a9c19f46a..0b0eb8f03cba 100644
> > --- a/fs/f2fs/segment.h
> > +++ b/fs/f2fs/segment.h
> > @@ -670,6 +670,8 @@ static inline int utilization(struct f2fs_sb_info *sbi)
> > #define SMALL_VOLUME_SEGMENTS (16 * 512) /* 16GB */
> > +#define F2FS_IPU_DISABLE 0
> > +
> > enum {
> > F2FS_IPU_FORCE,
> > F2FS_IPU_SSR,
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index d8a65645ee48..ebc76683f05d 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -2272,6 +2272,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
> > if (err)
> > goto restore_opts;
> > + if (F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS)
>
> if (f2fs_lfs_mode())
>
> > + SM_I(sbi)->ipu_policy = F2FS_IPU_DISABLE;
>
> How about adding such restriction to f2fs_tuning_parameters()? For
> f2fs_remount() and __sbi_store() cases, how about returning -EINVAL if
> there is a conflict?
>
> Thanks,
>
> > +
> > /*
> > * Previous and new state of filesystem is RO,
> > * so skip checking GC and FLUSH_MERGE conditions.
> > @@ -4080,10 +4083,9 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
> > /* adjust parameters according to the volume size */
> > if (MAIN_SEGS(sbi) <= SMALL_VOLUME_SEGMENTS) {
> > if (f2fs_block_unit_discard(sbi))
> > - SM_I(sbi)->dcc_info->discard_granularity =
> > - MIN_DISCARD_GRANULARITY;
> > - SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) |
> > - BIT(F2FS_IPU_HONOR_OPU_WRITE);
> > + SM_I(sbi)->dcc_info->discard_granularity = MIN_DISCARD_GRANULARITY;
> > + if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS)
> > + SM_I(sbi)->ipu_policy = BIT(F2FS_IPU_FORCE) | BIT(F2FS_IPU_HONOR_OPU_WRITE);
> > }
> > sbi->readdir_ra = true;
> > @@ -4310,9 +4312,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
> > test_opt(sbi, MERGE_CHECKPOINT)) {
> > err = f2fs_start_ckpt_thread(sbi);
> > if (err) {
> > - f2fs_err(sbi,
> > - "Failed to start F2FS issue_checkpoint_thread (%d)",
> > - err);
> > + f2fs_err(sbi, "Failed to start F2FS issue_checkpoint_thread (%d)", err);
> > goto stop_ckpt_thread;
> > }
> > }
> > @@ -4320,14 +4320,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
> > /* setup f2fs internal modules */
> > err = f2fs_build_segment_manager(sbi);
> > if (err) {
> > - f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)",
> > - err);
> > + f2fs_err(sbi, "Failed to initialize F2FS segment manager (%d)", err);
> > goto free_sm;
> > }
> > err = f2fs_build_node_manager(sbi);
> > if (err) {
> > - f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)",
> > - err);
> > + f2fs_err(sbi, "Failed to initialize F2FS node manager (%d)", err);
> > goto free_nm;
> > }