summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2016-06-13 09:47:48 -0700
committerJaegeuk Kim <jaegeuk@kernel.org>2016-07-06 10:44:07 -0700
commit52763a4b7a2112743745c5bbfe43fe6f54d4b39a (patch)
tree42b1ca3efc444ed16b29796fd13d7054737ab20c
parent67c3758d2267de589ee9a8856fe637cce85993d9 (diff)
f2fs: detect host-managed SMR by feature flag
If mkfs.f2fs gives a feature flag for host-managed SMR, we can set mode=lfs by default. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c3
-rw-r--r--fs/f2fs/f2fs.h21
-rw-r--r--fs/f2fs/segment.c3
-rw-r--r--fs/f2fs/super.c16
4 files changed, 35 insertions, 8 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 607ef4397330..08325280d03c 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -102,7 +102,8 @@ static inline void __submit_bio(struct f2fs_sb_info *sbi, int rw,
{
if (!is_read_io(rw)) {
atomic_inc(&sbi->nr_wb_bios);
- if (current->plug && (type == DATA || type == NODE))
+ if (f2fs_sb_mounted_hmsmr(sbi->sb) &&
+ current->plug && (type == DATA || type == NODE))
blk_finish_plug(current->plug);
}
submit_bio(rw, bio);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index bbcd4688f97b..b3aeb58a6285 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -133,6 +133,7 @@ struct f2fs_mount_info {
};
#define F2FS_FEATURE_ENCRYPT 0x0001
+#define F2FS_FEATURE_HMSMR 0x0002
#define F2FS_HAS_FEATURE(sb, mask) \
((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -2334,6 +2335,26 @@ static inline int f2fs_sb_has_crypto(struct super_block *sb)
return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_ENCRYPT);
}
+static inline int f2fs_sb_mounted_hmsmr(struct super_block *sb)
+{
+ return F2FS_HAS_FEATURE(sb, F2FS_FEATURE_HMSMR);
+}
+
+static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
+{
+ clear_opt(sbi, ADAPTIVE);
+ clear_opt(sbi, LFS);
+
+ switch (mt) {
+ case F2FS_MOUNT_ADAPTIVE:
+ set_opt(sbi, ADAPTIVE);
+ break;
+ case F2FS_MOUNT_LFS:
+ set_opt(sbi, LFS);
+ break;
+ }
+}
+
static inline bool f2fs_may_encrypt(struct inode *inode)
{
#ifdef CONFIG_F2FS_FS_ENCRYPTION
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 4792f94089f7..782975e791f1 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2402,7 +2402,8 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
sm_info->ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
sm_info->rec_prefree_segments = sm_info->main_segments *
DEF_RECLAIM_PREFREE_SEGMENTS / 100;
- sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
+ if (!test_opt(sbi, LFS))
+ sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 41347c0829cd..8c698e183d2b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -515,12 +515,10 @@ static int parse_options(struct super_block *sb, char *options)
return -ENOMEM;
if (strlen(name) == 8 &&
!strncmp(name, "adaptive", 8)) {
- set_opt(sbi, ADAPTIVE);
- clear_opt(sbi, LFS);
+ set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);
} else if (strlen(name) == 3 &&
!strncmp(name, "lfs", 3)) {
- clear_opt(sbi, ADAPTIVE);
- set_opt(sbi, LFS);
+ set_opt_mode(sbi, F2FS_MOUNT_LFS);
} else {
kfree(name);
return -EINVAL;
@@ -966,7 +964,12 @@ static void default_options(struct f2fs_sb_info *sbi)
set_opt(sbi, EXTENT_CACHE);
sbi->sb->s_flags |= MS_LAZYTIME;
set_opt(sbi, FLUSH_MERGE);
- set_opt(sbi, ADAPTIVE);
+ if (f2fs_sb_mounted_hmsmr(sbi->sb)) {
+ set_opt_mode(sbi, F2FS_MOUNT_LFS);
+ set_opt(sbi, DISCARD);
+ } else {
+ set_opt_mode(sbi, F2FS_MOUNT_ADAPTIVE);
+ }
#ifdef CONFIG_F2FS_FS_XATTR
set_opt(sbi, XATTR_USER);
@@ -1615,6 +1618,8 @@ try_onemore:
goto free_sbi;
sb->s_fs_info = sbi;
+ sbi->raw_super = raw_super;
+
default_options(sbi);
/* parse mount options */
options = kstrdup((const char *)data, GFP_KERNEL);
@@ -1644,7 +1649,6 @@ try_onemore:
memcpy(sb->s_uuid, raw_super->uuid, sizeof(raw_super->uuid));
/* init f2fs-specific super block info */
- sbi->raw_super = raw_super;
sbi->valid_super_block = valid_super_block;
mutex_init(&sbi->gc_mutex);
mutex_init(&sbi->cp_mutex);