Commit 4279f3f9 authored by Gao Xiang's avatar Gao Xiang Committed by Greg Kroah-Hartman
Browse files

staging: erofs: turn cache strategies into mount options



Kill all kconfig cache strategies and turn them into mount options
"cache_strategy={disable|readahead|readaround}".

As the first step, cached pages can still be usable after cache
is disabled by remounting, and these pages will be fallen out
over time, which can be refined in the later version if some
requirement is needed. Update related document as well.

Suggested-by: default avatarTheodore Ts'o <tytso@mit.edu>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarGao Xiang <gaoxiang25@huawei.com>
Link: https://lore.kernel.org/r/20190731155752.210602-20-gaoxiang25@huawei.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent eace994a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -65,6 +65,16 @@ fault_injection=%d Enable fault injection in all supported types with
                       by default if CONFIG_EROFS_FS_XATTR is selected.
(no)acl                Setup POSIX Access Control List. Note: acl is enabled
                       by default if CONFIG_EROFS_FS_POSIX_ACL is selected.
cache_strategy=%s      Select a strategy for cached decompression from now on:
                         disabled: In-place I/O decompression only;
                        readahead: Cache the last incomplete compressed physical
                                   cluster for further reading. It still does
                                   in-place I/O decompression for the rest
                                   compressed physical clusters;
                       readaround: Cache the both ends of incomplete compressed
                                   physical clusters for further reading.
                                   It still does in-place I/O decompression
                                   for the rest compressed physical clusters.

Module parameters
=================
+0 −38
Original line number Diff line number Diff line
@@ -94,41 +94,3 @@ config EROFS_FS_CLUSTER_PAGE_LIMIT
	  than 2. Otherwise, the image cannot be mounted
	  correctly on this kernel.
choice
	prompt "EROFS VLE Data Decompression mode"
	depends on EROFS_FS_ZIP
	default EROFS_FS_ZIP_CACHE_BIPOLAR
	help
	  EROFS supports three options for VLE decompression.
	  "In-place Decompression Only" consumes the minimum memory
	  with lowest random read.

	  "Bipolar Cached Decompression" consumes the maximum memory
	  with highest random read.

	  If unsure, select "Bipolar Cached Decompression"

config EROFS_FS_ZIP_NO_CACHE
	bool "In-place Decompression Only"
	help
	  Read compressed data into page cache and do in-place
	  decompression directly.

config EROFS_FS_ZIP_CACHE_UNIPOLAR
	bool "Unipolar Cached Decompression"
	help
	  For each request, it caches the last compressed page
	  for further reading.
	  It still decompresses in place for the rest compressed pages.

config EROFS_FS_ZIP_CACHE_BIPOLAR
	bool "Bipolar Cached Decompression"
	help
	  For each request, it caches the both end compressed pages
	  for further reading.
	  It still decompresses in place for the rest compressed pages.

	  Recommended for performance priority.

endchoice
+10 −15
Original line number Diff line number Diff line
@@ -51,18 +51,6 @@ struct erofs_fault_info {
};
#endif	/* CONFIG_EROFS_FAULT_INJECTION */

#ifdef CONFIG_EROFS_FS_ZIP_CACHE_BIPOLAR
#define EROFS_FS_ZIP_CACHE_LVL	(2)
#elif defined(EROFS_FS_ZIP_CACHE_UNIPOLAR)
#define EROFS_FS_ZIP_CACHE_LVL	(1)
#else
#define EROFS_FS_ZIP_CACHE_LVL	(0)
#endif

#if (!defined(EROFS_FS_HAS_MANAGED_CACHE) && (EROFS_FS_ZIP_CACHE_LVL > 0))
#define EROFS_FS_HAS_MANAGED_CACHE
#endif

/* EROFS_SUPER_MAGIC_V1 to represent the whole file system */
#define EROFS_SUPER_MAGIC   EROFS_SUPER_MAGIC_V1

