Linux-BTRFS Archive on lore.kernel.org
 help / color / Atom feed
From: Naohiro Aota <naohiro.aota@wdc.com>
To: linux-btrfs@vger.kernel.org, David Sterba <dsterba@suse.com>
Cc: Chris Mason <clm@fb.com>, Josef Bacik <josef@toxicpanda.com>,
	Nikolay Borisov <nborisov@suse.com>,
	Damien Le Moal <damien.lemoal@wdc.com>,
	Johannes Thumshirn <Johannes.Thumshirn@wdc.com>,
	Hannes Reinecke <hare@suse.com>,
	Anand Jain <anand.jain@oracle.com>,
	linux-fsdevel@vger.kernel.org,
	Naohiro Aota <naohiro.aota@wdc.com>,
	Johannes Thumshirn <johannes.thumshirn@wdc.com>
Subject: [PATCH v2 08/21] btrfs: factor out decide_stripe_size()
Date: Wed, 12 Feb 2020 16:20:35 +0900
Message-ID: <20200212072048.629856-9-naohiro.aota@wdc.com> (raw)
In-Reply-To: <20200212072048.629856-1-naohiro.aota@wdc.com>

Factor out decide_stripe_size() from __btrfs_alloc_chunk(). This function
calculates the actual stripe size to allocate. decide_stripe_size() handles
the common case to round down the 'ndevs' to 'devs_increment' and check the
upper and lower limitation of 'ndevs'. decide_stripe_size_regular() decides
the size of a stripe and the size of a chunk. The policy is to maximize the
number of stripes.

This commit has no functional changes.

Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/volumes.c | 138 ++++++++++++++++++++++++++-------------------
 1 file changed, 80 insertions(+), 58 deletions(-)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 2bd3ed830a28..00085943e4dd 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4974,6 +4974,84 @@ static int gather_device_info(struct btrfs_fs_devices *fs_devices,
 	return 0;
 }
 
