All of lore.kernel.org
 help / color / mirror / Atom feed
From: Goffredo Baroncelli <kreijack@libero.it>
To: linux-btrfs@vger.kernel.org
Cc: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>,
	Qu Wenruo <quwenruo.btrfs@gmx.com>,
	David Sterba <dsterba@suse.com>,
	Graham Cobb <g.btrfs@cobb.uk.net>,
	Goffredo Baroncelli <kreijack@inwind.it>
Subject: [PATCH 1/5] btrfs-progs: Add code for checking mixed profile  function
Date: Sat,  4 Apr 2020 12:32:08 +0200	[thread overview]
Message-ID: <20200404103212.40986-2-kreijack@libero.it> (raw)
In-Reply-To: <20200404103212.40986-1-kreijack@libero.it>

From: Goffredo Baroncelli <kreijack@inwind.it>

Add code to show a warning if a mixed profiles filesystem is detected.

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
---
 common/utils.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++
 common/utils.h |  11 +++
 2 files changed, 199 insertions(+)

diff --git a/common/utils.c b/common/utils.c
index a7761683..5c9ff562 100644
--- a/common/utils.c
+++ b/common/utils.c
@@ -1710,3 +1710,191 @@ void print_all_devices(struct list_head *devices)
 		print_device_info(dev, "\t");
 	printf("\n");
 }
+
+static int bit_count(u64 x)
+{
+	int ret = 0;
+
+	while (x) {
+		if (x & 1)
+			ret++;
+		x >>= 1;
+	}
+	return ret;
+}
+
+static void sprint_profiles(char **ptr, u64 profiles)
+{
+	int i;
+	int first = true;
+	int l = 1;
+
+	*ptr = NULL;
+
+	for (i = 0 ; i < BTRFS_NR_RAID_TYPES ; i++)
+		l += strlen(btrfs_raid_array[i].raid_name) + 2;
+
+	*ptr = malloc(l);
+	if (!*ptr)
+		return;
+	**ptr = 0;
+
+	for (i = 0 ; i < BTRFS_NR_RAID_TYPES ; i++) {
+		if (!(btrfs_raid_array[i].bg_flag & profiles))
+			continue;
+
+		if (!first)
+			strcat(*ptr, ", ");
+		strcat(*ptr, btrfs_raid_array[i].raid_name);
+		first = false;
+	}
+	if (profiles & BTRFS_AVAIL_ALLOC_BIT_SINGLE) {
+		if (!first)
+			strcat(*ptr, ", ");
+		strcat(*ptr, btrfs_raid_array[BTRFS_RAID_SINGLE].raid_name);
+	}
+}
+
+int btrfs_string_check_for_mixed_profiles_by_fd(int fd, char **data_ret,
+							char **metadata_ret,
+							char **mixed_ret,
+							char **system_ret)
+{
+	int ret;
+	int i;
+	struct btrfs_ioctl_space_args *sargs;
+	u64 data_profiles = 0;
+	u64 metadata_profiles = 0;
+	u64 system_profiles = 0;
+	u64 mixed_profiles = 0;
+	static const u64 mixed_profile_fl = BTRFS_BLOCK_GROUP_METADATA |
+		BTRFS_BLOCK_GROUP_DATA;
+
+	ret = get_df(fd, &sargs);
+	if (ret < 0)
+		return -1;
+
+	for (i = 0 ; i < sargs->total_spaces ; i++) {
+		u64 flags = sargs->spaces[i].flags;
+
+		if (!(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK))
+			flags |= BTRFS_AVAIL_ALLOC_BIT_SINGLE;
+
+		if ((flags & mixed_profile_fl) == mixed_profile_fl)
+			mixed_profiles |= flags;
+		else if (flags & BTRFS_BLOCK_GROUP_DATA)
+			data_profiles |= flags;
+		else if (flags & BTRFS_BLOCK_GROUP_METADATA)
+			metadata_profiles |= flags;
+		else if (flags & BTRFS_BLOCK_GROUP_SYSTEM)
+			system_profiles |= flags;
+	}
+	free(sargs);
+
+	data_profiles &= BTRFS_EXTENDED_PROFILE_MASK;
+	system_profiles &= BTRFS_EXTENDED_PROFILE_MASK;
+	mixed_profiles &= BTRFS_EXTENDED_PROFILE_MASK;
+	metadata_profiles &= BTRFS_EXTENDED_PROFILE_MASK;
+
+	if ((bit_count(data_profiles) <= 1) &&
+	    (bit_count(metadata_profiles) <= 1) &&
+	    (bit_count(system_profiles) <= 1) &&
+	    (bit_count(mixed_profiles) <= 1))
+		return 0;
+
+	if (data_ret) {
+		if (bit_count(data_profiles) > 1)
+			sprint_profiles(data_ret, data_profiles);
+		else
+			*data_ret = NULL;
+	}
+	if (metadata_ret) {
+		if (bit_count(metadata_profiles) > 1)
+			sprint_profiles(metadata_ret, metadata_profiles);
+		else
+			*metadata_ret = NULL;
+	}
+	if (mixed_ret) {
+		if (bit_count(mixed_profiles) > 1)
+			sprint_profiles(mixed_ret, mixed_profiles);
+		else
+			*mixed_ret = NULL;
+	}
+	if (system_ret) {
+		if (bit_count(system_profiles) > 1)
+			sprint_profiles(system_ret, system_profiles);
+		else
+			*system_ret = NULL;
+	}
+
+	return 1;
+}
+
+int btrfs_check_for_mixed_profiles_by_path(char *path)
+{
+	int fd;
+	int ret;
+	DIR *dirstream;
+
+	fd = btrfs_open_dir(path, &dirstream, 0);
+	if (fd < 0)
+		return -1;
+	closedir(dirstream);
+
+	ret = btrfs_check_for_mixed_profiles_by_fd(fd);
+	close(fd);
+
+	return ret;
+}
+
+int btrfs_check_for_mixed_profiles_by_fd(int fd)
+{
+	int ret;
+	int first = true;
+	char *data_prof, *mixed_prof, *metadata_prof, *system_prof;
+
+	ret = btrfs_string_check_for_mixed_profiles_by_fd(fd, &data_prof,
+			&metadata_prof, &mixed_prof, &system_prof);
+
+	if (ret != 1)
+		return ret;
+
+	fprintf(stderr,
+		"WARNING: Multiple profiles detected.  See 'man btrfs(5)'.\n");
+	fprintf(stderr, "WARNING: ");
+	if (data_prof) {
+		fprintf(stderr, "data -> [%s]", data_prof);
+		first = false;
+	}
+	if (metadata_prof) {
+		if (!first)
+			fprintf(stderr, ", ");
+		fprintf(stderr, "metadata -> [%s]", metadata_prof);
+		first = false;
+	}
+	if (mixed_prof) {
+		if (!first)
+			fprintf(stderr, ", ");
+		fprintf(stderr, "data+metadata -> [%s]", mixed_prof);
+		first = false;
+	}
+	if (system_prof) {
+		if (!first)
+			fprintf(stderr, ", ");
+		fprintf(stderr, "system -> [%s]", system_prof);
+		first = false;
+	}
+
+	fprintf(stderr, "\n");
+
+	if (data_prof)
+		free(data_prof);
+	if (metadata_prof)
+		free(metadata_prof);
+	if (mixed_prof)
+		free(mixed_prof);
+	if (system_prof)
+		free(system_prof);
+
+	return 1;
+}
diff --git a/common/utils.h b/common/utils.h
index 5c1afda9..c4e6e935 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -137,4 +137,15 @@ u64 rand_u64(void);
 unsigned int rand_range(unsigned int upper);
 void init_rand_seed(u64 seed);
 
