All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gao Xiang <hsiangkao@linux.alibaba.com>
To: Hongbo Li <lihongbo22@huawei.com>,
	chao@kernel.org, brauner@kernel.org, djwong@kernel.org,
	amir73il@gmail.com, joannelkoong@gmail.com
Cc: linux-fsdevel@vger.kernel.org, linux-erofs@lists.ozlabs.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v9 07/10] erofs: introduce the page cache share feature
Date: Mon, 22 Dec 2025 16:59:52 +0800	[thread overview]
Message-ID: <37fafc56-af2f-4a73-a5b7-2041049b8c71@linux.alibaba.com> (raw)
In-Reply-To: <20251117132537.227116-8-lihongbo22@huawei.com>

Hi Hongbo,

On 2025/11/17 21:25, Hongbo Li wrote:
> From: Hongzhen Luo <hongzhen@linux.alibaba.com>
> 
> Currently, reading files with different paths (or names) but the same
> content will consume multiple copies of the page cache, even if the
> content of these page caches is the same. For example, reading
> identical files (e.g., *.so files) from two different minor versions of
> container images will cost multiple copies of the same page cache,
> since different containers have different mount points. Therefore,
> sharing the page cache for files with the same content can save memory.
> 
> This introduces the page cache share feature in erofs. It allocate a
> deduplicated inode and use its page cache as shared. Reads for files
> with identical content will ultimately be routed to the page cache of
> the deduplicated inode. In this way, a single page cache satisfies
> multiple read requests for different files with the same contents.
> 
> Signed-off-by: Hongzhen Luo <hongzhen@linux.alibaba.com>
> Signed-off-by: Hongbo Li <lihongbo22@huawei.com>
> ---
>   fs/erofs/Makefile   |   1 +
>   fs/erofs/internal.h |  29 ++++++
>   fs/erofs/ishare.c   | 241 ++++++++++++++++++++++++++++++++++++++++++++
>   fs/erofs/super.c    |  31 +++++-
>   4 files changed, 300 insertions(+), 2 deletions(-)
>   create mode 100644 fs/erofs/ishare.c
> 
> diff --git a/fs/erofs/Makefile b/fs/erofs/Makefile
> index 549abc424763..a80e1762b607 100644
> --- a/fs/erofs/Makefile
> +++ b/fs/erofs/Makefile
> @@ -10,3 +10,4 @@ erofs-$(CONFIG_EROFS_FS_ZIP_ZSTD) += decompressor_zstd.o
>   erofs-$(CONFIG_EROFS_FS_ZIP_ACCEL) += decompressor_crypto.o
>   erofs-$(CONFIG_EROFS_FS_BACKED_BY_FILE) += fileio.o
>   erofs-$(CONFIG_EROFS_FS_ONDEMAND) += fscache.o
> +erofs-$(CONFIG_EROFS_FS_PAGE_CACHE_SHARE) += ishare.o
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 3033252211ba..93ad34f2b488 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -304,6 +304,22 @@ struct erofs_inode {
>   		};
>   #endif	/* CONFIG_EROFS_FS_ZIP */
>   	};
> +#ifdef CONFIG_EROFS_FS_PAGE_CACHE_SHARE
> +	union {
> +		/* internal dedup inode */
> +		struct {
> +			char *fingerprint;
> +			spinlock_t lock;
> +			/* all backing inodes */
> +			struct list_head backing_head;
> +		};
> +
> +		struct {
> +			struct inode *ishare;
> +			struct list_head backing_link;
> +		};
> +	};
> +#endif
>   	/* the corresponding vfs inode */
>   	struct inode vfs_inode;
>   };
> @@ -410,6 +426,7 @@ extern const struct inode_operations erofs_dir_iops;
>   
>   extern const struct file_operations erofs_file_fops;
>   extern const struct file_operations erofs_dir_fops;
> +extern const struct file_operations erofs_ishare_fops;
>   
>   extern const struct iomap_ops z_erofs_iomap_report_ops;
>   
> @@ -541,6 +558,18 @@ static inline struct bio *erofs_fscache_bio_alloc(struct erofs_map_dev *mdev) {
>   static inline void erofs_fscache_submit_bio(struct bio *bio) {}
>   #endif
>   
> +#ifdef CONFIG_EROFS_FS_PAGE_CACHE_SHARE
> +int erofs_ishare_init(struct super_block *sb);
> +void erofs_ishare_exit(struct super_block *sb);
> +bool erofs_ishare_fill_inode(struct inode *inode);
> +void erofs_ishare_free_inode(struct inode *inode);
> +#else
> +static inline int erofs_ishare_init(struct super_block *sb) { return 0; }
> +static inline void erofs_ishare_exit(struct super_block *sb) {}
> +static inline bool erofs_ishare_fill_inode(struct inode *inode) { return false; }
> +static inline void erofs_ishare_free_inode(struct inode *inode) {}
> +#endif // CONFIG_EROFS_FS_PAGE_CACHE_SHARE
> +
>   long erofs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
>   long erofs_compat_ioctl(struct file *filp, unsigned int cmd,
>   			unsigned long arg);
> diff --git a/fs/erofs/ishare.c b/fs/erofs/ishare.c
> new file mode 100644
> index 000000000000..f386efb260da
> --- /dev/null
> +++ b/fs/erofs/ishare.c
> @@ -0,0 +1,241 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2024, Alibaba Cloud
> + */
> +#include <linux/xxhash.h>
> +#include <linux/refcount.h>
> +#include <linux/mount.h>
> +#include <linux/mutex.h>
> +#include <linux/ramfs.h>
> +#include "internal.h"
> +#include "xattr.h"
> +
> +#include "../internal.h"
> +
> +static DEFINE_MUTEX(erofs_ishare_lock);
> +static struct vfsmount *erofs_ishare_mnt;
> +static refcount_t erofs_ishare_supers;
> +
> +int erofs_ishare_init(struct super_block *sb)
> +{
> +	struct vfsmount *mnt = NULL;
> +	struct erofs_sb_info *sbi = EROFS_SB(sb);
> +
> +	if (!erofs_sb_has_ishare_key(sbi))
> +		return 0;
> +
> +	mutex_lock(&erofs_ishare_lock);
> +	if (erofs_ishare_mnt) {
> +		refcount_inc(&erofs_ishare_supers);
> +	} else {
> +		mnt = kern_mount(&erofs_anon_fs_type);
> +		if (!IS_ERR(mnt)) {
> +			erofs_ishare_mnt = mnt;
> +			refcount_set(&erofs_ishare_supers, 1);
> +		}
> +	}
> +	mutex_unlock(&erofs_ishare_lock);

It seems this part is too complex, we could just
kern_mount() once.

and kern_unmount() before unregistering the module.

And since `erofs_anon_fs_type` is an internal fstype, we
could drop ".owner" field to avoid it from unloading the fs
module I think.

> +	return IS_ERR(mnt) ? PTR_ERR(mnt) : 0;
> +}
> +
> +void erofs_ishare_exit(struct super_block *sb)
> +{
> +	struct erofs_sb_info *sbi = EROFS_SB(sb);
> +	struct vfsmount *tmp;
> +
> +	if (!erofs_sb_has_ishare_key(sbi) || !erofs_ishare_mnt)
> +		return;
> +
> +	mutex_lock(&erofs_ishare_lock);
> +	if (refcount_dec_and_test(&erofs_ishare_supers)) {
> +		tmp = erofs_ishare_mnt;
> +		erofs_ishare_mnt = NULL;
> +		mutex_unlock(&erofs_ishare_lock);
> +		kern_unmount(tmp);
> +		mutex_lock(&erofs_ishare_lock);
> +	}
> +	mutex_unlock(&erofs_ishare_lock);

Same here.

Thanks,
Gao Xiang


  reply	other threads:[~2025-12-22  9:00 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-11-17 13:25 [PATCH v9 00/10] erofs: inode page cache share feature Hongbo Li
2025-11-17 13:25 ` [PATCH v9 01/10] iomap: stash iomap read ctx in the private field of iomap_iter Hongbo Li
2025-11-17 17:08   ` Gao Xiang
2025-11-18  7:35     ` Gao Xiang
2025-11-19  5:49       ` Christoph Hellwig
2025-11-19  6:17         ` Gao Xiang
2025-11-19  9:12           ` Christoph Hellwig
2025-11-19  9:28             ` Gao Xiang
2025-11-17 13:25 ` [PATCH v9 02/10] erofs: hold read context in iomap_iter if needed Hongbo Li
2025-11-17 13:25 ` [PATCH v9 03/10] fs: Export alloc_empty_backing_file Hongbo Li
2025-11-17 13:25 ` [PATCH v9 04/10] erofs: move `struct erofs_anon_fs_type` to super.c Hongbo Li
2025-11-17 13:25 ` [PATCH v9 05/10] erofs: support user-defined fingerprint name Hongbo Li
2025-11-17 17:26   ` Gao Xiang
2025-11-18  2:16     ` Hongbo Li
2025-11-17 13:25 ` [PATCH v9 06/10] erofs: support domain-specific page cache share Hongbo Li
2025-11-17 13:25 ` [PATCH v9 07/10] erofs: introduce the page cache share feature Hongbo Li
2025-12-22  8:59   ` Gao Xiang [this message]
2025-11-17 13:25 ` [PATCH v9 08/10] erofs: support unencoded inodes for page cache share Hongbo Li
2025-11-18  2:13   ` Hongbo Li
2025-11-17 13:25 ` [PATCH v9 09/10] erofs: support compressed " Hongbo Li
2025-11-17 13:25 ` [PATCH v9 10/10] erofs: implement .fadvise " Hongbo Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=37fafc56-af2f-4a73-a5b7-2041049b8c71@linux.alibaba.com \
    --to=hsiangkao@linux.alibaba.com \
    --cc=amir73il@gmail.com \
    --cc=brauner@kernel.org \
    --cc=chao@kernel.org \
    --cc=djwong@kernel.org \
    --cc=joannelkoong@gmail.com \
    --cc=lihongbo22@huawei.com \
    --cc=linux-erofs@lists.ozlabs.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.