+static int decide_stripe_size_regular(struct alloc_chunk_ctl *ctl,
+				      struct btrfs_device_info *devices_info)
+{
+	int data_stripes;	/* number of stripes that count for
+				   block group size */
+
+	/*
+	 * The primary goal is to maximize the number of stripes, so use as
+	 * many devices as possible, even if the stripes are not maximum sized.
+	 *
+	 * The DUP profile stores more than one stripe per device, the
+	 * max_avail is the total size so we have to adjust.
+	 */
+	ctl->stripe_size = div_u64(devices_info[ctl->ndevs - 1].max_avail,
+				   ctl->dev_stripes);
+	ctl->num_stripes = ctl->ndevs * ctl->dev_stripes;
+
+	/*
+	 * this will have to be fixed for RAID1 and RAID10 over
+	 * more drives
+	 */
+	data_stripes = (ctl->num_stripes - ctl->nparity) / ctl->ncopies;
+
+	/*
+	 * Use the number of data stripes to figure out how big this chunk
+	 * is really going to be in terms of logical address space,
+	 * and compare that answer with the max chunk size. If it's higher,
+	 * we try to reduce stripe_size.
+	 */
+	if (ctl->stripe_size * data_stripes > ctl->max_chunk_size) {
+		/*
+		 * Reduce stripe_size, round it up to a 16MB boundary again and
+		 * then use it, unless it ends up being even bigger than the
+		 * previous value we had already.
+		 */
+		ctl->stripe_size = min(round_up(div_u64(ctl->max_chunk_size,
+							data_stripes), SZ_16M),
+				       ctl->stripe_size);
+	}
+
+	/* align to BTRFS_STRIPE_LEN */
+	ctl->stripe_size = round_down(ctl->stripe_size, BTRFS_STRIPE_LEN);
+	ctl->chunk_size = ctl->stripe_size * data_stripes;
+
+	return 0;
+}
+
+static int decide_stripe_size(struct btrfs_fs_devices *fs_devices,
+			      struct alloc_chunk_ctl *ctl,
+			      struct btrfs_device_info *devices_info)
+{
+	struct btrfs_fs_info *info = fs_devices->fs_info;
+
+	/*
+	 * Round down to number of usable stripes, devs_increment can be any
+	 * number so we can't use round_down()
+	 */
+	ctl->ndevs -= ctl->ndevs % ctl->devs_increment;
+
+	if (ctl->ndevs < ctl->devs_min) {
+		if (btrfs_test_opt(info, ENOSPC_DEBUG)) {
+			btrfs_debug(info,
+	"%s: not enough devices with free space: have=%d minimum required=%d",
+				    __func__, ctl->ndevs, ctl->devs_min);
+		}
+		return -ENOSPC;
+	}
+
+	ctl->ndevs = min(ctl->ndevs, ctl->devs_max);
+
+	switch (fs_devices->chunk_alloc_policy) {
+	case BTRFS_CHUNK_ALLOC_REGULAR:
+		return decide_stripe_size_regular(ctl, devices_info);
+	default:
+		BUG();
+	}
+}
+
 static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 			       u64 start, u64 type)
 {
@@ -4984,8 +5062,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 	struct extent_map *em;
 	struct btrfs_device_info *devices_info = NULL;
 	struct alloc_chunk_ctl ctl;
-	int data_stripes;	/* number of stripes that count for
-				   block group size */
 	int ret;
 	int i;
 	int j;
@@ -5019,61 +5095,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 	if (ret < 0)
 		goto error;
 
-	/*
-	 * Round down to number of usable stripes, devs_increment can be any
-	 * number so we can't use round_down()
-	 */
-	ctl.ndevs -= ctl.ndevs % ctl.devs_increment;
-
-	if (ctl.ndevs < ctl.devs_min) {
-		ret = -ENOSPC;
-		if (btrfs_test_opt(info, ENOSPC_DEBUG)) {
-			btrfs_debug(info,
-	"%s: not enough devices with free space: have=%d minimum required=%d",
-				    __func__, ctl.ndevs, ctl.devs_min);
-		}
+	ret = decide_stripe_size(fs_devices, &ctl, devices_info);
+	if (ret < 0)
 		goto error;
-	}
-
-	ctl.ndevs = min(ctl.ndevs, ctl.devs_max);
-
-	/*
-	 * The primary goal is to maximize the number of stripes, so use as
-	 * many devices as possible, even if the stripes are not maximum sized.
-	 *
-	 * The DUP profile stores more than one stripe per device, the
-	 * max_avail is the total size so we have to adjust.
-	 */
-	ctl.stripe_size = div_u64(devices_info[ctl.ndevs - 1].max_avail,
-				   ctl.dev_stripes);
-	ctl.num_stripes = ctl.ndevs * ctl.dev_stripes;
-
-	/*
-	 * this will have to be fixed for RAID1 and RAID10 over
-	 * more drives
-	 */
-	data_stripes = (ctl.num_stripes - ctl.nparity) / ctl.ncopies;
-
-	/*
-	 * Use the number of data stripes to figure out how big this chunk
-	 * is really going to be in terms of logical address space,
-	 * and compare that answer with the max chunk size. If it's higher,
-	 * we try to reduce stripe_size.
-	 */
-	if (ctl.stripe_size * data_stripes > ctl.max_chunk_size) {
-		/*
-		 * Reduce stripe_size, round it up to a 16MB boundary again and
-		 * then use it, unless it ends up being even bigger than the
-		 * previous value we had already.
-		 */
-		ctl.stripe_size =
-			min(round_up(div_u64(ctl.max_chunk_size, data_stripes),
-				     SZ_16M),
-			    ctl.stripe_size);
-	}
-
-	/* align to BTRFS_STRIPE_LEN */
-	ctl.stripe_size = round_down(ctl.stripe_size, BTRFS_STRIPE_LEN);
 
 	map = kmalloc(map_lookup_size(ctl.num_stripes), GFP_NOFS);
 	if (!map) {
@@ -5097,8 +5121,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 	map->type = type;
 	map->sub_stripes = ctl.sub_stripes;
 
-	ctl.chunk_size = ctl.stripe_size * data_stripes;
-
 	trace_btrfs_chunk_alloc(info, map, start, ctl.chunk_size);
 
 	em = alloc_extent_map();
-- 
2.25.0


  parent reply index

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-12  7:20 [PATCH v2 00/21] btrfs: refactor and generalize chunk/dev_extent/extent allocation Naohiro Aota
2020-02-12  7:20 ` [PATCH v2 01/21] btrfs: change type of full_search to bool Naohiro Aota
2020-02-12  7:20 ` [PATCH v2 02/21] btrfs: do not BUG_ON with invalid profile Naohiro Aota
2020-02-12  7:58   ` Johannes Thumshirn
2020-02-12 14:14   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 03/21] btrfs: introduce chunk allocation policy Naohiro Aota
2020-02-12  7:20 ` [PATCH v2 04/21] btrfs: refactor find_free_dev_extent_start() Naohiro Aota
2020-02-12 14:16   ` Josef Bacik
2020-02-13 11:32   ` Johannes Thumshirn
2020-02-12  7:20 ` [PATCH v2 05/21] btrfs: introduce alloc_chunk_ctl Naohiro Aota
2020-02-12  8:00   ` Johannes Thumshirn
2020-02-13 16:17   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 06/21] btrfs: factor out init_alloc_chunk_ctl Naohiro Aota
2020-02-13 16:20   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 07/21] btrfs: factor out gather_device_info() Naohiro Aota
2020-02-12  8:04   ` Johannes Thumshirn
2020-02-12  7:20 ` Naohiro Aota [this message]
2020-02-12  7:20 ` [PATCH v2 09/21] btrfs: factor out create_chunk() Naohiro Aota
2020-02-12  8:07   ` Johannes Thumshirn
2020-02-13 16:24   ` Josef Bacik
2020-02-20 10:17     ` Naohiro Aota
2020-02-12  7:20 ` [PATCH v2 10/21] btrfs: parameterize dev_extent_min Naohiro Aota
2020-02-13 16:27   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 11/21] btrfs: introduce extent allocation policy Naohiro Aota
2020-02-13 19:55   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 12/21] btrfs: move hint_byte into find_free_extent_ctl Naohiro Aota
2020-02-12 14:11   ` Johannes Thumshirn
2020-02-13 19:56   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 13/21] btrfs: move vairalbes for clustered allocation " Naohiro Aota
2020-02-12 14:14   ` Johannes Thumshirn
2020-02-13 19:57   ` Josef Bacik
2020-02-20 14:27   ` Christoph Hellwig
2020-02-12  7:20 ` [PATCH v2 14/21] btrfs: factor out do_allocation() Naohiro Aota
2020-02-12 14:45   ` Johannes Thumshirn
2020-02-13 19:57   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 15/21] btrfs: drop unnecessary arguments from clustered allocation functions Naohiro Aota
2020-02-12 14:47   ` Johannes Thumshirn
2020-02-13 19:58   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 16/21] btrfs: factor out release_block_group() Naohiro Aota
2020-02-12 14:48   ` Johannes Thumshirn
2020-02-13 19:58   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 17/21] btrfs: factor out found_extent() Naohiro Aota
2020-02-12 14:50   ` Johannes Thumshirn
2020-02-13 19:58   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 18/21] btrfs: drop unnecessary arguments from find_free_extent_update_loop() Naohiro Aota
2020-02-12 14:51   ` Johannes Thumshirn
2020-02-13 19:58   ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 19/21] btrfs: factor out chunk_allocation_failed() Naohiro Aota
2020-02-12 14:56   ` Johannes Thumshirn
2020-02-13 19:52   ` Josef Bacik
2020-02-20  9:57     ` Naohiro Aota
2020-02-12  7:20 ` [PATCH v2 20/21] btrfs: skip LOOP_NO_EMPTY_SIZE if not clustered allocation Naohiro Aota
2020-02-13 19:55   ` Josef Bacik
2020-02-20  9:56     ` Naohiro Aota
2020-02-20 15:40       ` Josef Bacik
2020-02-12  7:20 ` [PATCH v2 21/21] btrfs: factor out prepare_allocation() Naohiro Aota
2020-02-13 19:59   ` Josef Bacik

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=20200212072048.629856-9-naohiro.aota@wdc.com \
    --to=naohiro.aota@wdc.com \
    --cc=Johannes.Thumshirn@wdc.com \
    --cc=anand.jain@oracle.com \
    --cc=clm@fb.com \
    --cc=damien.lemoal@wdc.com \
    --cc=dsterba@suse.com \
    --cc=hare@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=nborisov@suse.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

Linux-BTRFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-btrfs/0 linux-btrfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-btrfs linux-btrfs/ https://lore.kernel.org/linux-btrfs \
		linux-btrfs@vger.kernel.org
	public-inbox-index linux-btrfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-btrfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git