All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Implement progs support for removing received uuid on RW vols
@ 2021-09-13 13:17 Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid Nikolay Borisov
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

This series is the userspace counter part to a kernel patch titled:
"btrfs: Remove received information from snapshot on ro->rw switch". This will
mainly serve people running old kernels that won't have this patch to be able to
remove received uuid et al from snapshots which have been switched RO->RW. This
is to ensure consistency.

First 3 patches are preparatory ones which pull needed code from the kernel as
well as removing some arguments making respective functions as close to their
kernel counterparts as possible. This enables to simply copy btrfs_uuid_tree_remove
with no changes from the kernel.

Next 2 patches implement detection and repair support for RO->RW-switched volumes
which have been received. And the final patch is an fs image with a received
subvolume that has been switched to RW following a receive.

Nikolay Borisov (8):
  btrfs-progs: Add btrfs_is_empty_uuid
  btrfs-progs: Remove root argument from btrfs_fixup_low_keys
  btrfs-progs: Remove fs_info argument from leaf_data_end
  btrfs-progs: Remove root argument from btrfs_truncate_item
  btrfs-progs: Add btrfs_uuid_tree_remove
  btrfs-progs: check/original: Implement removing received data for RW
    subvols
  btrfs-progs: check/lowmem: Implement received info clearing for RW
    volumes
  btrfs-progs: tests: Add test for received information removal

 check/main.c                                  |  48 ++++++++-
 check/mode-lowmem.c                           |  38 +++++++
 kernel-shared/ctree.c                         |  62 +++++-------
 kernel-shared/ctree.h                         |  12 ++-
 kernel-shared/dir-item.c                      |   2 +-
 kernel-shared/extent-tree.c                   |   2 +-
 kernel-shared/file-item.c                     |   4 +-
 kernel-shared/inode-item.c                    |   4 +-
 kernel-shared/uuid-tree.c                     |  93 ++++++++++++++++++
 .../050-subvol-recv-clear/test.raw.xz         | Bin 0 -> 493524 bytes
 10 files changed, 216 insertions(+), 49 deletions(-)
 create mode 100644 tests/fsck-tests/050-subvol-recv-clear/test.raw.xz

--
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-14  0:58   ` Qu Wenruo
  2021-09-13 13:17 ` [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys Nikolay Borisov
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

This utility function is needed by the RO->RW snapshot detection code.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 kernel-shared/ctree.h     |  2 ++
 kernel-shared/uuid-tree.c | 11 +++++++++++
 2 files changed, 13 insertions(+)

diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 3cca60323e3d..f53436a7f38b 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2860,6 +2860,8 @@ int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid,
 int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
 			u64 subvol_id_cpu);
 
+int btrfs_is_empty_uuid(u8 *uuid);
+
 static inline int is_fstree(u64 rootid)
 {
 	if (rootid == BTRFS_FS_TREE_OBJECTID ||
diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
index 21115a4d2d09..51a7b5d9ff5d 100644
--- a/kernel-shared/uuid-tree.c
+++ b/kernel-shared/uuid-tree.c
@@ -109,3 +109,14 @@ int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid,
 					  BTRFS_UUID_KEY_RECEIVED_SUBVOL,
 					  subvol_id);
 }
