linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luis Chamberlain <mcgrof@kernel.org>
To: hughd@google.com, akpm@linux-foundation.org, willy@infradead.org,
	brauner@kernel.org, djwong@kernel.org
Cc: p.raghav@samsung.com, da.gomez@samsung.com,
	a.manzanares@samsung.com, dave@stgolabs.net,
	yosryahmed@google.com, keescook@chromium.org, hare@suse.de,
	kbusch@kernel.org, mcgrof@kernel.org, patches@lists.linux.dev,
	linux-block@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [RFC 8/8] shmem: add support to customize block size on multiple PAGE_SIZE
Date: Fri, 21 Apr 2023 14:44:00 -0700	[thread overview]
Message-ID: <20230421214400.2836131-9-mcgrof@kernel.org> (raw)
In-Reply-To: <20230421214400.2836131-1-mcgrof@kernel.org>

This allows tmpfs mounts to use a custom block size. We only allow
block sizes greater than PAGE_SIZE, and these must also be a multiple
of the PAGE_SIZE too.

Only simple tests have been run so far:

time for i in $(seq 1 1000000); do echo $i >> /root/ordered.txt; done

real    0m21.392s
user    0m8.077s
sys     0m13.098s

du -h /root/ordered.txt
6.6M    /root/ordered.txt

sha1sum /root/ordered.txt
2dcc06b7ca3b7dd8b5626af83c1be3cb08ddc76c  /root/ordered.txt

stat /root/ordered.txt
  File: /root/ordered.txt
  Size: 6888896         Blocks: 13456      IO Block: 4096   regular file
Device: 254,1   Inode: 655717      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-04-21 19:34:20.709869093 +0000
Modify: 2023-04-21 19:34:43.833900042 +0000
Change: 2023-04-21 19:34:43.833900042 +0000
 Birth: 2023-04-21 19:34:20.709869093 +0000

8 KiB block size:

sha1sum /root/ordered.txt
mount -t tmpfs            -o size=10M,bsize=$((4096*2)) -o noswap tmpfs /data-tmpfs/
cp /root/ordered.txt
sha1sum /data-tmpfs/ordered.txt
stat /data-tmpfs/ordered.txt
2dcc06b7ca3b7dd8b5626af83c1be3cb08ddc76c  /root/ordered.txt
2dcc06b7ca3b7dd8b5626af83c1be3cb08ddc76c  /data-tmpfs/ordered.txt
  File: /data-tmpfs/ordered.txt
  Size: 6888896         Blocks: 13456      IO Block: 8192   regular file
Device: 0,42    Inode: 2           Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-04-21 19:31:16.078390405 +0000
Modify: 2023-04-21 19:31:16.070391363 +0000
Change: 2023-04-21 19:31:16.070391363 +0000
 Birth: 2023-04-21 19:31:16.034395676 +0000

64 KiB block size:

sha1sum /root/ordered.txt
mount -t tmpfs            -o size=10M,bsize=$((4096*16)) -o noswap tmpfs /data-tmpfs/
cp /root/ordered.txt /data-tmpfs/; sha1sum /data-tmpfs/ordered.txt
stat /data-tmpfs/ordered.txt
2dcc06b7ca3b7dd8b5626af83c1be3cb08ddc76c  /root/ordered.txt
2dcc06b7ca3b7dd8b5626af83c1be3cb08ddc76c  /data-tmpfs/ordered.txt
  File: /data-tmpfs/ordered.txt
  Size: 6888896         Blocks: 13568      IO Block: 65536  regular file
Device: 0,42    Inode: 2           Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2023-04-21 19:32:14.669796970 +0000
Modify: 2023-04-21 19:32:14.661796959 +0000
Change: 2023-04-21 19:32:14.661796959 +0000
 Birth: 2023-04-21 19:32:14.649796944 +0000

Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
---
 mm/shmem.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 5 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index 740b4448f936..64108c28eebd 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -118,11 +118,13 @@ struct shmem_options {
 	int huge;
 	int seen;
 	bool noswap;
+	u64 blocksize;
 #define SHMEM_SEEN_BLOCKS 1
 #define SHMEM_SEEN_INODES 2
 #define SHMEM_SEEN_HUGE 4
 #define SHMEM_SEEN_INUMS 8
 #define SHMEM_SEEN_NOSWAP 16
+#define SHMEM_SEEN_BLOCKSIZE 32
 };
 
 static u64 shmem_default_bsize(void)
@@ -3779,6 +3781,7 @@ enum shmem_param {
 	Opt_inode32,
 	Opt_inode64,
 	Opt_noswap,
+	Opt_bsize,
 };
 
 static const struct constant_table shmem_param_enums_huge[] = {
@@ -3801,6 +3804,7 @@ const struct fs_parameter_spec shmem_fs_parameters[] = {
 	fsparam_flag  ("inode32",	Opt_inode32),
 	fsparam_flag  ("inode64",	Opt_inode64),
 	fsparam_flag  ("noswap",	Opt_noswap),
+	fsparam_u32   ("bsize",		Opt_bsize),
 	{}
 };
 
@@ -3827,7 +3831,14 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
 		}
 		if (*rest)
 			goto bad_value;
-		ctx->blocks = DIV_ROUND_UP(size, shmem_default_bsize());
+		if (!(ctx->seen & SHMEM_SEEN_BLOCKSIZE) ||
+		    ctx->blocksize == shmem_default_bsize())
+			ctx->blocks = DIV_ROUND_UP(size, shmem_default_bsize());
+		else {
+			if (size < ctx->blocksize || size % ctx->blocksize != 0)
+				goto bad_value;
+			ctx->blocks = DIV_ROUND_UP(size, ctx->blocksize);
+		}
 		ctx->seen |= SHMEM_SEEN_BLOCKS;
 		break;
 	case Opt_nr_blocks:
@@ -3892,6 +3903,23 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
 		ctx->noswap = true;
 		ctx->seen |= SHMEM_SEEN_NOSWAP;
 		break;
+	case Opt_bsize:
+		ctx->blocksize = result.uint_32;
+		ctx->seen |= SHMEM_SEEN_BLOCKSIZE;
+		/* Must be >= PAGE_SIZE */
+		if (ctx->blocksize < PAGE_SIZE)
+			goto bad_value;
+		/*
+		 * We cap this to allow a block to be at least allowed to
+		 * be allocated using the buddy allocator. That's MAX_ORDER
+		 * pages. So 4 MiB on x86_64.
+		 */
+		if (ctx->blocksize > (1 << (MAX_ORDER + PAGE_SHIFT)))
+			goto bad_value;
+		/* The blocksize must be a multiple of the page size so must be aligned */
+		if (!PAGE_ALIGNED(ctx->blocksize))
+			goto bad_value;
+		break;
 	}
 	return 0;
 
@@ -3963,6 +3991,12 @@ static int shmem_reconfigure(struct fs_context *fc)
 	raw_spin_lock(&sbinfo->stat_lock);
 	inodes = sbinfo->max_inodes - sbinfo->free_inodes;
 
+	if (ctx->seen & SHMEM_SEEN_BLOCKSIZE) {
+		if (ctx->blocksize != shmem_sb_blocksize(sbinfo)) {
+			err = "Cannot modify block size on remount";
+			goto out;
+		}
+	}
 	if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
 		if (!sbinfo->max_blocks) {
 			err = "Cannot retroactively limit size";
@@ -4078,6 +4112,8 @@ static int shmem_show_options(struct seq_file *seq, struct dentry *root)
 	shmem_show_mpol(seq, sbinfo->mpol);
 	if (sbinfo->noswap)
 		seq_printf(seq, ",noswap");
+	if (shmem_sb_blocksize(sbinfo) != shmem_default_bsize())
+		seq_printf(seq, ",bsize=%llu", shmem_sb_blocksize(sbinfo));
 	return 0;
 }
 
@@ -4115,10 +4151,12 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
 	 * but the internal instance is left unlimited.
 	 */
 	if (!(sb->s_flags & SB_KERNMOUNT)) {
+		if (!(ctx->seen & SHMEM_SEEN_BLOCKSIZE))
+			ctx->blocksize = shmem_default_bsize();
 		if (!(ctx->seen & SHMEM_SEEN_BLOCKS))
-			ctx->blocks = shmem_default_max_blocks(shmem_default_bsize());
+			ctx->blocks = shmem_default_max_blocks(ctx->blocksize);
 		if (!(ctx->seen & SHMEM_SEEN_INODES))
-			ctx->inodes = shmem_default_max_inodes(shmem_default_bsize());
+			ctx->inodes = shmem_default_max_inodes(ctx->blocksize);
 		if (!(ctx->seen & SHMEM_SEEN_INUMS))
 			ctx->full_inums = IS_ENABLED(CONFIG_TMPFS_INODE64);
 		sbinfo->noswap = ctx->noswap;
@@ -4127,7 +4165,7 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
 	}
 	sb->s_export_op = &shmem_export_ops;
 	sb->s_flags |= SB_NOSEC | SB_I_VERSION;
-	sbinfo->blocksize = shmem_default_bsize();
+	sbinfo->blocksize = ctx->blocksize;
 #else
 	sb->s_flags |= SB_NOUSER;
 #endif
@@ -4155,7 +4193,6 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_blocksize = shmem_sb_blocksize(sbinfo);
 	sb->s_blocksize_bits = __ffs(sb->s_blocksize);
-	WARN_ON_ONCE(sb->s_blocksize_bits != PAGE_SHIFT);
 	sb->s_magic = TMPFS_MAGIC;
 	sb->s_op = &shmem_ops;
 	sb->s_time_gran = 1;
-- 
2.39.2


  parent reply	other threads:[~2023-04-21 21:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-21 21:43 [RFC 0/8] shmem: add support for blocksize > PAGE_SIZE Luis Chamberlain
2023-04-21 21:43 ` [RFC 1/8] shmem: replace BLOCKS_PER_PAGE with PAGE_SECTORS Luis Chamberlain
2023-04-21 21:43 ` [RFC 2/8] shmem: convert to use folio_test_hwpoison() Luis Chamberlain
2023-04-21 22:42   ` Matthew Wilcox
2023-04-22  3:05     ` Luis Chamberlain
2023-04-24 21:17       ` Yang Shi
2023-04-24 21:36         ` Matthew Wilcox
2023-04-24 23:05           ` Yang Shi
     [not found]     ` <CGME20230425110913eucas1p22cf9d4c7401881999adb12134b985273@eucas1p2.samsung.com>
2023-04-25 11:00       ` Pankaj Raghav
2023-04-25 22:47         ` Luis Chamberlain
2023-04-26  7:43           ` Luis Chamberlain
2023-04-21 21:43 ` [RFC 3/8] shmem: account for high order folios Luis Chamberlain
2023-04-21 22:46   ` Matthew Wilcox
2023-04-21 21:43 ` [RFC 4/8] shmem: add helpers to get block size Luis Chamberlain
2023-04-21 22:49   ` Matthew Wilcox
2023-04-21 21:43 ` [RFC 5/8] shmem: account for larger blocks sizes for shmem_default_max_blocks() Luis Chamberlain
2023-04-21 21:43 ` [RFC 6/8] shmem: consider block size in shmem_default_max_inodes() Luis Chamberlain
2023-04-21 21:43 ` [RFC 7/8] shmem: add high order page support Luis Chamberlain
2023-04-21 21:44 ` Luis Chamberlain [this message]
2023-04-22  5:10   ` [RFC 8/8] shmem: add support to customize block size on multiple PAGE_SIZE Jane Chu

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=20230421214400.2836131-9-mcgrof@kernel.org \
    --to=mcgrof@kernel.org \
    --cc=a.manzanares@samsung.com \
    --cc=akpm@linux-foundation.org \
    --cc=brauner@kernel.org \
    --cc=da.gomez@samsung.com \
    --cc=dave@stgolabs.net \
    --cc=djwong@kernel.org \
    --cc=hare@suse.de \
    --cc=hughd@google.com \
    --cc=kbusch@kernel.org \
    --cc=keescook@chromium.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=p.raghav@samsung.com \
    --cc=patches@lists.linux.dev \
    --cc=willy@infradead.org \
    --cc=yosryahmed@google.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).