@@ -85,10 +73,11 @@ struct erofs_sb_info {

	unsigned int shrinker_run_no;

#ifdef EROFS_FS_HAS_MANAGED_CACHE
	struct inode *managed_cache;
#endif
	/* current strategy of how to use managed cache */
	unsigned char cache_strategy;

	/* pseudo inode to manage cached pages */
	struct inode *managed_cache;
#endif	/* CONFIG_EROFS_FS_ZIP */
	u32 blocks;
	u32 meta_blkaddr;
@@ -174,6 +163,12 @@ static inline void *erofs_kmalloc(struct erofs_sb_info *sbi,
#define test_opt(sbi, option)	((sbi)->mount_opt & EROFS_MOUNT_##option)

#ifdef CONFIG_EROFS_FS_ZIP
enum {
	EROFS_ZIP_CACHE_DISABLED,
	EROFS_ZIP_CACHE_READAHEAD,
	EROFS_ZIP_CACHE_READAROUND
};

#define EROFS_LOCKED_MAGIC     (INT_MIN | 0xE0F510CCL)

/* basic unit of the workstation of a super_block */
+57 −7
Original line number Diff line number Diff line
@@ -197,17 +197,50 @@ static unsigned int erofs_get_fault_rate(struct erofs_sb_info *sbi)
}
#endif

#ifdef CONFIG_EROFS_FS_ZIP
static int erofs_build_cache_strategy(struct erofs_sb_info *sbi,
				      substring_t *args)
{
	const char *cs = match_strdup(args);
	int err = 0;

	if (!cs) {
		errln("Not enough memory to store cache strategy");
		return -ENOMEM;
	}

	if (!strcmp(cs, "disabled")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_DISABLED;
	} else if (!strcmp(cs, "readahead")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_READAHEAD;
	} else if (!strcmp(cs, "readaround")) {
		sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
	} else {
		errln("Unrecognized cache strategy \"%s\"", cs);
		err = -EINVAL;
	}
	kfree(cs);
	return err;
}
#else
static int erofs_build_cache_strategy(struct erofs_sb_info *sbi,
				      substring_t *args)
{
	infoln("EROFS compression is disabled, so cache strategy is ignored");
	return 0;
}
#endif

/* set up default EROFS parameters */
static void default_options(struct erofs_sb_info *sbi)
{
	/* set up some FS parameters */
#ifdef CONFIG_EROFS_FS_ZIP
	sbi->cache_strategy = EROFS_ZIP_CACHE_READAROUND;
	sbi->max_sync_decompress_pages = 3;
#endif

#ifdef CONFIG_EROFS_FS_XATTR
	set_opt(sbi, XATTR_USER);
#endif

#ifdef CONFIG_EROFS_FS_POSIX_ACL
	set_opt(sbi, POSIX_ACL);
#endif
@@ -219,6 +252,7 @@ enum {
	Opt_acl,
	Opt_noacl,
	Opt_fault_injection,
	Opt_cache_strategy,
	Opt_err
};

@@ -228,6 +262,7 @@ static match_table_t erofs_tokens = {
	{Opt_acl, "acl"},
	{Opt_noacl, "noacl"},
	{Opt_fault_injection, "fault_injection=%u"},
	{Opt_cache_strategy, "cache_strategy=%s"},
	{Opt_err, NULL}
};

@@ -285,7 +320,11 @@ static int parse_options(struct super_block *sb, char *options)
			if (err)
				return err;
			break;

		case Opt_cache_strategy:
			err = erofs_build_cache_strategy(EROFS_SB(sb), args);
			if (err)
				return err;
			break;
		default:
			errln("Unrecognized mount option \"%s\" "
					"or missing value", p);
@@ -295,8 +334,7 @@ static int parse_options(struct super_block *sb, char *options)
	return 0;
}

#ifdef EROFS_FS_HAS_MANAGED_CACHE

#ifdef CONFIG_EROFS_FS_ZIP
static const struct address_space_operations managed_cache_aops;

static int managed_cache_releasepage(struct page *page, gfp_t gfp_mask)
@@ -469,7 +507,7 @@ static void erofs_put_super(struct super_block *sb)
	DBG_BUGON(!sbi);

	erofs_shrinker_unregister(sb);
#ifdef EROFS_FS_HAS_MANAGED_CACHE
#ifdef CONFIG_EROFS_FS_ZIP
	iput(sbi->managed_cache);
	sbi->managed_cache = NULL;
#endif
@@ -570,6 +608,18 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
	if (test_opt(sbi, FAULT_INJECTION))
		seq_printf(seq, ",fault_injection=%u",
			   erofs_get_fault_rate(sbi));
#ifdef CONFIG_EROFS_FS_ZIP
	if (sbi->cache_strategy == EROFS_ZIP_CACHE_DISABLED) {
		seq_puts(seq, ",cache_strategy=disabled");
	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAHEAD) {
		seq_puts(seq, ",cache_strategy=readahead");
	} else if (sbi->cache_strategy == EROFS_ZIP_CACHE_READAROUND) {
		seq_puts(seq, ",cache_strategy=readaround");
	} else {
		seq_puts(seq, ",cache_strategy=(unknown)");
		DBG_BUGON(1);
	}
#endif
	return 0;
}

+0 −26
Original line number Diff line number Diff line
@@ -145,8 +145,6 @@ int erofs_workgroup_put(struct erofs_workgroup *grp)
	return count;
}

#ifdef EROFS_FS_HAS_MANAGED_CACHE
/* for cache-managed case, customized reclaim paths exist */
static void erofs_workgroup_unfreeze_final(struct erofs_workgroup *grp)
{
	erofs_workgroup_unfreeze(grp, 0);
@@ -192,30 +190,6 @@ static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
	return true;
}

#else
/* for nocache case, no customized reclaim path at all */
static bool erofs_try_to_release_workgroup(struct erofs_sb_info *sbi,
					   struct erofs_workgroup *grp,
					   bool cleanup)
{
	int cnt = atomic_read(&grp->refcount);

	DBG_BUGON(cnt <= 0);
	DBG_BUGON(cleanup && cnt != 1);

	if (cnt > 1)
		return false;

	DBG_BUGON(xa_untag_pointer(radix_tree_delete(&sbi->workstn_tree,
						     grp->index)) != grp);

	/* (rarely) could be grabbed again when freeing */
	erofs_workgroup_put(grp);
	return true;
}

#endif

static unsigned long erofs_shrink_workstation(struct erofs_sb_info *sbi,
					      unsigned long nr_shrink,
					      bool cleanup)
Loading