+
+int btrfs_is_empty_uuid(u8 *uuid)
+{
+	int i;
+
+	for (i = 0; i < BTRFS_UUID_SIZE; i++) {
+		if (uuid[i])
+			return 0;
+	}
+	return 1;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-14  1:01   ` Qu Wenruo
  2021-09-13 13:17 ` [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end Nikolay Borisov
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

It's not used, so just remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 check/main.c          |  5 ++---
 kernel-shared/ctree.c | 24 +++++++++++-------------
 kernel-shared/ctree.h |  4 ++--
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/check/main.c b/check/main.c
index a88518159830..6369bdd90656 100644
--- a/check/main.c
+++ b/check/main.c
@@ -4197,8 +4197,7 @@ static int swap_values(struct btrfs_root *root, struct btrfs_path *path,
 			struct btrfs_disk_key key;
 
 			btrfs_node_key(buf, &key, 0);
-			btrfs_fixup_low_keys(root, path, &key,
-					     btrfs_header_level(buf) + 1);
+			btrfs_fixup_low_keys(path, &key, btrfs_header_level(buf) + 1);
 		}
 	} else {
 		struct btrfs_item *item1, *item2;
@@ -4302,7 +4301,7 @@ static int delete_bogus_item(struct btrfs_root *root,
 		struct btrfs_disk_key disk_key;
 
 		btrfs_item_key(buf, &disk_key, 0);
-		btrfs_fixup_low_keys(root, path, &disk_key, 1);
+		btrfs_fixup_low_keys(path, &disk_key, 1);
 	}
 	btrfs_mark_buffer_dirty(buf);
 	return 0;
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 518718de04dd..02eb975338e5 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -1437,8 +1437,8 @@ int btrfs_search_slot_for_read(struct btrfs_root *root,
  * fixing up pointers when a given leaf/node is not in slot 0 of the
  * higher levels
  */
-void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
-			  struct btrfs_disk_key *key, int level)
+void btrfs_fixup_low_keys( struct btrfs_path *path, struct btrfs_disk_key *key,
+		int level)
 {
 	int i;
 	struct extent_buffer *t;
@@ -1485,7 +1485,7 @@ int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path,
 	btrfs_set_item_key(eb, &disk_key, slot);
 	btrfs_mark_buffer_dirty(eb);
 	if (slot == 0)
-		btrfs_fixup_low_keys(root, path, &disk_key, 1);
+		btrfs_fixup_low_keys(path, &disk_key, 1);
 	return 0;
 }
 
@@ -1508,7 +1508,7 @@ void btrfs_set_item_key_unsafe(struct btrfs_root *root,
 	btrfs_set_item_key(eb, &disk_key, slot);
 	btrfs_mark_buffer_dirty(eb);
 	if (slot == 0)
-		btrfs_fixup_low_keys(root, path, &disk_key, 1);
+		btrfs_fixup_low_keys(path, &disk_key, 1);
 }
 
 /*
@@ -2184,7 +2184,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
 		btrfs_mark_buffer_dirty(right);
 
 	btrfs_item_key(right, &disk_key, 0);
-	btrfs_fixup_low_keys(root, path, &disk_key, 1);
+	btrfs_fixup_low_keys(path, &disk_key, 1);
 
 	/* then fixup the leaf pointer in the path */
 	if (path->slots[0] < push_items) {
@@ -2415,10 +2415,8 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
 			free_extent_buffer(path->nodes[0]);
 			path->nodes[0] = right;
 			path->slots[0] = 0;
-			if (path->slots[1] == 0) {
-				btrfs_fixup_low_keys(root, path,
-						     &disk_key, 1);
-			}
+			if (path->slots[1] == 0)
+				btrfs_fixup_low_keys(path, &disk_key, 1);
 		}
 		btrfs_mark_buffer_dirty(right);
 		return ret;
@@ -2632,7 +2630,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
 		btrfs_set_disk_key_offset(&disk_key, offset + size_diff);
 		btrfs_set_item_key(leaf, &disk_key, slot);
 		if (slot == 0)
-			btrfs_fixup_low_keys(root, path, &disk_key, 1);
+			btrfs_fixup_low_keys(path, &disk_key, 1);
 	}
 
 	item = btrfs_item_nr(slot);
@@ -2809,7 +2807,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
 	ret = 0;
 	if (slot == 0) {
 		btrfs_cpu_key_to_disk(&disk_key, cpu_key);
-		btrfs_fixup_low_keys(root, path, &disk_key, 1);
+		btrfs_fixup_low_keys(path, &disk_key, 1);
 	}
 
 	if (btrfs_leaf_free_space(leaf) < 0) {
@@ -2882,7 +2880,7 @@ int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path,
 		struct btrfs_disk_key disk_key;
 
 		btrfs_node_key(parent, &disk_key, 0);
-		btrfs_fixup_low_keys(root, path, &disk_key, level + 1);
+		btrfs_fixup_low_keys(path, &disk_key, level + 1);
 	}
 	btrfs_mark_buffer_dirty(parent);
 	return ret;
@@ -2982,7 +2980,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 			struct btrfs_disk_key disk_key;
 
 			btrfs_item_key(leaf, &disk_key, 0);
-			btrfs_fixup_low_keys(root, path, &disk_key, 1);
+			btrfs_fixup_low_keys(path, &disk_key, 1);
 		}
 
 		/* delete the leaf if it is mostly empty */
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index f53436a7f38b..a17bf50e29b4 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2747,8 +2747,8 @@ static inline int btrfs_next_item(struct btrfs_root *root,
 
 int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
 int btrfs_leaf_free_space(struct extent_buffer *leaf);
-void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
-			  struct btrfs_disk_key *key, int level);
+void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
+		int level);
 int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path,
 			    struct btrfs_key *new_key);
 void btrfs_set_item_key_unsafe(struct btrfs_root *root,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-14  1:02   ` Qu Wenruo
  2021-09-13 13:17 ` [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item Nikolay Borisov
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

The function already takes an extent_buffer which has a reference to
the owning filesystem's fs_info. This also brings the function in line
with the kernel's signature.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 kernel-shared/ctree.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 02eb975338e5..77766c2a7931 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -557,12 +557,11 @@ static int btrfs_comp_keys(struct btrfs_disk_key *disk,
  * this returns the address of the start of the last item,
  * which is the stop of the leaf data stack
  */
-static inline unsigned int leaf_data_end(const struct btrfs_fs_info *fs_info,
-					 const struct extent_buffer *leaf)
+static inline unsigned int leaf_data_end(const struct extent_buffer *leaf)
 {
 	u32 nr = btrfs_header_nritems(leaf);
 	if (nr == 0)
-		return BTRFS_LEAF_DATA_SIZE(fs_info);
+		return BTRFS_LEAF_DATA_SIZE(leaf->fs_info);
 	return btrfs_item_offset_nr(leaf, nr - 1);
 }
 
@@ -1980,10 +1979,10 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
 	right_nritems = btrfs_header_nritems(right);
 
 	push_space = btrfs_item_end_nr(left, left_nritems - push_items);
-	push_space -= leaf_data_end(fs_info, left);
+	push_space -= leaf_data_end(left);
 
 	/* make room in the right data area */
-	data_end = leaf_data_end(fs_info, right);
+	data_end = leaf_data_end(right);
 	memmove_extent_buffer(right,
 			      btrfs_leaf_data(right) + data_end - push_space,
 			      btrfs_leaf_data(right) + data_end,
@@ -1992,8 +1991,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
 	/* copy from the left data area */
 	copy_extent_buffer(right, left, btrfs_leaf_data(right) +
 		     BTRFS_LEAF_DATA_SIZE(root->fs_info) - push_space,
-		     btrfs_leaf_data(left) + leaf_data_end(fs_info, left),
-		     push_space);
+		     btrfs_leaf_data(left) + leaf_data_end(left), push_space);
 
 	memmove_extent_buffer(right, btrfs_item_nr_offset(push_items),
 			      btrfs_item_nr_offset(0),
@@ -2130,7 +2128,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
 		     btrfs_item_offset_nr(right, push_items -1);
 
 	copy_extent_buffer(left, right, btrfs_leaf_data(left) +
-		     leaf_data_end(fs_info, left) - push_space,
+		     leaf_data_end(left) - push_space,
 		     btrfs_leaf_data(right) +
 		     btrfs_item_offset_nr(right, push_items - 1),
 		     push_space);
@@ -2157,13 +2155,12 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
 
 	if (push_items < right_nritems) {
 		push_space = btrfs_item_offset_nr(right, push_items - 1) -
-						  leaf_data_end(fs_info, right);
+						  leaf_data_end(right);
 		memmove_extent_buffer(right, btrfs_leaf_data(right) +
 				      BTRFS_LEAF_DATA_SIZE(root->fs_info) -
 				      push_space,
 				      btrfs_leaf_data(right) +
-				      leaf_data_end(fs_info, right),
-				      push_space);
+				      leaf_data_end(right), push_space);
 
 		memmove_extent_buffer(right, btrfs_item_nr_offset(0),
 			      btrfs_item_nr_offset(push_items),
@@ -2222,8 +2219,7 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
 
 	nritems = nritems - mid;
 	btrfs_set_header_nritems(right, nritems);
-	data_copy_size = btrfs_item_end_nr(l, mid) -
-		leaf_data_end(root->fs_info, l);
+	data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(l);
 
 	copy_extent_buffer(right, l, btrfs_item_nr_offset(0),
 			   btrfs_item_nr_offset(mid),
@@ -2231,9 +2227,8 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
 
 	copy_extent_buffer(right, l,
 		     btrfs_leaf_data(right) +
-		     BTRFS_LEAF_DATA_SIZE(root->fs_info) -
-		     data_copy_size, btrfs_leaf_data(l) +
-		     leaf_data_end(root->fs_info, l), data_copy_size);
+		     BTRFS_LEAF_DATA_SIZE(root->fs_info) - data_copy_size,
+			 btrfs_leaf_data(l) + leaf_data_end(l), data_copy_size);
 
 	rt_data_off = BTRFS_LEAF_DATA_SIZE(root->fs_info) -
 		      btrfs_item_end_nr(l, mid);
@@ -2572,7 +2567,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
 		return 0;
 
 	nritems = btrfs_header_nritems(leaf);
-	data_end = leaf_data_end(root->fs_info, leaf);
+	data_end = leaf_data_end(leaf);
 
 	old_data_start = btrfs_item_offset_nr(leaf, slot);
 
@@ -2661,7 +2656,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
 	leaf = path->nodes[0];
 
 	nritems = btrfs_header_nritems(leaf);
-	data_end = leaf_data_end(root->fs_info, leaf);
+	data_end = leaf_data_end(leaf);
 
 	if (btrfs_leaf_free_space(leaf) < data_size) {
 		btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
@@ -2747,7 +2742,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
 	leaf = path->nodes[0];
 
 	nritems = btrfs_header_nritems(leaf);
-	data_end = leaf_data_end(root->fs_info, leaf);
+	data_end = leaf_data_end(leaf);
 
 	if (btrfs_leaf_free_space(leaf) < total_size) {
 		btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
@@ -2940,7 +2935,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
 	nritems = btrfs_header_nritems(leaf);
 
 	if (slot + nr != nritems) {
-		int data_end = leaf_data_end(root->fs_info, leaf);
+		int data_end = leaf_data_end(leaf);
 
 		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
 			      data_end + dsize,
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
                   ` (2 preceding siblings ...)
  2021-09-13 13:17 ` [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-14  1:02   ` Qu Wenruo
  2021-09-13 13:17 ` [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove Nikolay Borisov
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

This function lies in the kernel-shared directory and is supposed to be
close to 1:1 copy with its kernel counterpart, yet it takes one extra
argument - root. But this is now unused to simply remove it.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 kernel-shared/ctree.c       | 3 +--
 kernel-shared/ctree.h       | 3 +--
 kernel-shared/dir-item.c    | 2 +-
 kernel-shared/extent-tree.c | 2 +-
 kernel-shared/file-item.c   | 4 ++--
 kernel-shared/inode-item.c  | 4 ++--
 6 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 77766c2a7931..78f94c6cd42f 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -2545,8 +2545,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
 	return ret;
 }
 
-int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
-			u32 new_size, int from_end)
+int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end)
 {
 	int ret = 0;
 	int slot;
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index a17bf50e29b4..91a85796a678 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2670,8 +2670,7 @@ int btrfs_create_root(struct btrfs_trans_handle *trans,
 		      struct btrfs_fs_info *fs_info, u64 objectid);
 int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
 		u32 data_size);
-int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
-			u32 new_size, int from_end);
+int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end);
 int btrfs_split_item(struct btrfs_trans_handle *trans,
 		     struct btrfs_root *root,
 		     struct btrfs_path *path,
diff --git a/kernel-shared/dir-item.c b/kernel-shared/dir-item.c
index 7dc606c132b5..590b79a929d3 100644
--- a/kernel-shared/dir-item.c
+++ b/kernel-shared/dir-item.c
@@ -284,7 +284,7 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
 		start = btrfs_item_ptr_offset(leaf, path->slots[0]);
 		memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
 			item_len - (ptr + sub_item_len - start));
-		btrfs_truncate_item(root, path, item_len - sub_item_len, 1);
+		btrfs_truncate_item(path, item_len - sub_item_len, 1);
 	}
 	return ret;
 }
diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c
index 056a9256b9a4..a8e0c1e60e2e 100644
--- a/kernel-shared/extent-tree.c
+++ b/kernel-shared/extent-tree.c
@@ -1166,7 +1166,7 @@ static int update_inline_extent_backref(struct btrfs_trans_handle *trans,
 			memmove_extent_buffer(leaf, ptr, ptr + size,
 					      end - ptr - size);
 		item_size -= size;
-		ret = btrfs_truncate_item(root, path, item_size, 1);
+		ret = btrfs_truncate_item(path, item_size, 1);
 		BUG_ON(ret);
 	}
 	btrfs_mark_buffer_dirty(leaf);
diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c
index 7e16b747e36c..c910e27e5a5d 100644
--- a/kernel-shared/file-item.c
+++ b/kernel-shared/file-item.c
@@ -362,7 +362,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root,
 		 */
 		u32 new_size = (bytenr - key->offset) / blocksize;
 		new_size *= csum_size;
-		ret = btrfs_truncate_item(root, path, new_size, 1);
+		ret = btrfs_truncate_item(path, new_size, 1);
 		BUG_ON(ret);
 	} else if (key->offset >= bytenr && csum_end > end_byte &&
 		   end_byte > key->offset) {
@@ -375,7 +375,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root,
 		u32 new_size = (csum_end - end_byte) / blocksize;
 		new_size *= csum_size;
 
-		ret = btrfs_truncate_item(root, path, new_size, 0);
+		ret = btrfs_truncate_item(path, new_size, 0);
 		BUG_ON(ret);
 
 		key->offset = end_byte;
diff --git a/kernel-shared/inode-item.c b/kernel-shared/inode-item.c
index 4e009746de0e..67173eb141d8 100644
--- a/kernel-shared/inode-item.c
+++ b/kernel-shared/inode-item.c
@@ -311,7 +311,7 @@ int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
 	memmove_extent_buffer(leaf, ptr, ptr + del_len,
 			      item_size - (ptr + del_len - item_start));
 
-	btrfs_truncate_item(root, path, item_size - del_len, 1);
+	btrfs_truncate_item(path, item_size - del_len, 1);
 
 out:
 	btrfs_free_path(path);
@@ -432,7 +432,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
 	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
 	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
 			      item_size - (ptr + sub_item_len - item_start));
-	btrfs_truncate_item(root, path, item_size - sub_item_len, 1);
+	btrfs_truncate_item(path, item_size - sub_item_len, 1);
 	btrfs_mark_buffer_dirty(path->nodes[0]);
 out:
 	btrfs_free_path(path);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
                   ` (3 preceding siblings ...)
  2021-09-13 13:17 ` [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-14  1:07   ` Qu Wenruo
  2021-09-13 13:17 ` [PATCH 6/8] btrfs-progs: check/original: Implement removing received data for RW subvols Nikolay Borisov
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

It will be used to clear received data on RW snapshots that were
received.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 kernel-shared/ctree.h     |  3 ++
 kernel-shared/uuid-tree.c | 82 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 91a85796a678..158281a9fd67 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2860,6 +2860,9 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
 			u64 subvol_id_cpu);
 
 int btrfs_is_empty_uuid(u8 *uuid);
+int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
+               u64 subid);
+
 
 static inline int is_fstree(u64 rootid)
 {
diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
index 51a7b5d9ff5d..0f0fbf667dda 100644
--- a/kernel-shared/uuid-tree.c
+++ b/kernel-shared/uuid-tree.c
@@ -120,3 +120,85 @@ int btrfs_is_empty_uuid(u8 *uuid)
 	}
 	return 1;
 }