+int btrfs_string_check_for_mixed_profiles_by_fd(int fd, char **data_ret,
+							char **metadata_ret,
+							char **mixed_ret,
+							char **system_ret);
+static inline int btrfs_test_for_mixed_profiles_by_fd(int fd)
+{
+	return btrfs_string_check_for_mixed_profiles_by_fd(fd, 0L, 0L, 0L, 0L);
+}
+int btrfs_check_for_mixed_profiles_by_path(char *path);
+int btrfs_check_for_mixed_profiles_by_fd(int fd);
+
 #endif
-- 
2.26.0


  reply	other threads:[~2020-04-04 10:32 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-04 10:32 [PATCH v3] btrfs-progs: add warning for mixed profiles filesystem Goffredo Baroncelli
2020-04-04 10:32 ` Goffredo Baroncelli [this message]
2020-04-04 10:32 ` [PATCH 2/5] btrfs-progs: Add mixed profiles check to some btrfs sub-commands Goffredo Baroncelli
2020-04-04 10:32 ` [PATCH 3/5] Add check for multiple profile in btrfs fi us Goffredo Baroncelli
2020-04-04 10:32 ` [PATCH 4/5] Add further check in btrfs subcommand Goffredo Baroncelli
2020-04-04 10:32 ` [PATCH 5/5] Update the man page in order to give a guideline about mixed profiles Goffredo Baroncelli
2020-04-06 17:57 ` [PATCH v3] btrfs-progs: add warning for mixed profiles filesystem David Sterba
2020-04-30 16:09   ` David Sterba
2020-04-30 13:37 ` Johannes Thumshirn
2020-04-30 14:04   ` David Sterba

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=20200404103212.40986-2-kreijack@libero.it \
    --to=kreijack@libero.it \
    --cc=ce3g8jdj@umail.furryterror.org \
    --cc=dsterba@suse.com \
    --cc=g.btrfs@cobb.uk.net \
    --cc=kreijack@inwind.it \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=quwenruo.btrfs@gmx.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 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.