diff mbox series

[7/8] btrfs-progs: check/lowmem: Implement received info clearing for RW volumes

Message ID 20210913131729.37897-8-nborisov@suse.com (mailing list archive)
State New, archived
Headers show
Series Implement progs support for removing received uuid on RW vols | expand

Commit Message

Nikolay Borisov Sept. 13, 2021, 1:17 p.m. UTC
This is the counterpart to the original mode's implementation but for
lowmem. I've put the code under the  if (!check_all) branch because
otherwise the check is run multiple times - from check_chunks_and_extents_lowmem
and from actual fs_root check. By having it under the !check_all
condition in check_btrfs_root it ensures that the check is performed
only when checking the fs roots themselves.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 check/mode-lowmem.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)
diff mbox series

Patch

diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index 323e66bc4cb1..70cf164752ff 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -5197,6 +5197,44 @@  static int check_btrfs_root(struct btrfs_root *root, int check_all)
 		ret = check_fs_first_inode(root);
 		if (ret < 0)
 			return FATAL_ERROR;
+
+		if (!((btrfs_root_flags(root_item) & BTRFS_ROOT_SUBVOL_RDONLY) ||
+					btrfs_is_empty_uuid(root_item->received_uuid))) {
+			printf("Subvolume id: %llu is RW and has a received uuid\n",
+					root->root_key.objectid);
+			if (repair) {
+				struct btrfs_trans_handle *trans = btrfs_start_transaction(root, 2);
+				if (IS_ERR(trans))
+					return PTR_ERR(trans);
+
+				ret = btrfs_uuid_tree_remove(trans, root_item->received_uuid,
+						BTRFS_UUID_KEY_RECEIVED_SUBVOL, root->root_key.objectid);
+
+				if (ret && ret != -ENOENT) {
+					btrfs_abort_transaction(trans, ret);
+					return ret;
+				}
+
+				memset(root_item->received_uuid, 0, BTRFS_UUID_SIZE);
+				btrfs_set_root_stransid(root_item, 0);
+				btrfs_set_root_rtransid(root_item, 0);
+				btrfs_set_stack_timespec_sec(&root_item->stime, 0);
+				btrfs_set_stack_timespec_nsec(&root_item->stime, 0);
+				btrfs_set_stack_timespec_sec(&root_item->rtime, 0);
+				btrfs_set_stack_timespec_nsec(&root_item->rtime, 0);
+
+				ret = btrfs_update_root(trans, gfs_info->tree_root, &root->root_key,
+						root_item);
+				if (ret < 0) {
+					btrfs_abort_transaction(trans, ret);
+					return ret;
+				}
+
+				btrfs_commit_transaction(trans, gfs_info->tree_root);
+				printf("Cleared received information for subvol: %llu\n",
+						root->root_key.objectid);
+			}
+		}
 	}