+
+int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
+		u64 subid)
+{
+	struct btrfs_fs_info *fs_info = trans->fs_info;
+	struct btrfs_root *uuid_root = fs_info->uuid_root;
+	int ret;
+	struct btrfs_path *path = NULL;
+	struct btrfs_key key;
+	struct extent_buffer *eb;
+	int slot;
+	unsigned long offset;
+	u32 item_size;
+	unsigned long move_dst;
+	unsigned long move_src;
+	unsigned long move_len;
+
+	if (!uuid_root) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	btrfs_uuid_to_key(uuid, &key);
+	key.type = type;
+
+	path = btrfs_alloc_path();
+	if (!path) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = btrfs_search_slot(trans, uuid_root, &key, path, -1, 1);
+	if (ret < 0) {
+		warning("error %d while searching for uuid item!", ret);
+		goto out;
+	}
+	if (ret > 0) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+
+	eb = path->nodes[0];
+	slot = path->slots[0];
+	offset = btrfs_item_ptr_offset(eb, slot);
+	item_size = btrfs_item_size_nr(eb, slot);
+	if (!IS_ALIGNED(item_size, sizeof(u64))) {
+		warning("uuid item with illegal size %lu!",	(unsigned long)item_size);
+		ret = -ENOENT;
+		goto out;
+	}
+	while (item_size) {
+		__le64 read_subid;
+
+		read_extent_buffer(eb, &read_subid, offset, sizeof(read_subid));
+		if (le64_to_cpu(read_subid) == subid)
+			break;
+		offset += sizeof(read_subid);
+		item_size -= sizeof(read_subid);
+	}
+
+	if (!item_size) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	item_size = btrfs_item_size_nr(eb, slot);
+	if (item_size == sizeof(subid)) {
+		ret = btrfs_del_item(trans, uuid_root, path);
+		goto out;
+	}
+
+	move_dst = offset;
+	move_src = offset + sizeof(subid);
+	move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot));
+	memmove_extent_buffer(eb, move_dst, move_src, move_len);
+	btrfs_truncate_item(path, item_size - sizeof(subid), 1);
+
+out:
+	btrfs_free_path(path);
+	return ret;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/8] btrfs-progs: check/original: Implement removing received data for RW subvols
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
                   ` (4 preceding siblings ...)
  2021-09-13 13:17 ` [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 7/8] btrfs-progs: check/lowmem: Implement received info clearing for RW volumes Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 8/8] btrfs-progs: tests: Add test for received information removal Nikolay Borisov
  7 siblings, 0 replies; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

Making a received subvolume RO should preclude doing an incremental send
of said subvolume since it can't be guaranteed that nothing changed in
the structure and this in turn has correctness implications for send.

There is a pending kernel change that implements this behavior and
ensures that in the future RO volumes which are switched to RW can't be
used for incremental send. However, old kernels won't have that patch
backported. To ensure there is a supported way for users to put their
subvolumes in sane state let's implement the same functionality in
progs.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 check/main.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/check/main.c b/check/main.c
index 6369bdd90656..7a2296d00234 100644
--- a/check/main.c
+++ b/check/main.c
@@ -3544,6 +3544,7 @@ static int check_fs_root(struct btrfs_root *root,
 	int ret = 0;
 	int err = 0;
 	bool generation_err = false;
+	bool rw_received_err = false;
 	int wret;
 	int level;
 	u64 super_generation;
@@ -3658,6 +3659,46 @@ static int check_fs_root(struct btrfs_root *root,
 					sizeof(found_key)));
 	}
 
