* [PATCH 0/2] btrfs-progs: check: add repair ability for missing root orphan item
@ 2025-11-14 21:45 Qu Wenruo
2025-11-14 21:45 ` [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item Qu Wenruo
2025-11-14 21:46 ` [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable Qu Wenruo
0 siblings, 2 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-14 21:45 UTC (permalink / raw)
To: linux-btrfs
There is another report of missing root orphan item, although the latest
btrfs-progs can detect such corruption, we have no way to fix it.
This makes the affected end users helpless, as the corruption can happen
for affected old kernels, and that damage is persistent.
Add the repair ability to save those affected end users.
Qu Wenruo (2):
btrfs-progs: check: add repair ability for missing orphan root item
btrfs-progs: fsck-tests: make test case 066 to be repairable
check/main.c | 5 +++
check/mode-common.c | 33 +++++++++++++++++++
check/mode-common.h | 1 +
check/mode-lowmem.c | 13 ++++++--
.../.lowmem_repairable | 0
.../066-missing-root-orphan-item/test.sh | 14 --------
6 files changed, 49 insertions(+), 17 deletions(-)
create mode 100644 tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable
delete mode 100755 tests/fsck-tests/066-missing-root-orphan-item/test.sh
--
2.51.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item
2025-11-14 21:45 [PATCH 0/2] btrfs-progs: check: add repair ability for missing root orphan item Qu Wenruo
@ 2025-11-14 21:45 ` Qu Wenruo
2025-11-19 23:02 ` Boris Burkov
2025-11-14 21:46 ` [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable Qu Wenruo
1 sibling, 1 reply; 6+ messages in thread
From: Qu Wenruo @ 2025-11-14 21:45 UTC (permalink / raw)
To: linux-btrfs
There is a known bug in older kernels that orphan items can be missing
for dropped subvolumes.
This makes those subvolumes unable to be removed on the next mount, and
recent kernel commit 4289b494ac55 ("btrfs: do not allow relocation of
partially dropped subvolumes") introduced one extra safe net to catch
such problem.
But unfortunately there is no way to repair it.
Add the repair ability to both the original and lowmem modes.
Link: https://lore.kernel.org/linux-btrfs/01f8b560-fb57-4861-8382-141c39655478@gmx.com/
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
check/main.c | 5 +++++
check/mode-common.c | 33 +++++++++++++++++++++++++++++++++
check/mode-common.h | 1 +
check/mode-lowmem.c | 13 ++++++++++---
4 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/check/main.c b/check/main.c
index 77458a769028..db055ae194f8 100644
--- a/check/main.c
+++ b/check/main.c
@@ -3550,6 +3550,11 @@ static int check_root_refs(struct btrfs_root *root,
*/
if (!rec->found_root_item)
continue;
+ if (opt_check_repair) {
+ ret = repair_subvol_orphan_item(gfs_info, rec->objectid);
+ if (!ret)
+ continue;
+ }
errors++;
fprintf(stderr, "fs tree %llu missing orphan item\n", rec->objectid);
}
diff --git a/check/mode-common.c b/check/mode-common.c
index 0467ba28395e..2d11a96dfb7e 100644
--- a/check/mode-common.c
+++ b/check/mode-common.c
@@ -1672,3 +1672,36 @@ int check_and_repair_super_num_devs(struct btrfs_fs_info *fs_info)
printf("Successfully reset super num devices to %u\n", found_devs);
return 0;
}
+
+int repair_subvol_orphan_item(struct btrfs_fs_info *fs_info, u64 rootid)
+{
+ struct btrfs_root *tree_root = fs_info->tree_root;
+ struct btrfs_trans_handle *trans;
+ struct btrfs_path path = { 0 };
+ int ret;
+
+ trans = btrfs_start_transaction(tree_root, 1);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ errno = -ret;
+ error_msg(ERROR_MSG_START_TRANS, "%m");
+ return ret;
+ }
+ ret = btrfs_add_orphan_item(trans, tree_root, &path, rootid);
+ btrfs_release_path(&path);
+ if (ret < 0) {
+ errno = -ret;
+ error("failed to insert orphan item for subvolume %llu: %m", rootid);
+ btrfs_abort_transaction(trans, ret);
+ btrfs_commit_transaction(trans, tree_root);
+ return ret;
+ }
+ ret = btrfs_commit_transaction(trans, tree_root);
+ if (ret < 0) {
+ errno = -ret;
+ error_msg(ERROR_MSG_COMMIT_TRANS, "%m");
+ return ret;
+ }
+ printf("Added back missing orphan item for subvolume %llu\n", rootid);
+ return 0;
+}
diff --git a/check/mode-common.h b/check/mode-common.h
index c37b4dc00e54..e97835a5b6a3 100644
--- a/check/mode-common.h
+++ b/check/mode-common.h
@@ -197,5 +197,6 @@ int repair_dev_item_bytes_used(struct btrfs_fs_info *fs_info,
int fill_csum_tree(struct btrfs_trans_handle *trans, bool search_fs_tree);
int check_and_repair_super_num_devs(struct btrfs_fs_info *fs_info);
+int repair_subvol_orphan_item(struct btrfs_fs_info *fs_info, u64 rootid);
#endif
diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index 363dc4ae1904..ea4d4017827f 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -5569,9 +5569,16 @@ static int check_btrfs_root(struct btrfs_root *root, int check_all)
* If this tree is a subvolume (not a reloc tree) and has no refs, there
* should be an orphan item for it, or this subvolume will never be deleted.
*/
- if (btrfs_root_refs(root_item) == 0 && is_fstree(btrfs_root_id(root))) {
- if (!has_orphan_item(root->fs_info->tree_root,
- btrfs_root_id(root))) {
+ if (btrfs_root_refs(root_item) == 0 && is_fstree(btrfs_root_id(root)) &&
+ !has_orphan_item(root->fs_info->tree_root, btrfs_root_id(root))) {
+ bool repaired = false;
+
+ if (opt_check_repair) {
+ ret = repair_subvol_orphan_item(root->fs_info, btrfs_root_id(root));
+ if (!ret)
+ repaired = true;
+ }
+ if (!repaired) {
error("missing orphan item for root %lld", btrfs_root_id(root));
err |= REFERENCER_MISSING;
}
--
2.51.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable
2025-11-14 21:45 [PATCH 0/2] btrfs-progs: check: add repair ability for missing root orphan item Qu Wenruo
2025-11-14 21:45 ` [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item Qu Wenruo
@ 2025-11-14 21:46 ` Qu Wenruo
[not found] ` <314461b6-9c30-4f19-aed3-486656db661e@libero.it>
2025-11-19 23:03 ` Boris Burkov
1 sibling, 2 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-14 21:46 UTC (permalink / raw)
To: linux-btrfs
The test case fsck/066 is only to verify we can detect the missing root
orphan item, no repair for it yet.
Now the repair ability is added, change the test case to verify the
repair is also properly done.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
.../.lowmem_repairable | 0
.../066-missing-root-orphan-item/test.sh | 14 --------------
2 files changed, 14 deletions(-)
create mode 100644 tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable
delete mode 100755 tests/fsck-tests/066-missing-root-orphan-item/test.sh
diff --git a/tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable b/tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/tests/fsck-tests/066-missing-root-orphan-item/test.sh b/tests/fsck-tests/066-missing-root-orphan-item/test.sh
deleted file mode 100755
index 9db625714c1f..000000000000
--- a/tests/fsck-tests/066-missing-root-orphan-item/test.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-#
-# Verify that check can report missing orphan root itemm as an error
-
-source "$TEST_TOP/common" || exit
-
-check_prereq btrfs
-
-check_image() {
- run_mustfail "missing root orphan item not reported as an error" \
- "$TOP/btrfs" check "$1"
-}
-
-check_all_images
--
2.51.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable
[not found] ` <314461b6-9c30-4f19-aed3-486656db661e@libero.it>
@ 2025-11-15 10:45 ` Qu Wenruo
0 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-11-15 10:45 UTC (permalink / raw)
To: kreijack, linux-btrfs
在 2025/11/15 20:17, Goffredo Baroncelli 写道:
> On 14/11/2025 22.46, Qu Wenruo wrote:
>> The test case fsck/066 is only to verify we can detect the missing root
>> orphan item, no repair for it yet.
>>
>> Now the repair ability is added, change the test case to verify the
>> repair is also properly done.
>
>
> It seems more that this patch only can removed a test...
>
> May be something was wrong ?
Nope, it's completely correct.
Check run_one_test() from tests/fsck-tests.sh.
There are tons of examples inside tests/fsck-tests/ where there are only
test images without test.sh.
Test.sh are all utilized to override the existing check_image() which is
not the full default check-repair-check run.
Thanks,
Qu
>
>
>>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>> .../.lowmem_repairable | 0
>> .../066-missing-root-orphan-item/test.sh | 14 --------------
>> 2 files changed, 14 deletions(-)
>> create mode 100644 tests/fsck-tests/066-missing-root-orphan-
>> item/.lowmem_repairable
>> delete mode 100755 tests/fsck-tests/066-missing-root-orphan-item/
>> test.sh
>>
>> diff --git a/tests/fsck-tests/066-missing-root-orphan-
>> item/.lowmem_repairable b/tests/fsck-tests/066-missing-root-orphan-
>> item/.lowmem_repairable
>> new file mode 100644
>> index 000000000000..e69de29bb2d1
>> diff --git a/tests/fsck-tests/066-missing-root-orphan-item/test.sh b/
>> tests/fsck-tests/066-missing-root-orphan-item/test.sh
>> deleted file mode 100755
>> index 9db625714c1f..000000000000
>> --- a/tests/fsck-tests/066-missing-root-orphan-item/test.sh
>> +++ /dev/null
>> @@ -1,14 +0,0 @@
>> -#!/bin/bash
>> -#
>> -# Verify that check can report missing orphan root itemm as an error
>> -
>> -source "$TEST_TOP/common" || exit
>> -
>> -check_prereq btrfs
>> -
>> -check_image() {
>> - run_mustfail "missing root orphan item not reported as an error" \
>> - "$TOP/btrfs" check "$1"
>> -}
>> -
>> -check_all_images
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item
2025-11-14 21:45 ` [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item Qu Wenruo
@ 2025-11-19 23:02 ` Boris Burkov
0 siblings, 0 replies; 6+ messages in thread
From: Boris Burkov @ 2025-11-19 23:02 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Sat, Nov 15, 2025 at 08:15:59AM +1030, Qu Wenruo wrote:
> There is a known bug in older kernels that orphan items can be missing
> for dropped subvolumes.
>
> This makes those subvolumes unable to be removed on the next mount, and
> recent kernel commit 4289b494ac55 ("btrfs: do not allow relocation of
> partially dropped subvolumes") introduced one extra safe net to catch
> such problem.
>
> But unfortunately there is no way to repair it.
>
> Add the repair ability to both the original and lowmem modes.
>
> Link: https://lore.kernel.org/linux-btrfs/01f8b560-fb57-4861-8382-141c39655478@gmx.com/
> Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Boris Burkov <boris@bur.io>
> ---
> check/main.c | 5 +++++
> check/mode-common.c | 33 +++++++++++++++++++++++++++++++++
> check/mode-common.h | 1 +
> check/mode-lowmem.c | 13 ++++++++++---
> 4 files changed, 49 insertions(+), 3 deletions(-)
>
> diff --git a/check/main.c b/check/main.c
> index 77458a769028..db055ae194f8 100644
> --- a/check/main.c
> +++ b/check/main.c
> @@ -3550,6 +3550,11 @@ static int check_root_refs(struct btrfs_root *root,
> */
> if (!rec->found_root_item)
> continue;
> + if (opt_check_repair) {
> + ret = repair_subvol_orphan_item(gfs_info, rec->objectid);
> + if (!ret)
> + continue;
> + }
> errors++;
> fprintf(stderr, "fs tree %llu missing orphan item\n", rec->objectid);
> }
> diff --git a/check/mode-common.c b/check/mode-common.c
> index 0467ba28395e..2d11a96dfb7e 100644
> --- a/check/mode-common.c
> +++ b/check/mode-common.c
> @@ -1672,3 +1672,36 @@ int check_and_repair_super_num_devs(struct btrfs_fs_info *fs_info)
> printf("Successfully reset super num devices to %u\n", found_devs);
> return 0;
> }
> +
> +int repair_subvol_orphan_item(struct btrfs_fs_info *fs_info, u64 rootid)
> +{
> + struct btrfs_root *tree_root = fs_info->tree_root;
> + struct btrfs_trans_handle *trans;
> + struct btrfs_path path = { 0 };
> + int ret;
> +
> + trans = btrfs_start_transaction(tree_root, 1);
> + if (IS_ERR(trans)) {
> + ret = PTR_ERR(trans);
> + errno = -ret;
> + error_msg(ERROR_MSG_START_TRANS, "%m");
> + return ret;
> + }
> + ret = btrfs_add_orphan_item(trans, tree_root, &path, rootid);
> + btrfs_release_path(&path);
> + if (ret < 0) {
> + errno = -ret;
> + error("failed to insert orphan item for subvolume %llu: %m", rootid);
> + btrfs_abort_transaction(trans, ret);
> + btrfs_commit_transaction(trans, tree_root);
> + return ret;
> + }
> + ret = btrfs_commit_transaction(trans, tree_root);
> + if (ret < 0) {
> + errno = -ret;
> + error_msg(ERROR_MSG_COMMIT_TRANS, "%m");
> + return ret;
> + }
> + printf("Added back missing orphan item for subvolume %llu\n", rootid);
> + return 0;
> +}
> diff --git a/check/mode-common.h b/check/mode-common.h
> index c37b4dc00e54..e97835a5b6a3 100644
> --- a/check/mode-common.h
> +++ b/check/mode-common.h
> @@ -197,5 +197,6 @@ int repair_dev_item_bytes_used(struct btrfs_fs_info *fs_info,
> int fill_csum_tree(struct btrfs_trans_handle *trans, bool search_fs_tree);
>
> int check_and_repair_super_num_devs(struct btrfs_fs_info *fs_info);
> +int repair_subvol_orphan_item(struct btrfs_fs_info *fs_info, u64 rootid);
>
> #endif
> diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
> index 363dc4ae1904..ea4d4017827f 100644
> --- a/check/mode-lowmem.c
> +++ b/check/mode-lowmem.c
> @@ -5569,9 +5569,16 @@ static int check_btrfs_root(struct btrfs_root *root, int check_all)
> * If this tree is a subvolume (not a reloc tree) and has no refs, there
> * should be an orphan item for it, or this subvolume will never be deleted.
> */
> - if (btrfs_root_refs(root_item) == 0 && is_fstree(btrfs_root_id(root))) {
> - if (!has_orphan_item(root->fs_info->tree_root,
> - btrfs_root_id(root))) {
> + if (btrfs_root_refs(root_item) == 0 && is_fstree(btrfs_root_id(root)) &&
> + !has_orphan_item(root->fs_info->tree_root, btrfs_root_id(root))) {
> + bool repaired = false;
> +
> + if (opt_check_repair) {
> + ret = repair_subvol_orphan_item(root->fs_info, btrfs_root_id(root));
> + if (!ret)
> + repaired = true;
> + }
> + if (!repaired) {
> error("missing orphan item for root %lld", btrfs_root_id(root));
> err |= REFERENCER_MISSING;
> }
> --
> 2.51.2
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable
2025-11-14 21:46 ` [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable Qu Wenruo
[not found] ` <314461b6-9c30-4f19-aed3-486656db661e@libero.it>
@ 2025-11-19 23:03 ` Boris Burkov
1 sibling, 0 replies; 6+ messages in thread
From: Boris Burkov @ 2025-11-19 23:03 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Sat, Nov 15, 2025 at 08:16:00AM +1030, Qu Wenruo wrote:
> The test case fsck/066 is only to verify we can detect the missing root
> orphan item, no repair for it yet.
>
> Now the repair ability is added, change the test case to verify the
> repair is also properly done.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Boris Burkov <boris@bur.io>
> ---
> .../.lowmem_repairable | 0
> .../066-missing-root-orphan-item/test.sh | 14 --------------
> 2 files changed, 14 deletions(-)
> create mode 100644 tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable
> delete mode 100755 tests/fsck-tests/066-missing-root-orphan-item/test.sh
>
> diff --git a/tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable b/tests/fsck-tests/066-missing-root-orphan-item/.lowmem_repairable
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/tests/fsck-tests/066-missing-root-orphan-item/test.sh b/tests/fsck-tests/066-missing-root-orphan-item/test.sh
> deleted file mode 100755
> index 9db625714c1f..000000000000
> --- a/tests/fsck-tests/066-missing-root-orphan-item/test.sh
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -#!/bin/bash
> -#
> -# Verify that check can report missing orphan root itemm as an error
> -
> -source "$TEST_TOP/common" || exit
> -
> -check_prereq btrfs
> -
> -check_image() {
> - run_mustfail "missing root orphan item not reported as an error" \
> - "$TOP/btrfs" check "$1"
> -}
> -
> -check_all_images
> --
> 2.51.2
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-11-19 23:04 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 21:45 [PATCH 0/2] btrfs-progs: check: add repair ability for missing root orphan item Qu Wenruo
2025-11-14 21:45 ` [PATCH 1/2] btrfs-progs: check: add repair ability for missing orphan root item Qu Wenruo
2025-11-19 23:02 ` Boris Burkov
2025-11-14 21:46 ` [PATCH 2/2] btrfs-progs: fsck-tests: make test case 066 to be repairable Qu Wenruo
[not found] ` <314461b6-9c30-4f19-aed3-486656db661e@libero.it>
2025-11-15 10:45 ` Qu Wenruo
2025-11-19 23:03 ` Boris Burkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox