Linux Btrfs filesystem development
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 04/12] btrfs-progs: tune: use BTRFS_PATH_AUTO_RELEASE() for on-stack paths
Date: Fri, 30 Oct 2026 14:45:11 +1030	[thread overview]
Message-ID: <5af92f33db87f42aec2c3920166183eedc826d75.1793333606.git.wqu@suse.com> (raw)
In-Reply-To: <cover.1793333606.git.wqu@suse.com>

Convert all on-stack btrfs_path in tune/ to BTRFS_PATH_AUTO_RELEASE(),
and drop the btrfs_release_path() calls that only existed as function
exit cleanup.

Where the path is only used inside one loop (generate_new_data_csums_range(),
delete_old_data_csums(), change_csum_objectids(),
extend_block_group_items()), the variable is declared in the loop body,
so the path is released as early as possible.

This also fixes the path leaks on error paths of:

- get_last_csum_bytenr()
- generate_new_data_csums_range()
- delete_old_data_csums()
- change_meta_csums()
- get_csum_items_range()
- btrfs_change_csum_type() helpers (resume_csum_change())
- extend_block_group_items()
- remove_owner_refs()
- enable_quota()

Explicit releases which are not at function exit are kept.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 tune/change-csum.c        | 50 +++++++++++----------------------------
 tune/change-uuid.c        | 38 ++++++++++-------------------
 tune/convert-remap-tree.c | 12 ++++------
 tune/quota.c              | 19 +++++++--------
 4 files changed, 39 insertions(+), 80 deletions(-)

diff --git a/tune/change-csum.c b/tune/change-csum.c
index 1efb6fd60758..1e01a983ea17 100644
--- a/tune/change-csum.c
+++ b/tune/change-csum.c
@@ -40,7 +40,7 @@ static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_
 {
 	struct btrfs_root *tree_root = fs_info->tree_root;
 	struct btrfs_root *dev_root = fs_info->dev_root;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -73,7 +73,6 @@ static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_
 	key.offset = 0;
 	ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
 	if (ret < 0) {
-		btrfs_release_path(&path);
 		errno = -ret;
 		error("failed to check the dev-replace status: %m");
 		return ret;
@@ -86,7 +85,6 @@ static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_
 		state = btrfs_dev_replace_replace_state(path.nodes[0], ptr);
 		if (state == BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED ||
 		    state == BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED) {
-			btrfs_release_path(&path);
 			error(
 	"running/suspended dev-replace detected, please finish or cancel it");
 			return -EINVAL;
@@ -105,7 +103,7 @@ static int check_csum_change_requreiment(struct btrfs_fs_info *fs_info, u16 new_
 static int get_last_csum_bytenr(struct btrfs_fs_info *fs_info, u64 *result)
 {
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -127,13 +125,11 @@ static int get_last_csum_bytenr(struct btrfs_fs_info *fs_info, u64 *result)
 	 */
 	if (ret > 0) {
 		*result = 0;
-		btrfs_release_path(&path);
 		return 0;
 	}
 	btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 	*result = key.offset + btrfs_item_size(path.nodes[0], path.slots[0]) /
 			       fs_info->csum_size * fs_info->sectorsize;
-	btrfs_release_path(&path);
 	return 0;
 }
 
@@ -239,7 +235,6 @@ static int generate_new_data_csums_range(struct btrfs_fs_info *fs_info, u64 star
 	const unsigned int nr_items = calc_csum_change_nr_items(fs_info, new_csum_type);
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
 	struct btrfs_trans_handle *trans;
-	struct btrfs_path path = { 0 };
 	struct btrfs_key key;
 	void *csum_buffer;
 	u64 converted_bytes = 0;
@@ -266,6 +261,7 @@ static int generate_new_data_csums_range(struct btrfs_fs_info *fs_info, u64 star
 	}
 
 	while (cur < last_csum) {
+		BTRFS_PATH_AUTO_RELEASE(path);
 		u64 csum_start;
 		u64 len;
 		u32 item_size;
@@ -282,13 +278,10 @@ static int generate_new_data_csums_range(struct btrfs_fs_info *fs_info, u64 star
 			ret = btrfs_next_leaf(csum_root, &path);
 			if (ret > 0) {
 				ret = 0;
-				btrfs_release_path(&path);
 				break;
 			}
-			if (ret < 0) {
-				btrfs_release_path(&path);
+			if (ret < 0)
 				goto out;
-			}
 		}
 		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 		UASSERT(key.offset >= cur);
@@ -333,7 +326,7 @@ static int generate_new_data_csums(struct btrfs_fs_info *fs_info, u16 new_csum_t
 {
 	struct btrfs_root *tree_root = fs_info->tree_root;
 	struct btrfs_trans_handle *trans;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -376,7 +369,6 @@ static int delete_old_data_csums(struct btrfs_fs_info *fs_info)
 {
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
 	struct btrfs_trans_handle *trans = 0;
-	struct btrfs_path path = { 0 };
 	struct btrfs_key last_key;
 	unsigned int deleted_leaves = 0;
 	int ret;
@@ -386,6 +378,7 @@ static int delete_old_data_csums(struct btrfs_fs_info *fs_info)
 	last_key.offset = (u64)-1;
 
 	while (true) {
+		BTRFS_PATH_AUTO_RELEASE(path);
 		int start_slot;
 		int nr;
 
@@ -444,10 +437,8 @@ static int delete_old_data_csums(struct btrfs_fs_info *fs_info)
 			error("failed to delete items: %m");
 			break;
 		}
-		btrfs_release_path(&path);
 		deleted_leaves++;
 	}
-	btrfs_release_path(&path);
 	if (ret < 0)
 		btrfs_abort_transaction(trans, ret);
 	ret = btrfs_commit_transaction(trans, csum_root);
@@ -464,7 +455,6 @@ static int change_csum_objectids(struct btrfs_fs_info *fs_info)
 {
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
 	struct btrfs_trans_handle *trans = NULL;
-	struct btrfs_path path = { 0 };
 	struct btrfs_key last_key;
 	unsigned int changed_leaves = 0;
 	u64 super_flags;
@@ -475,6 +465,7 @@ static int change_csum_objectids(struct btrfs_fs_info *fs_info)
 	last_key.offset = (u64)-1;
 
 	while (true) {
+		BTRFS_PATH_AUTO_RELEASE(path);
 		struct btrfs_key found_key;
 		int nr;
 
@@ -527,10 +518,8 @@ static int change_csum_objectids(struct btrfs_fs_info *fs_info)
 			path.slots[0] = i;
 			btrfs_set_item_key_safe(fs_info, &path, &found_key);
 		}
-		btrfs_release_path(&path);
 	}
 out:
-	btrfs_release_path(&path);
 	if (ret < 0) {
 		btrfs_abort_transaction(trans, ret);
 		return ret;
@@ -610,7 +599,7 @@ out:
 static int change_meta_csums(struct btrfs_fs_info *fs_info, u16 new_csum_type)
 {
 	struct btrfs_root *extent_root = btrfs_extent_root(fs_info, 0);
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	u64 super_flags;
 	int ret;
@@ -754,7 +743,7 @@ static int get_csum_items_range(struct btrfs_fs_info *fs_info,
 				u32 *last_item_size)
 {
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -773,17 +762,14 @@ static int get_csum_items_range(struct btrfs_fs_info *fs_info,
 		if (ret < 0) {
 			errno = -ret;
 			error("failed to search csum tree: %m");
-			btrfs_release_path(&path);
 			return ret;
 		}
 		/*
 		 * There is no next leaf, meaning we didn't find any csum item
 		 * with given objectid.
 		 */
-		if (ret > 0) {
-			btrfs_release_path(&path);
+		if (ret > 0)
 			return ret;
-		}
 	}
 
 	btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
@@ -808,16 +794,12 @@ static int get_csum_items_range(struct btrfs_fs_info *fs_info,
 	if (ret < 0) {
 		errno = -ret;
 		error("failed to search csum tree: %m");
-		btrfs_release_path(&path);
 		return ret;
 	}
-	if (ret > 0) {
-		btrfs_release_path(&path);
+	if (ret > 0)
 		return 1;
-	}
 	btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
 	*last_item_size = btrfs_item_size(path.nodes[0], path.slots[0]);
-	btrfs_release_path(&path);
 	*last_ret = key.offset;
 	return 0;
 }
@@ -834,7 +816,7 @@ static int determine_csum_type(struct btrfs_fs_info *fs_info, u64 logical,
 			       u16 csum_type)
 {
 	struct btrfs_root *csum_root = btrfs_csum_root(fs_info, logical);
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	u16 csum_size = btrfs_csum_type_size(csum_type);
 	u8 csum_expected[BTRFS_CSUM_SIZE];
@@ -851,7 +833,6 @@ static int determine_csum_type(struct btrfs_fs_info *fs_info, u64 logical,
 	if (ret < 0) {
 		errno = -ret;
 		error("failed to search csum tree: %m");
-		btrfs_release_path(&path);
 		return ret;
 	}
 
@@ -859,10 +840,8 @@ static int determine_csum_type(struct btrfs_fs_info *fs_info, u64 logical,
 	 * The csum item size is smaller than expected csum size, no
 	 * more need to check.
 	 */
-	if (btrfs_item_size(path.nodes[0], path.slots[0]) < csum_size) {
-		btrfs_release_path(&path);
+	if (btrfs_item_size(path.nodes[0], path.slots[0]) < csum_size)
 		return 1;
-	}
 	read_extent_buffer(path.nodes[0], csum_expected,
 			   btrfs_item_ptr_offset(path.nodes[0], path.slots[0]),
 			   csum_size);
@@ -1009,7 +988,7 @@ static int resume_csum_change(struct btrfs_fs_info *fs_info, u16 new_csum_type)
 {
 	const u64 super_flags = btrfs_super_flags(fs_info->super_copy);
 	struct btrfs_root *tree_root = fs_info->tree_root;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -1039,7 +1018,6 @@ static int resume_csum_change(struct btrfs_fs_info *fs_info, u16 new_csum_type)
 	if (ret < 0) {
 		errno = -ret;
 		error("failed to locate the csum change item: %m");
-		btrfs_release_path(&path);
 		return ret;
 	}
 	btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
diff --git a/tune/change-uuid.c b/tune/change-uuid.c
index c24cba7080bf..db63e446ac8f 100644
--- a/tune/change-uuid.c
+++ b/tune/change-uuid.c
@@ -84,7 +84,7 @@ static int change_buffer_header_uuid(struct extent_buffer *eb, uuid_t new_fsid)
 static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsid)
 {
 	struct btrfs_root *root = btrfs_extent_root(fs_info, 0);
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key = {0, 0, 0};
 	int ret = 0;
 
@@ -94,7 +94,7 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi
 	 */
 	ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	while (1) {
 		struct btrfs_extent_item *ei;
@@ -117,29 +117,22 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi
 		eb = read_tree_block(fs_info, bytenr, &check);
 		if (IS_ERR(eb)) {
 			error("failed to read tree block: %llu", bytenr);
-			ret = PTR_ERR(eb);
-			goto out;
+			return PTR_ERR(eb);
 		}
 		ret = change_buffer_header_uuid(eb, new_fsid);
 		free_extent_buffer(eb);
 		if (ret < 0) {
 			error("failed to change uuid of tree block: %llu",
 				bytenr);
-			goto out;
+			return ret;
 		}
 next:
 		ret = btrfs_next_item(root, &path);
 		if (ret < 0)
-			goto out;
-		if (ret > 0) {
-			ret = 0;
-			goto out;
-		}
+			return ret;
+		if (ret > 0)
+			return 0;
 	}
-
-out:
-	btrfs_release_path(&path);
-	return ret;
 }
 
 static int change_device_uuid(struct extent_buffer *eb, int slot,
@@ -164,14 +157,14 @@ static int change_device_uuid(struct extent_buffer *eb, int slot,
 
 static int change_chunk_tree_uuid(struct btrfs_root *root, uuid_t new_fsid)
 {
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key = {0, 0, 0};
 	int ret = 0;
 
 	/* No transaction again */
 	ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
 	if (ret < 0)
-		goto out;
+		return ret;
 
 	while (1) {
 		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
@@ -181,19 +174,14 @@ static int change_chunk_tree_uuid(struct btrfs_root *root, uuid_t new_fsid)
 		ret = change_device_uuid(path.nodes[0], path.slots[0],
 					 new_fsid);
 		if (ret < 0)
-			goto out;
+			return ret;
 next:
 		ret = btrfs_next_item(root, &path);
 		if (ret < 0)
-			goto out;
-		if (ret > 0) {
-			ret = 0;
-			goto out;
-		}
+			return ret;
+		if (ret > 0)
+			return 0;
 	}
-out:
-	btrfs_release_path(&path);
-	return ret;
 }
 
 static int change_fsid_done(struct btrfs_fs_info *fs_info)
diff --git a/tune/convert-remap-tree.c b/tune/convert-remap-tree.c
index 21f1f4e2ffc5..6bc8f14fd7e7 100644
--- a/tune/convert-remap-tree.c
+++ b/tune/convert-remap-tree.c
@@ -98,7 +98,6 @@ static int create_remap_tree(struct btrfs_trans_handle *trans)
 static int extend_block_group_items(struct btrfs_trans_handle *trans)
 {
 	struct btrfs_fs_info *fs_info = trans->fs_info;
-	struct btrfs_path path = { 0 };
 	struct btrfs_key key = { 0 };
 	struct extent_buffer *leaf;
 	struct btrfs_block_group_item_v2 *bgi;
@@ -106,6 +105,8 @@ static int extend_block_group_items(struct btrfs_trans_handle *trans)
 	u32 size;
 
 	while (true) {
+		BTRFS_PATH_AUTO_RELEASE(path);
+
 		ret = btrfs_search_slot(trans, fs_info->block_group_root, &key,
 					&path, -1, 1);
 		if (ret < 0)
@@ -113,10 +114,8 @@ static int extend_block_group_items(struct btrfs_trans_handle *trans)
 
 		leaf = path.nodes[0];
 
-		if (path.slots[0] >= btrfs_header_nritems(leaf)) {
-			btrfs_release_path(&path);
+		if (path.slots[0] >= btrfs_header_nritems(leaf))
 			break;
-		}
 
 		while (path.slots[0] < btrfs_header_nritems(leaf)) {
 			btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
@@ -143,8 +142,6 @@ static int extend_block_group_items(struct btrfs_trans_handle *trans)
 
 		key.objectid++;
 		key.offset = 0;
-
-		btrfs_release_path(&path);
 	}
 
 	return 0;
@@ -154,7 +151,7 @@ int convert_to_remap_tree(struct btrfs_fs_info *fs_info)
 {
 	struct btrfs_super_block *sb = fs_info->super_copy;
 	struct btrfs_trans_handle *trans;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int ret;
 
@@ -166,7 +163,6 @@ int convert_to_remap_tree(struct btrfs_fs_info *fs_info)
 		return ret;
 
 	if (!ret) {
-		btrfs_release_path(&path);
 		error("cannot convert filesystem that has balance already in progress");
 		return -EINVAL;
 	}
diff --git a/tune/quota.c b/tune/quota.c
index 746c0ef0a258..a5f7fb40c73f 100644
--- a/tune/quota.c
+++ b/tune/quota.c
@@ -86,7 +86,7 @@ static int remove_owner_refs(struct btrfs_fs_info *fs_info)
 	struct btrfs_root *extent_root;
 	struct btrfs_key key;
 	struct extent_buffer *leaf;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	int slot;
 	int ret;
 
@@ -170,7 +170,7 @@ static int create_qgroup(struct btrfs_fs_info *fs_info,
 			 struct btrfs_trans_handle *trans,
 			 u64 qgroupid)
 {
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_root *quota_root = fs_info->quota_root;
 	struct btrfs_key key;
 	int ret;
@@ -195,7 +195,6 @@ static int create_qgroup(struct btrfs_fs_info *fs_info,
 	key.offset = qgroupid;
 	ret = btrfs_insert_empty_item(trans, quota_root, &path, &key,
 				      sizeof(struct btrfs_qgroup_limit_item));
-	btrfs_release_path(&path);
 
 	printf("created qgroup for %llu\n", qgroupid);
 	return ret;
@@ -209,7 +208,7 @@ static int create_qgroups(struct btrfs_fs_info *fs_info,
 		.type = BTRFS_ROOT_REF_KEY,
 		.offset = 0,
 	};
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct extent_buffer *leaf;
 	int slot;
 	struct btrfs_root *tree_root = fs_info->tree_root;
@@ -218,11 +217,11 @@ static int create_qgroups(struct btrfs_fs_info *fs_info,
 
 	ret = create_qgroup(fs_info, trans, BTRFS_FS_TREE_OBJECTID);
 	if (ret)
-		goto out;
+		return ret;
 
 	ret = btrfs_search_slot_for_read(tree_root, &key, &path, 1, 0);
 	if (ret)
-		goto out;
+		return ret;
 
 	while (1) {
 		slot = path.slots[0];
@@ -231,19 +230,17 @@ static int create_qgroups(struct btrfs_fs_info *fs_info,
 		if (key.type == BTRFS_ROOT_REF_KEY) {
 			ret = create_qgroup(fs_info, trans, key.offset);
 			if (ret)
-				goto out;
+				return ret;
 		}
 		ret = btrfs_next_item(tree_root, &path);
 		if (ret < 0) {
 			error("failed to advance to next item");
-			goto out;
+			return ret;
 		}
 		if (ret)
 			break;
 	}
 
-out:
-	btrfs_release_path(&path);
 	return ret;
 }
 
@@ -254,7 +251,7 @@ int enable_quota(struct btrfs_fs_info *fs_info, bool simple)
 	int super_flags = btrfs_super_incompat_flags(sb);
 	struct btrfs_qgroup_status_item *qsi;
 	struct btrfs_root *quota_root;
-	struct btrfs_path path = { 0 };
+	BTRFS_PATH_AUTO_RELEASE(path);
 	struct btrfs_key key;
 	int flags;
 	int ret;
-- 
2.56.0


  parent reply	other threads:[~2026-10-30  4:15 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30  4:15 [PATCH 00/12] btrfs-progs: fix btrfs_path leak, part 2 Qu Wenruo
2026-10-30  4:15 ` [PATCH 01/12] btrfs-progs: kernel-shared: use BTRFS_PATH_AUTO_RELEASE() for on-stack paths Qu Wenruo
2026-10-30  4:15 ` [PATCH 02/12] btrfs-progs: common, convert, image: " Qu Wenruo
2026-10-30  4:15 ` [PATCH 03/12] btrfs-progs: mkfs: " Qu Wenruo
2026-10-30  4:15 ` Qu Wenruo [this message]
2026-10-30  4:15 ` [PATCH 05/12] btrfs-progs: cmds: " Qu Wenruo
2026-10-30  4:15 ` [PATCH 06/12] btrfs-progs: check: use BTRFS_PATH_AUTO_RELEASE() for repair, qgroup-verify and mode-common Qu Wenruo
2026-10-30  4:15 ` [PATCH 07/12] btrfs-progs: check: use BTRFS_PATH_AUTO_RELEASE() for lowmem mode Qu Wenruo
2026-10-30  4:15 ` [PATCH 08/12] btrfs-progs: check: use BTRFS_PATH_AUTO_RELEASE() for original mode Qu Wenruo
2026-10-30  4:15 ` [PATCH 09/12] btrfs-progs: check: fix fixup_extent_flags() retry path Qu Wenruo
2026-10-30  4:15 ` [PATCH 10/12] btrfs-progs: fix missing transaction commit in truncate_free_ino_items() Qu Wenruo
2026-10-30  4:15 ` [PATCH 11/12] btrfs-progs: dump-tree: fix exit code and leak on open failure Qu Wenruo
2026-10-30  4:15 ` [PATCH 12/12] btrfs-progs: check: return error if fill_csum_tree_from_fs() fails to read a root Qu Wenruo
2026-10-30  4:19 ` [PATCH 00/12] btrfs-progs: fix btrfs_path leak, part 2 Qu Wenruo

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=5af92f33db87f42aec2c3920166183eedc826d75.1793333606.git.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