+	if (!((btrfs_root_flags(root_item) & BTRFS_ROOT_SUBVOL_RDONLY) ||
+			btrfs_is_empty_uuid(root_item->received_uuid))) {
+		error("Subvolume id: %llu is RW and has a received uuid",
+				root->root_key.objectid);
+		rw_received_err = true;
+		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);
+			rw_received_err = false;
+			printf("Cleared received information for subvol: %llu\n",
+					root->root_key.objectid);
+		}
+	}
+
 	while (1) {
 		ctx.item_count++;
 		wret = walk_down_tree(root, &path, wc, &level, &nrefs);
@@ -3722,7 +3763,7 @@ static int check_fs_root(struct btrfs_root *root,
 
 	free_corrupt_blocks_tree(&corrupt_blocks);
 	gfs_info->corrupt_blocks = NULL;
-	if (!ret && generation_err)
+	if (!ret && (generation_err ||  rw_received_err))
 		ret = -1;
 	return ret;
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/8] btrfs-progs: check/lowmem: Implement received info clearing for RW volumes
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
                   ` (5 preceding siblings ...)
  2021-09-13 13:17 ` [PATCH 6/8] btrfs-progs: check/original: Implement removing received data for RW subvols Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  2021-09-13 13:17 ` [PATCH 8/8] btrfs-progs: tests: Add test for received information removal Nikolay Borisov
  7 siblings, 0 replies; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

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 --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);
+			}
+		}
 	}
 
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 8/8] btrfs-progs: tests: Add test for received information removal
  2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
                   ` (6 preceding siblings ...)
  2021-09-13 13:17 ` [PATCH 7/8] btrfs-progs: check/lowmem: Implement received info clearing for RW volumes Nikolay Borisov
@ 2021-09-13 13:17 ` Nikolay Borisov
  7 siblings, 0 replies; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-13 13:17 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Nikolay Borisov

The image contains a subvolume which as been received i.e has relevant
received fields populated and subsequently has been switched to RW mode.


Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 .../050-subvol-recv-clear/test.raw.xz          | Bin 0 -> 493524 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 tests/fsck-tests/050-subvol-recv-clear/test.raw.xz

diff --git a/tests/fsck-tests/050-subvol-recv-clear/test.raw.xz b/tests/fsck-tests/050-subvol-recv-clear/test.raw.xz
new file mode 100644
index 0000000000000000000000000000000000000000..074a53b49cdd473af4f2a97cbf7e3f0d3c6518aa
GIT binary patch
literal 493524
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

literal 0
HcmV?d00001

--
2.17.1


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid
  2021-09-13 13:17 ` [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid Nikolay Borisov
@ 2021-09-14  0:58   ` Qu Wenruo
  0 siblings, 0 replies; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  0:58 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/13 下午9:17, Nikolay Borisov wrote:
> This utility function is needed by the RO->RW snapshot detection code.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> ---
>   kernel-shared/ctree.h     |  2 ++
>   kernel-shared/uuid-tree.c | 11 +++++++++++
>   2 files changed, 13 insertions(+)
>
> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
> index 3cca60323e3d..f53436a7f38b 100644
> --- a/kernel-shared/ctree.h
> +++ b/kernel-shared/ctree.h
> @@ -2860,6 +2860,8 @@ int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid,
>   int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
>   			u64 subvol_id_cpu);
>
> +int btrfs_is_empty_uuid(u8 *uuid);
> +
>   static inline int is_fstree(u64 rootid)
>   {
>   	if (rootid == BTRFS_FS_TREE_OBJECTID ||
> diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
> index 21115a4d2d09..51a7b5d9ff5d 100644
> --- a/kernel-shared/uuid-tree.c
> +++ b/kernel-shared/uuid-tree.c
> @@ -109,3 +109,14 @@ int btrfs_lookup_uuid_received_subvol_item(int fd, const u8 *uuid,
>   					  BTRFS_UUID_KEY_RECEIVED_SUBVOL,
>   					  subvol_id);
>   }
> +
> +int btrfs_is_empty_uuid(u8 *uuid)
> +{

I did the same work in my previous warning try, but it can be even easier:

	u8 empty_uuid[BTRFS_UUID_SIZE] = 0;

	return !memcmpy(uuid, empty_uuid, BTRFS_UUID_SIZE);

So simple that I didn't even create a helper for it...

Thanks,
Qu

> +	int i;
> +
> +	for (i = 0; i < BTRFS_UUID_SIZE; i++) {
> +		if (uuid[i])
> +			return 0;
> +	}
> +	return 1;
> +}
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys
  2021-09-13 13:17 ` [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys Nikolay Borisov
@ 2021-09-14  1:01   ` Qu Wenruo
  0 siblings, 0 replies; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  1:01 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/13 下午9:17, Nikolay Borisov wrote:
> It's not used, so just remove it.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Just one unrelated topic inlined below.

> ---
>   check/main.c          |  5 ++---
>   kernel-shared/ctree.c | 24 +++++++++++-------------
>   kernel-shared/ctree.h |  4 ++--
>   3 files changed, 15 insertions(+), 18 deletions(-)
>
> diff --git a/check/main.c b/check/main.c
> index a88518159830..6369bdd90656 100644
> --- a/check/main.c
> +++ b/check/main.c
> @@ -4197,8 +4197,7 @@ static int swap_values(struct btrfs_root *root, struct btrfs_path *path,
>   			struct btrfs_disk_key key;
>
>   			btrfs_node_key(buf, &key, 0);
> -			btrfs_fixup_low_keys(root, path, &key,
> -					     btrfs_header_level(buf) + 1);
> +			btrfs_fixup_low_keys(path, &key, btrfs_header_level(buf) + 1);
>   		}
>   	} else {
>   		struct btrfs_item *item1, *item2;
> @@ -4302,7 +4301,7 @@ static int delete_bogus_item(struct btrfs_root *root,
>   		struct btrfs_disk_key disk_key;
>
>   		btrfs_item_key(buf, &disk_key, 0);
> -		btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +		btrfs_fixup_low_keys(path, &disk_key, 1);
>   	}
>   	btrfs_mark_buffer_dirty(buf);
>   	return 0;
> diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
> index 518718de04dd..02eb975338e5 100644
> --- a/kernel-shared/ctree.c
> +++ b/kernel-shared/ctree.c
> @@ -1437,8 +1437,8 @@ int btrfs_search_slot_for_read(struct btrfs_root *root,
>    * fixing up pointers when a given leaf/node is not in slot 0 of the
>    * higher levels
>    */
> -void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
> -			  struct btrfs_disk_key *key, int level)

Isn't it recommended to use btrfs_key instead of btrfs_disk_key nowadays?

Maybe a good time to cleanup unnecessary btrfs_disk_key usage?

Thanks,
Qu

> +void btrfs_fixup_low_keys( struct btrfs_path *path, struct btrfs_disk_key *key,
> +		int level)
>   {
>   	int i;
>   	struct extent_buffer *t;
> @@ -1485,7 +1485,7 @@ int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path,
>   	btrfs_set_item_key(eb, &disk_key, slot);
>   	btrfs_mark_buffer_dirty(eb);
>   	if (slot == 0)
> -		btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +		btrfs_fixup_low_keys(path, &disk_key, 1);
>   	return 0;
>   }
>
> @@ -1508,7 +1508,7 @@ void btrfs_set_item_key_unsafe(struct btrfs_root *root,
>   	btrfs_set_item_key(eb, &disk_key, slot);
>   	btrfs_mark_buffer_dirty(eb);
>   	if (slot == 0)
> -		btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +		btrfs_fixup_low_keys(path, &disk_key, 1);
>   }
>
>   /*
> @@ -2184,7 +2184,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
>   		btrfs_mark_buffer_dirty(right);
>
>   	btrfs_item_key(right, &disk_key, 0);
> -	btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +	btrfs_fixup_low_keys(path, &disk_key, 1);
>
>   	/* then fixup the leaf pointer in the path */
>   	if (path->slots[0] < push_items) {
> @@ -2415,10 +2415,8 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
>   			free_extent_buffer(path->nodes[0]);
>   			path->nodes[0] = right;
>   			path->slots[0] = 0;
> -			if (path->slots[1] == 0) {
> -				btrfs_fixup_low_keys(root, path,
> -						     &disk_key, 1);
> -			}
> +			if (path->slots[1] == 0)
> +				btrfs_fixup_low_keys(path, &disk_key, 1);
>   		}
>   		btrfs_mark_buffer_dirty(right);
>   		return ret;
> @@ -2632,7 +2630,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
>   		btrfs_set_disk_key_offset(&disk_key, offset + size_diff);
>   		btrfs_set_item_key(leaf, &disk_key, slot);
>   		if (slot == 0)
> -			btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +			btrfs_fixup_low_keys(path, &disk_key, 1);
>   	}
>
>   	item = btrfs_item_nr(slot);
> @@ -2809,7 +2807,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
>   	ret = 0;
>   	if (slot == 0) {
>   		btrfs_cpu_key_to_disk(&disk_key, cpu_key);
> -		btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +		btrfs_fixup_low_keys(path, &disk_key, 1);
>   	}
>
>   	if (btrfs_leaf_free_space(leaf) < 0) {
> @@ -2882,7 +2880,7 @@ int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path,
>   		struct btrfs_disk_key disk_key;
>
>   		btrfs_node_key(parent, &disk_key, 0);
> -		btrfs_fixup_low_keys(root, path, &disk_key, level + 1);
> +		btrfs_fixup_low_keys(path, &disk_key, level + 1);
>   	}
>   	btrfs_mark_buffer_dirty(parent);
>   	return ret;
> @@ -2982,7 +2980,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
>   			struct btrfs_disk_key disk_key;
>
>   			btrfs_item_key(leaf, &disk_key, 0);
> -			btrfs_fixup_low_keys(root, path, &disk_key, 1);
> +			btrfs_fixup_low_keys(path, &disk_key, 1);
>   		}
>
>   		/* delete the leaf if it is mostly empty */
> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
> index f53436a7f38b..a17bf50e29b4 100644
> --- a/kernel-shared/ctree.h
> +++ b/kernel-shared/ctree.h
> @@ -2747,8 +2747,8 @@ static inline int btrfs_next_item(struct btrfs_root *root,
>
>   int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
>   int btrfs_leaf_free_space(struct extent_buffer *leaf);
> -void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
> -			  struct btrfs_disk_key *key, int level);
> +void btrfs_fixup_low_keys(struct btrfs_path *path, struct btrfs_disk_key *key,
> +		int level);
>   int btrfs_set_item_key_safe(struct btrfs_root *root, struct btrfs_path *path,
>   			    struct btrfs_key *new_key);
>   void btrfs_set_item_key_unsafe(struct btrfs_root *root,
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end
  2021-09-13 13:17 ` [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end Nikolay Borisov
@ 2021-09-14  1:02   ` Qu Wenruo
  0 siblings, 0 replies; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  1:02 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/13 下午9:17, Nikolay Borisov wrote:
> The function already takes an extent_buffer which has a reference to
> the owning filesystem's fs_info. This also brings the function in line
> with the kernel's signature.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   kernel-shared/ctree.c | 35 +++++++++++++++--------------------
>   1 file changed, 15 insertions(+), 20 deletions(-)
>
> diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
> index 02eb975338e5..77766c2a7931 100644
> --- a/kernel-shared/ctree.c
> +++ b/kernel-shared/ctree.c
> @@ -557,12 +557,11 @@ static int btrfs_comp_keys(struct btrfs_disk_key *disk,
>    * this returns the address of the start of the last item,
>    * which is the stop of the leaf data stack
>    */
> -static inline unsigned int leaf_data_end(const struct btrfs_fs_info *fs_info,
> -					 const struct extent_buffer *leaf)
> +static inline unsigned int leaf_data_end(const struct extent_buffer *leaf)
>   {
>   	u32 nr = btrfs_header_nritems(leaf);
>   	if (nr == 0)
> -		return BTRFS_LEAF_DATA_SIZE(fs_info);
> +		return BTRFS_LEAF_DATA_SIZE(leaf->fs_info);
>   	return btrfs_item_offset_nr(leaf, nr - 1);
>   }
>
> @@ -1980,10 +1979,10 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
>   	right_nritems = btrfs_header_nritems(right);
>
>   	push_space = btrfs_item_end_nr(left, left_nritems - push_items);
> -	push_space -= leaf_data_end(fs_info, left);
> +	push_space -= leaf_data_end(left);
>
>   	/* make room in the right data area */
> -	data_end = leaf_data_end(fs_info, right);
> +	data_end = leaf_data_end(right);
>   	memmove_extent_buffer(right,
>   			      btrfs_leaf_data(right) + data_end - push_space,
>   			      btrfs_leaf_data(right) + data_end,
> @@ -1992,8 +1991,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root
>   	/* copy from the left data area */
>   	copy_extent_buffer(right, left, btrfs_leaf_data(right) +
>   		     BTRFS_LEAF_DATA_SIZE(root->fs_info) - push_space,
> -		     btrfs_leaf_data(left) + leaf_data_end(fs_info, left),
> -		     push_space);
> +		     btrfs_leaf_data(left) + leaf_data_end(left), push_space);
>
>   	memmove_extent_buffer(right, btrfs_item_nr_offset(push_items),
>   			      btrfs_item_nr_offset(0),
> @@ -2130,7 +2128,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
>   		     btrfs_item_offset_nr(right, push_items -1);
>
>   	copy_extent_buffer(left, right, btrfs_leaf_data(left) +
> -		     leaf_data_end(fs_info, left) - push_space,
> +		     leaf_data_end(left) - push_space,
>   		     btrfs_leaf_data(right) +
>   		     btrfs_item_offset_nr(right, push_items - 1),
>   		     push_space);
> @@ -2157,13 +2155,12 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root
>
>   	if (push_items < right_nritems) {
>   		push_space = btrfs_item_offset_nr(right, push_items - 1) -
> -						  leaf_data_end(fs_info, right);
> +						  leaf_data_end(right);
>   		memmove_extent_buffer(right, btrfs_leaf_data(right) +
>   				      BTRFS_LEAF_DATA_SIZE(root->fs_info) -
>   				      push_space,
>   				      btrfs_leaf_data(right) +
> -				      leaf_data_end(fs_info, right),
> -				      push_space);
> +				      leaf_data_end(right), push_space);
>
>   		memmove_extent_buffer(right, btrfs_item_nr_offset(0),
>   			      btrfs_item_nr_offset(push_items),
> @@ -2222,8 +2219,7 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
>
>   	nritems = nritems - mid;
>   	btrfs_set_header_nritems(right, nritems);
> -	data_copy_size = btrfs_item_end_nr(l, mid) -
> -		leaf_data_end(root->fs_info, l);
> +	data_copy_size = btrfs_item_end_nr(l, mid) - leaf_data_end(l);
>
>   	copy_extent_buffer(right, l, btrfs_item_nr_offset(0),
>   			   btrfs_item_nr_offset(mid),
> @@ -2231,9 +2227,8 @@ static noinline int copy_for_split(struct btrfs_trans_handle *trans,
>
>   	copy_extent_buffer(right, l,
>   		     btrfs_leaf_data(right) +
> -		     BTRFS_LEAF_DATA_SIZE(root->fs_info) -
> -		     data_copy_size, btrfs_leaf_data(l) +
> -		     leaf_data_end(root->fs_info, l), data_copy_size);
> +		     BTRFS_LEAF_DATA_SIZE(root->fs_info) - data_copy_size,
> +			 btrfs_leaf_data(l) + leaf_data_end(l), data_copy_size);
>
>   	rt_data_off = BTRFS_LEAF_DATA_SIZE(root->fs_info) -
>   		      btrfs_item_end_nr(l, mid);
> @@ -2572,7 +2567,7 @@ int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
>   		return 0;
>
>   	nritems = btrfs_header_nritems(leaf);
> -	data_end = leaf_data_end(root->fs_info, leaf);
> +	data_end = leaf_data_end(leaf);
>
>   	old_data_start = btrfs_item_offset_nr(leaf, slot);
>
> @@ -2661,7 +2656,7 @@ int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
>   	leaf = path->nodes[0];
>
>   	nritems = btrfs_header_nritems(leaf);
> -	data_end = leaf_data_end(root->fs_info, leaf);
> +	data_end = leaf_data_end(leaf);
>
>   	if (btrfs_leaf_free_space(leaf) < data_size) {
>   		btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
> @@ -2747,7 +2742,7 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans,
>   	leaf = path->nodes[0];
>
>   	nritems = btrfs_header_nritems(leaf);
> -	data_end = leaf_data_end(root->fs_info, leaf);
> +	data_end = leaf_data_end(leaf);
>
>   	if (btrfs_leaf_free_space(leaf) < total_size) {
>   		btrfs_print_leaf(leaf, BTRFS_PRINT_TREE_DEFAULT);
> @@ -2940,7 +2935,7 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
>   	nritems = btrfs_header_nritems(leaf);
>
>   	if (slot + nr != nritems) {
> -		int data_end = leaf_data_end(root->fs_info, leaf);
> +		int data_end = leaf_data_end(leaf);
>
>   		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
>   			      data_end + dsize,
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item
  2021-09-13 13:17 ` [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item Nikolay Borisov
@ 2021-09-14  1:02   ` Qu Wenruo
  0 siblings, 0 replies; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  1:02 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/13 下午9:17, Nikolay Borisov wrote:
> This function lies in the kernel-shared directory and is supposed to be
> close to 1:1 copy with its kernel counterpart, yet it takes one extra
> argument - root. But this is now unused to simply remove it.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   kernel-shared/ctree.c       | 3 +--
>   kernel-shared/ctree.h       | 3 +--
>   kernel-shared/dir-item.c    | 2 +-
>   kernel-shared/extent-tree.c | 2 +-
>   kernel-shared/file-item.c   | 4 ++--
>   kernel-shared/inode-item.c  | 4 ++--
>   6 files changed, 8 insertions(+), 10 deletions(-)
>
> diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
> index 77766c2a7931..78f94c6cd42f 100644
> --- a/kernel-shared/ctree.c
> +++ b/kernel-shared/ctree.c
> @@ -2545,8 +2545,7 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
>   	return ret;
>   }
>
> -int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
> -			u32 new_size, int from_end)
> +int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end)
>   {
>   	int ret = 0;
>   	int slot;
> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
> index a17bf50e29b4..91a85796a678 100644
> --- a/kernel-shared/ctree.h
> +++ b/kernel-shared/ctree.h
> @@ -2670,8 +2670,7 @@ int btrfs_create_root(struct btrfs_trans_handle *trans,
>   		      struct btrfs_fs_info *fs_info, u64 objectid);
>   int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
>   		u32 data_size);
> -int btrfs_truncate_item(struct btrfs_root *root, struct btrfs_path *path,
> -			u32 new_size, int from_end);
> +int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end);
>   int btrfs_split_item(struct btrfs_trans_handle *trans,
>   		     struct btrfs_root *root,
>   		     struct btrfs_path *path,
> diff --git a/kernel-shared/dir-item.c b/kernel-shared/dir-item.c
> index 7dc606c132b5..590b79a929d3 100644
> --- a/kernel-shared/dir-item.c
> +++ b/kernel-shared/dir-item.c
> @@ -284,7 +284,7 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
>   		start = btrfs_item_ptr_offset(leaf, path->slots[0]);
>   		memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
>   			item_len - (ptr + sub_item_len - start));
> -		btrfs_truncate_item(root, path, item_len - sub_item_len, 1);
> +		btrfs_truncate_item(path, item_len - sub_item_len, 1);
>   	}
>   	return ret;
>   }
> diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c
> index 056a9256b9a4..a8e0c1e60e2e 100644
> --- a/kernel-shared/extent-tree.c
> +++ b/kernel-shared/extent-tree.c
> @@ -1166,7 +1166,7 @@ static int update_inline_extent_backref(struct btrfs_trans_handle *trans,
>   			memmove_extent_buffer(leaf, ptr, ptr + size,
>   					      end - ptr - size);
>   		item_size -= size;
> -		ret = btrfs_truncate_item(root, path, item_size, 1);
> +		ret = btrfs_truncate_item(path, item_size, 1);
>   		BUG_ON(ret);
>   	}
>   	btrfs_mark_buffer_dirty(leaf);
> diff --git a/kernel-shared/file-item.c b/kernel-shared/file-item.c
> index 7e16b747e36c..c910e27e5a5d 100644
> --- a/kernel-shared/file-item.c
> +++ b/kernel-shared/file-item.c
> @@ -362,7 +362,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root,
>   		 */
>   		u32 new_size = (bytenr - key->offset) / blocksize;
>   		new_size *= csum_size;
> -		ret = btrfs_truncate_item(root, path, new_size, 1);
> +		ret = btrfs_truncate_item(path, new_size, 1);
>   		BUG_ON(ret);
>   	} else if (key->offset >= bytenr && csum_end > end_byte &&
>   		   end_byte > key->offset) {
> @@ -375,7 +375,7 @@ static noinline int truncate_one_csum(struct btrfs_root *root,
>   		u32 new_size = (csum_end - end_byte) / blocksize;
>   		new_size *= csum_size;
>
> -		ret = btrfs_truncate_item(root, path, new_size, 0);
> +		ret = btrfs_truncate_item(path, new_size, 0);
>   		BUG_ON(ret);
>
>   		key->offset = end_byte;
> diff --git a/kernel-shared/inode-item.c b/kernel-shared/inode-item.c
> index 4e009746de0e..67173eb141d8 100644
> --- a/kernel-shared/inode-item.c
> +++ b/kernel-shared/inode-item.c
> @@ -311,7 +311,7 @@ int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
>   	memmove_extent_buffer(leaf, ptr, ptr + del_len,
>   			      item_size - (ptr + del_len - item_start));
>
> -	btrfs_truncate_item(root, path, item_size - del_len, 1);
> +	btrfs_truncate_item(path, item_size - del_len, 1);
>
>   out:
>   	btrfs_free_path(path);
> @@ -432,7 +432,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
>   	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
>   	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
>   			      item_size - (ptr + sub_item_len - item_start));
> -	btrfs_truncate_item(root, path, item_size - sub_item_len, 1);
> +	btrfs_truncate_item(path, item_size - sub_item_len, 1);
>   	btrfs_mark_buffer_dirty(path->nodes[0]);
>   out:
>   	btrfs_free_path(path);
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove
  2021-09-13 13:17 ` [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove Nikolay Borisov
@ 2021-09-14  1:07   ` Qu Wenruo
  2021-09-14  4:49     ` Nikolay Borisov
  0 siblings, 1 reply; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  1:07 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/13 下午9:17, Nikolay Borisov wrote:
> It will be used to clear received data on RW snapshots that were
> received.
>
> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
> ---
>   kernel-shared/ctree.h     |  3 ++
>   kernel-shared/uuid-tree.c | 82 +++++++++++++++++++++++++++++++++++++++
>   2 files changed, 85 insertions(+)
>
> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
> index 91a85796a678..158281a9fd67 100644
> --- a/kernel-shared/ctree.h
> +++ b/kernel-shared/ctree.h
> @@ -2860,6 +2860,9 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
>   			u64 subvol_id_cpu);
>
>   int btrfs_is_empty_uuid(u8 *uuid);
> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
> +               u64 subid);
> +

I have checked the callers in the incoming check patches, they are all
starting a new trans on uuid tree, thus there is no need to start a
trans out of this function.

Let's just pass the subvolume root into the function, and start a new
trans in side the function.

So that we only need one parameter @root, everything else can be fetched
from @root, and we can also modify the root item and uuid tree just in
one go.

Thanks,
Qu
>
>   static inline int is_fstree(u64 rootid)
>   {
> diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
> index 51a7b5d9ff5d..0f0fbf667dda 100644
> --- a/kernel-shared/uuid-tree.c
> +++ b/kernel-shared/uuid-tree.c
> @@ -120,3 +120,85 @@ int btrfs_is_empty_uuid(u8 *uuid)
>   	}
>   	return 1;
>   }
> +
> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8 *uuid, u8 type,
> +		u64 subid)
> +{
> +	struct btrfs_fs_info *fs_info = trans->fs_info;
> +	struct btrfs_root *uuid_root = fs_info->uuid_root;
> +	int ret;
> +	struct btrfs_path *path = NULL;
> +	struct btrfs_key key;
> +	struct extent_buffer *eb;
> +	int slot;
> +	unsigned long offset;
> +	u32 item_size;
> +	unsigned long move_dst;
> +	unsigned long move_src;
> +	unsigned long move_len;
> +
> +	if (!uuid_root) {
> +		ret = -EINVAL;
> +		goto out;
> +	}
> +
> +	btrfs_uuid_to_key(uuid, &key);
> +	key.type = type;
> +
> +	path = btrfs_alloc_path();
> +	if (!path) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	ret = btrfs_search_slot(trans, uuid_root, &key, path, -1, 1);
> +	if (ret < 0) {
> +		warning("error %d while searching for uuid item!", ret);
> +		goto out;
> +	}
> +	if (ret > 0) {
> +		ret = -ENOENT;
> +		goto out;
> +	}
> +
> +
> +	eb = path->nodes[0];
> +	slot = path->slots[0];
> +	offset = btrfs_item_ptr_offset(eb, slot);
> +	item_size = btrfs_item_size_nr(eb, slot);
> +	if (!IS_ALIGNED(item_size, sizeof(u64))) {
> +		warning("uuid item with illegal size %lu!",	(unsigned long)item_size);
> +		ret = -ENOENT;
> +		goto out;
> +	}
> +	while (item_size) {
> +		__le64 read_subid;
> +
> +		read_extent_buffer(eb, &read_subid, offset, sizeof(read_subid));
> +		if (le64_to_cpu(read_subid) == subid)
> +			break;
> +		offset += sizeof(read_subid);
> +		item_size -= sizeof(read_subid);
> +	}
> +
> +	if (!item_size) {
> +		ret = -ENOENT;
> +		goto out;
> +	}
> +
> +	item_size = btrfs_item_size_nr(eb, slot);
> +	if (item_size == sizeof(subid)) {
> +		ret = btrfs_del_item(trans, uuid_root, path);
> +		goto out;
> +	}
> +
> +	move_dst = offset;
> +	move_src = offset + sizeof(subid);
> +	move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot));
> +	memmove_extent_buffer(eb, move_dst, move_src, move_len);
> +	btrfs_truncate_item(path, item_size - sizeof(subid), 1);
> +
> +out:
> +	btrfs_free_path(path);
> +	return ret;
> +}
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove
  2021-09-14  1:07   ` Qu Wenruo
@ 2021-09-14  4:49     ` Nikolay Borisov
  2021-09-14  4:57       ` Qu Wenruo
  0 siblings, 1 reply; 16+ messages in thread
From: Nikolay Borisov @ 2021-09-14  4:49 UTC (permalink / raw)
  To: Qu Wenruo, linux-btrfs



On 14.09.21 г. 4:07, Qu Wenruo wrote:
> 
> 
> On 2021/9/13 下午9:17, Nikolay Borisov wrote:
>> It will be used to clear received data on RW snapshots that were
>> received.
>>
>> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
>> ---
>>   kernel-shared/ctree.h     |  3 ++
>>   kernel-shared/uuid-tree.c | 82 +++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 85 insertions(+)
>>
>> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
>> index 91a85796a678..158281a9fd67 100644
>> --- a/kernel-shared/ctree.h
>> +++ b/kernel-shared/ctree.h
>> @@ -2860,6 +2860,9 @@ int btrfs_uuid_tree_add(struct
>> btrfs_trans_handle *trans, u8 *uuid, u8 type,
>>               u64 subvol_id_cpu);
>>
>>   int btrfs_is_empty_uuid(u8 *uuid);
>> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8
>> *uuid, u8 type,
>> +               u64 subid);
>> +
> 
> I have checked the callers in the incoming check patches, they are all
> starting a new trans on uuid tree, thus there is no need to start a
> trans out of this function.
> 
> Let's just pass the subvolume root into the function, and start a new
> trans in side the function.
> 
> So that we only need one parameter @root, everything else can be fetched
> from @root, and we can also modify the root item and uuid tree just in
> one go.

I disagree, this function is a direct copy from the kernel with the only
adjustment that btrfs_uuid_to_key doesn't set key.type. If I change it
in progs then this means it won't be unified with the kernel when this
happens (if ever). I really rather keep shared functions as close as
possible.

> 
> Thanks,
> Qu
>>
>>   static inline int is_fstree(u64 rootid)
>>   {
>> diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
>> index 51a7b5d9ff5d..0f0fbf667dda 100644
>> --- a/kernel-shared/uuid-tree.c
>> +++ b/kernel-shared/uuid-tree.c
>> @@ -120,3 +120,85 @@ int btrfs_is_empty_uuid(u8 *uuid)
>>       }
>>       return 1;
>>   }
>> +
>> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8
>> *uuid, u8 type,
>> +        u64 subid)
>> +{
>> +    struct btrfs_fs_info *fs_info = trans->fs_info;
>> +    struct btrfs_root *uuid_root = fs_info->uuid_root;
>> +    int ret;
>> +    struct btrfs_path *path = NULL;
>> +    struct btrfs_key key;
>> +    struct extent_buffer *eb;
>> +    int slot;
>> +    unsigned long offset;
>> +    u32 item_size;
>> +    unsigned long move_dst;
>> +    unsigned long move_src;
>> +    unsigned long move_len;
>> +
>> +    if (!uuid_root) {
>> +        ret = -EINVAL;
>> +        goto out;
>> +    }
>> +
>> +    btrfs_uuid_to_key(uuid, &key);
>> +    key.type = type;
>> +
>> +    path = btrfs_alloc_path();
>> +    if (!path) {
>> +        ret = -ENOMEM;
>> +        goto out;
>> +    }
>> +
>> +    ret = btrfs_search_slot(trans, uuid_root, &key, path, -1, 1);
>> +    if (ret < 0) {
>> +        warning("error %d while searching for uuid item!", ret);
>> +        goto out;
>> +    }
>> +    if (ret > 0) {
>> +        ret = -ENOENT;
>> +        goto out;
>> +    }
>> +
>> +
>> +    eb = path->nodes[0];
>> +    slot = path->slots[0];
>> +    offset = btrfs_item_ptr_offset(eb, slot);
>> +    item_size = btrfs_item_size_nr(eb, slot);
>> +    if (!IS_ALIGNED(item_size, sizeof(u64))) {
>> +        warning("uuid item with illegal size %lu!",    (unsigned
>> long)item_size);
>> +        ret = -ENOENT;
>> +        goto out;
>> +    }
>> +    while (item_size) {
>> +        __le64 read_subid;
>> +
>> +        read_extent_buffer(eb, &read_subid, offset, sizeof(read_subid));
>> +        if (le64_to_cpu(read_subid) == subid)
>> +            break;
>> +        offset += sizeof(read_subid);
>> +        item_size -= sizeof(read_subid);
>> +    }
>> +
>> +    if (!item_size) {
>> +        ret = -ENOENT;
>> +        goto out;
>> +    }
>> +
>> +    item_size = btrfs_item_size_nr(eb, slot);
>> +    if (item_size == sizeof(subid)) {
>> +        ret = btrfs_del_item(trans, uuid_root, path);
>> +        goto out;
>> +    }
>> +
>> +    move_dst = offset;
>> +    move_src = offset + sizeof(subid);
>> +    move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot));
>> +    memmove_extent_buffer(eb, move_dst, move_src, move_len);
>> +    btrfs_truncate_item(path, item_size - sizeof(subid), 1);
>> +
>> +out:
>> +    btrfs_free_path(path);
>> +    return ret;
>> +}
>>
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove
  2021-09-14  4:49     ` Nikolay Borisov
@ 2021-09-14  4:57       ` Qu Wenruo
  0 siblings, 0 replies; 16+ messages in thread
From: Qu Wenruo @ 2021-09-14  4:57 UTC (permalink / raw)
  To: Nikolay Borisov, linux-btrfs



On 2021/9/14 下午12:49, Nikolay Borisov wrote:
>
>
> On 14.09.21 г. 4:07, Qu Wenruo wrote:
>>
>>
>> On 2021/9/13 下午9:17, Nikolay Borisov wrote:
>>> It will be used to clear received data on RW snapshots that were
>>> received.
>>>
>>> Signed-off-by: Nikolay Borisov <nborisov@suse.com>
>>> ---
>>>    kernel-shared/ctree.h     |  3 ++
>>>    kernel-shared/uuid-tree.c | 82 +++++++++++++++++++++++++++++++++++++++
>>>    2 files changed, 85 insertions(+)
>>>
>>> diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
>>> index 91a85796a678..158281a9fd67 100644
>>> --- a/kernel-shared/ctree.h
>>> +++ b/kernel-shared/ctree.h
>>> @@ -2860,6 +2860,9 @@ int btrfs_uuid_tree_add(struct
>>> btrfs_trans_handle *trans, u8 *uuid, u8 type,
>>>                u64 subvol_id_cpu);
>>>
>>>    int btrfs_is_empty_uuid(u8 *uuid);
>>> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8
>>> *uuid, u8 type,
>>> +               u64 subid);
>>> +
>>
>> I have checked the callers in the incoming check patches, they are all
>> starting a new trans on uuid tree, thus there is no need to start a
>> trans out of this function.
>>
>> Let's just pass the subvolume root into the function, and start a new
>> trans in side the function.
>>
>> So that we only need one parameter @root, everything else can be fetched
>> from @root, and we can also modify the root item and uuid tree just in
>> one go.
>
> I disagree, this function is a direct copy from the kernel with the only
> adjustment that btrfs_uuid_to_key doesn't set key.type. If I change it
> in progs then this means it won't be unified with the kernel when this
> happens (if ever). I really rather keep shared functions as close as
> possible.

