From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 1/3] btrfs: volumes: Refactor device holes gathering into a separate function
Date: Thu, 7 Nov 2019 14:27:08 +0800 [thread overview]
Message-ID: <20191107062710.67964-2-wqu@suse.com> (raw)
In-Reply-To: <20191107062710.67964-1-wqu@suse.com>
In __btrfs_alloc_chunk() we need to iterate through all rw devices and
gather the hole sizes of them.
This function can be refactor into a new function, gather_dev_holes(),
to gather holes info from a list_head.
This provides the basis for later degraded chunk feature.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/volumes.c | 129 ++++++++++++++++++++++++++-------------------
1 file changed, 74 insertions(+), 55 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index cdd7af424033..eee5fc1d11f0 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4898,17 +4898,84 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
btrfs_set_fs_incompat(info, RAID56);
}
+static int gather_dev_holes(struct btrfs_fs_info *info,
+ struct btrfs_device_info *devices_info,
+ int *index, struct list_head *list,
+ int max_nr_devs, u64 stripe_size, int dev_stripes)
+{
+ struct btrfs_device *device;
+ int ret;
+ int ndevs = 0;
+
+ list_for_each_entry(device, list, dev_alloc_list) {
+ u64 max_avail;
+ u64 dev_offset;
+ u64 total_avail;
+
+ if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
+ !test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) {
+ WARN(1, KERN_ERR
+ "BTRFS: read-only device in alloc_list\n");
+ continue;
+ }
+
+ if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
+ &device->dev_state) ||
+ test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
+ continue;
+
+ if (device->total_bytes > device->bytes_used)
+ total_avail = device->total_bytes - device->bytes_used;
+ else
+ total_avail = 0;
+
+ /* If there is no space on this device, skip it. */
+ if (total_avail == 0)
+ continue;
+
+ ret = find_free_dev_extent(device,
+ stripe_size * dev_stripes,
+ &dev_offset, &max_avail);
+ if (ret && ret != -ENOSPC)
+ break;
+
+ if (ret == 0)
+ max_avail = stripe_size * dev_stripes;
+
+ if (max_avail < BTRFS_STRIPE_LEN * dev_stripes) {
+ if (btrfs_test_opt(info, ENOSPC_DEBUG))
+ btrfs_debug(info,
+ "%s: devid %llu has no free space, have=%llu want=%u",
+ __func__, device->devid, max_avail,
+ BTRFS_STRIPE_LEN * dev_stripes);
+ continue;
+ }
+
+ if (ndevs == max_nr_devs) {
+ WARN(1, "%s: found more than %u devices\n", __func__,
+ max_nr_devs);
+ break;
+ }
+ ret = 0;
+ devices_info[ndevs].dev_offset = dev_offset;
+ devices_info[ndevs].max_avail = max_avail;
+ devices_info[ndevs].total_avail = total_avail;
+ devices_info[ndevs].dev = device;
+ ++ndevs;
+ }
+ *index += ndevs;
+ return 0;
+}
+
static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
u64 start, u64 type)
{
struct btrfs_fs_info *info = trans->fs_info;
struct btrfs_fs_devices *fs_devices = info->fs_devices;
- struct btrfs_device *device;
struct map_lookup *map = NULL;
struct extent_map_tree *em_tree;
struct extent_map *em;
struct btrfs_device_info *devices_info = NULL;
- u64 total_avail;
int num_stripes; /* total number of stripes to allocate */
int data_stripes; /* number of stripes that count for
block group size */
@@ -4983,59 +5050,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
* about the available holes on each device.
*/
ndevs = 0;
- list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
- u64 max_avail;
- u64 dev_offset;
-
- if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
- WARN(1, KERN_ERR
- "BTRFS: read-only device in alloc_list\n");
- continue;
- }
-
- if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
- &device->dev_state) ||
- test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
- continue;
-
- if (device->total_bytes > device->bytes_used)
- total_avail = device->total_bytes - device->bytes_used;
- else
- total_avail = 0;
-
- /* If there is no space on this device, skip it. */
- if (total_avail == 0)
- continue;
-
- ret = find_free_dev_extent(device,
- max_stripe_size * dev_stripes,
- &dev_offset, &max_avail);
- if (ret && ret != -ENOSPC)
- goto error;
-
- if (ret == 0)
- max_avail = max_stripe_size * dev_stripes;
-
- if (max_avail < BTRFS_STRIPE_LEN * dev_stripes) {
- if (btrfs_test_opt(info, ENOSPC_DEBUG))
- btrfs_debug(info,
- "%s: devid %llu has no free space, have=%llu want=%u",
- __func__, device->devid, max_avail,
- BTRFS_STRIPE_LEN * dev_stripes);
- continue;
- }
-
- if (ndevs == fs_devices->rw_devices) {
- WARN(1, "%s: found more than %llu devices\n",
- __func__, fs_devices->rw_devices);
- break;
- }
- devices_info[ndevs].dev_offset = dev_offset;
- devices_info[ndevs].max_avail = max_avail;
- devices_info[ndevs].total_avail = total_avail;
- devices_info[ndevs].dev = device;
- ++ndevs;
- }
+ ret = gather_dev_holes(info, devices_info, &ndevs,
+ &fs_devices->alloc_list, fs_devices->rw_devices,
+ max_stripe_size, dev_stripes);
+ if (ret < 0)
+ goto error;
/*
* now sort the devices by hole size / available space
--
2.24.0
next prev parent reply other threads:[~2019-11-07 6:27 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-07 6:27 [PATCH 0/3] btrfs: More intelligent degraded chunk allocator Qu Wenruo
2019-11-07 6:27 ` Qu Wenruo [this message]
2019-11-07 9:20 ` [PATCH 1/3] btrfs: volumes: Refactor device holes gathering into a separate function Johannes Thumshirn
2019-11-07 9:33 ` Qu Wenruo
2019-11-07 9:45 ` Johannes Thumshirn
2019-11-07 6:27 ` [PATCH 2/3] btrfs: volumes: Add btrfs_fs_devices::missing_list to collect missing devices Qu Wenruo
2019-11-07 9:31 ` Johannes Thumshirn
2019-11-19 10:03 ` Anand Jain
2019-11-19 10:29 ` Qu Wenruo
2019-11-27 19:36 ` David Sterba
2019-11-07 6:27 ` [PATCH 3/3] btrfs: volumes: Allocate degraded chunks if rw devices can't fullfil a chunk Qu Wenruo
2019-11-19 10:05 ` Anand Jain
2019-11-19 10:41 ` Qu Wenruo
2019-11-27 19:23 ` David Sterba
2019-11-27 23:36 ` Qu Wenruo
2019-11-28 11:24 ` David Sterba
2019-11-28 12:29 ` Qu Wenruo
2019-11-28 12:30 ` Qu WenRuo
2019-11-28 12:39 ` Qu Wenruo
2019-11-18 20:18 ` [PATCH 0/3] btrfs: More intelligent degraded chunk allocator David Sterba
2019-11-18 23:32 ` Qu Wenruo
2019-11-19 5:18 ` Alberto Bursi
2019-11-27 19:26 ` David Sterba
2019-12-02 3:22 ` Zygo Blaxell
2019-12-02 4:41 ` Qu Wenruo
2019-12-02 19:27 ` Zygo Blaxell
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=20191107062710.67964-2-wqu@suse.com \
--to=wqu@suse.com \
--cc=linux-btrfs@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 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).