OK, didn't notice it's really some shared function. (in kernel it's
implemented in uuid-tree.c, not ctree.c).

Then maybe it's better to introduce a btrfs-progs specific helper like
btrfs_remove_recevied_uuid(), other than calling the function directly.

In fact, both mode shares the same root item modification code, which is
really a duplication.

As in btrfs-progs we don't need the other call sites in kernels which is
shared for subvolume removal.

Thanks,
Qu
>
>>
>> Thanks,
>> Qu
>>>
>>>    static inline int is_fstree(u64 rootid)
>>>    {
>>> diff --git a/kernel-shared/uuid-tree.c b/kernel-shared/uuid-tree.c
>>> index 51a7b5d9ff5d..0f0fbf667dda 100644
>>> --- a/kernel-shared/uuid-tree.c
>>> +++ b/kernel-shared/uuid-tree.c
>>> @@ -120,3 +120,85 @@ int btrfs_is_empty_uuid(u8 *uuid)
>>>        }
>>>        return 1;
>>>    }
>>> +
>>> +int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, u8
>>> *uuid, u8 type,
>>> +        u64 subid)
>>> +{
>>> +    struct btrfs_fs_info *fs_info = trans->fs_info;
>>> +    struct btrfs_root *uuid_root = fs_info->uuid_root;
>>> +    int ret;
>>> +    struct btrfs_path *path = NULL;
>>> +    struct btrfs_key key;
>>> +    struct extent_buffer *eb;
>>> +    int slot;
>>> +    unsigned long offset;
>>> +    u32 item_size;
>>> +    unsigned long move_dst;
>>> +    unsigned long move_src;
>>> +    unsigned long move_len;
>>> +
>>> +    if (!uuid_root) {
>>> +        ret = -EINVAL;
>>> +        goto out;
>>> +    }
>>> +
>>> +    btrfs_uuid_to_key(uuid, &key);
>>> +    key.type = type;
>>> +
>>> +    path = btrfs_alloc_path();
>>> +    if (!path) {
>>> +        ret = -ENOMEM;
>>> +        goto out;
>>> +    }
>>> +
>>> +    ret = btrfs_search_slot(trans, uuid_root, &key, path, -1, 1);
>>> +    if (ret < 0) {
>>> +        warning("error %d while searching for uuid item!", ret);
>>> +        goto out;
>>> +    }
>>> +    if (ret > 0) {
>>> +        ret = -ENOENT;
>>> +        goto out;
>>> +    }
>>> +
>>> +
>>> +    eb = path->nodes[0];
>>> +    slot = path->slots[0];
>>> +    offset = btrfs_item_ptr_offset(eb, slot);
>>> +    item_size = btrfs_item_size_nr(eb, slot);
>>> +    if (!IS_ALIGNED(item_size, sizeof(u64))) {
>>> +        warning("uuid item with illegal size %lu!",    (unsigned
>>> long)item_size);
>>> +        ret = -ENOENT;
>>> +        goto out;
>>> +    }
>>> +    while (item_size) {
>>> +        __le64 read_subid;
>>> +
>>> +        read_extent_buffer(eb, &read_subid, offset, sizeof(read_subid));
>>> +        if (le64_to_cpu(read_subid) == subid)
>>> +            break;
>>> +        offset += sizeof(read_subid);
>>> +        item_size -= sizeof(read_subid);
>>> +    }
>>> +
>>> +    if (!item_size) {
>>> +        ret = -ENOENT;
>>> +        goto out;
>>> +    }
>>> +
>>> +    item_size = btrfs_item_size_nr(eb, slot);
>>> +    if (item_size == sizeof(subid)) {
>>> +        ret = btrfs_del_item(trans, uuid_root, path);
>>> +        goto out;
>>> +    }
>>> +
>>> +    move_dst = offset;
>>> +    move_src = offset + sizeof(subid);
>>> +    move_len = item_size - (move_src - btrfs_item_ptr_offset(eb, slot));
>>> +    memmove_extent_buffer(eb, move_dst, move_src, move_len);
>>> +    btrfs_truncate_item(path, item_size - sizeof(subid), 1);
>>> +
>>> +out:
>>> +    btrfs_free_path(path);
>>> +    return ret;
>>> +}
>>>
>>

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-09-14  4:57 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-13 13:17 [PATCH 0/8] Implement progs support for removing received uuid on RW vols Nikolay Borisov
2021-09-13 13:17 ` [PATCH 1/8] btrfs-progs: Add btrfs_is_empty_uuid Nikolay Borisov
2021-09-14  0:58   ` Qu Wenruo
2021-09-13 13:17 ` [PATCH 2/8] btrfs-progs: Remove root argument from btrfs_fixup_low_keys Nikolay Borisov
2021-09-14  1:01   ` Qu Wenruo
2021-09-13 13:17 ` [PATCH 3/8] btrfs-progs: Remove fs_info argument from leaf_data_end Nikolay Borisov
2021-09-14  1:02   ` Qu Wenruo
2021-09-13 13:17 ` [PATCH 4/8] btrfs-progs: Remove root argument from btrfs_truncate_item Nikolay Borisov
2021-09-14  1:02   ` Qu Wenruo
2021-09-13 13:17 ` [PATCH 5/8] btrfs-progs: Add btrfs_uuid_tree_remove Nikolay Borisov
2021-09-14  1:07   ` Qu Wenruo
2021-09-14  4:49     ` Nikolay Borisov
2021-09-14  4:57       ` Qu Wenruo
2021-09-13 13:17 ` [PATCH 6/8] btrfs-progs: check/original: Implement removing received data for RW subvols Nikolay Borisov
2021-09-13 13:17 ` [PATCH 7/8] btrfs-progs: check/lowmem: Implement received info clearing for RW volumes Nikolay Borisov
2021-09-13 13:17 ` [PATCH 8/8] btrfs-progs: tests: Add test for received information removal Nikolay Borisov

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.