On 2019/1/15 下午7:47, HIRAKI Hideaki wrote:
> Hello,
> 
> I have two questions and a bug report.
> 
> Once upon a time I converted an ext3 partition to BTRFS to mount on
> /var/lib/docker and was happy with it. Recently an error occured:
> 
>  kernel: BTRFS info (device sdc1): leaf 2013170442240 total ptrs 171 free 
> space 6365
>  kernel: BTRFS error (device sdc1): eb 2013170442240 invalid extent inline 
> ref type 182
>  kernel: BTRFS: Transaction aborted (error -22)
>  kernel: BTRFS: error (device sdc1) in btrfs_run_delayed_refs:3089: errno=-22 
> unknown
>  kernel: BTRFS info (device sdc1): forced readonly
>  kernel: BTRFS error (device sdc1): pending csums is 77824
> 
> Now I know this was caused by the kernel upgrade from 4.12.5 to 4.14.83 which
> introduced an additional check of alignments rather than by a recent trivial
> file system corruption.

Nope, the alignment check is mostly done by tree-checker, but it's not
the case.

It's a really valid extent type checker, introduced by commit
167ce953ca55 ("Btrfs: add a helper to retrive extent inline ref type"),
which get merged into v4.14.

I'm not pretty sure why but this looks like either some corruption in
extent tree code, or just too old btrfs-convert.

> But I was hasty and commited such follies as hard
> resets on busy kernel, btrfs rescue chunk-recover -y,

Chunk-recovery is normally useless.

> btrfs check --repair,

And this could cause more problem unless you're really knowing the
problem can be fixed or your data isn't that important.

> etc. As you may expect, the partition is not mountable any more:
> 
> # mount -o compress=lzo,noatime /dev/sdc1 /mnt/temp
> mount: /mnt/temp: wrong fs type, bad option, bad superblock on /dev/sdc1, 
> missing codepage or helper program, or other error.
> 
>  kernel: BTRFS info (device sdc1): use lzo compression
>  kernel: BTRFS info (device sdc1): disk space caching is enabled
>  kernel: BTRFS info (device sdc1): has skinny extents
>  kernel: BTRFS info (device sdc1): bdev /dev/sdc1 errs: wr 1396, rd 0, flush 
> 0, corrupt 0, gen 0
>  kernel: BTRFS error (device sdc1): logical 3955568533504 len 1073741824 
> found bg but no related chunk

Some bad recovery move caused more problem, one block group doesn't has
corresponding chunk.
I don't know exactly what the cause is.

>  kernel: BTRFS error (device sdc1): failed to read block groups: -2
>  kernel: BTRFS error (device sdc1): open_ctree failed
> 
> Even btrfs check aborts:
> 
> # btrfs check --repair /dev/sdc1> enabling repair mode
> Opening filesystem to check...
> volumes.c:1729: btrfs_chunk_readonly: BUG_ON `!ce` triggered, value 1
> btrfs(+0x2e246)[0x562a5547c246]
> btrfs(+0x30cac)[0x562a5547ecac]

This could be worked around.

diff --git a/volumes.c b/volumes.c
index 30090ce5f8e8..05deeed710fb 100644
--- a/volumes.c
+++ b/volumes.c
@@ -1725,9 +1725,7 @@ int btrfs_chunk_readonly(struct btrfs_fs_info
*fs_info, u64 chunk_offset)
         * corresponding chunk, we will rebuild it later
         */
        ce = search_cache_extent(&map_tree->cache_tree, chunk_offset);
-       if (!fs_info->is_chunk_recover)
-               BUG_ON(!ce);
-       else
+       if (!ce)
                return 0;

        map = container_of(ce, struct map_lookup, ce);



> btrfs(btrfs_read_block_groups+0x27d)[0x562a55471f8d]
> btrfs(btrfs_setup_all_roots+0x35f)[0x562a5546bc9f]
> btrfs(+0x1e0cb)[0x562a5546c0cb]
> btrfs(open_ctree_fs_info+0x8c)[0x562a5546c2cc]
> btrfs(cmd_check+0x4db)[0x562a554b670b]
> btrfs(main+0x7a)[0x562a55461e2a]
> /lib64/libc.so.6(__libc_start_main+0xee)[0x7f83e3598bde]
> btrfs(_start+0x2a)[0x562a55461f3a]
> Aborted
> 
> How to repair this file system?

Use above diff to allow btrfs check to continue.
But no --repair, and paste the output.

Unfortunately, I don't believe the chance of a proper recovery is high.

> 
> 
> The second question is about btrfs-restore. It doesn't restore subvolumes
> even when the destination path is in a BTRFS file system.

I had a plan to support snapshot/subvolume creation for btrfs-restore if
destination is btrfs, or supports reflink.

But that feature will be too late for your use case anyway.

> "btrfs restore -l"
> is to list subvolumes but the output lacks the path (relative to the top
> level subvolume) information.

You could try my experimental patch:
https://patchwork.kernel.org/patch/10738583/

It provides kernel equivalent of btrfs-restore, using 'ro,skip_bg' mount
option.

If everything goes OK, then you should be able to get 'btrfs subv list'
working.

Thanks,
Qu

> With the information, the destination of
> btrfs-restore with the subvolumes could be prepared and hopefully
> "dockerd" would work properly with the restored file tree, though the files
> would be duplicated significantly.


> 
> How can the subvolumes' paths be obtained from an unmountable file system?
> 
> 
> By the way, some constants in the source code had to be increased to run
> btrfs-restore for me.
> 
> --- cmds-restore.c~   2018-11-03 19:06:34.000000000 +0900
> +++ cmds-restore.c    2019-01-09 00:34:17.000000000 +0900
> @@ -289,7 +289,7 @@ static int copy_one_inline(struct btrfs_
>  {
>         struct extent_buffer *leaf = path->nodes[0];
>         struct btrfs_file_extent_item *fi;
> -       char buf[4096];
> +       char buf[65536];
>         char *outbuf;
>         u64 ram_size;
>         ssize_t done;
> @@ -729,7 +729,7 @@ static int copy_file(struct btrfs_root *
>         }
>  
>         while (1) {
> -               if (loops >= 0 && loops++ >= 1024) {
> +               if (loops >= 0 && loops++ >= 102400) {
>                         enum loop_response resp;
>  
>                         resp = ask_to_continue(file);
> @@ -1007,7 +1007,7 @@ static int search_dir(struct btrfs_root
>         }
>  
>         while (leaf) {
> -               if (loops++ >= 1024) {
> +               if (loops++ >= 102400) {
>                         printf("We have looped trying to restore files in %s "
>                                "too many times to be making progress, "
>                                "stopping\n", in_dir);
> 
> The first one is to avoid the abortion with "*** stack smashing detected ***".
> So, not only the increase but also a size checking code (at least) is
> necessary to fix this bug. I hope the other two constants (if necessary) will
> be tunable from the command line option.
> 
> 
> For your information:
> 
> # uname -a
> Linux plcd1 4.14.83-gentoo #1 SMP Wed Dec 19 00:20:46 JST 2018 x86_64 
> Intel(R) Core(TM) i7-3970X CPU @ 3.50GHz GenuineIntel GNU/Linux
> 
> # btrfs --version
> btrfs-progs v4.19 
> 
> # btrfs fi show
> Label: none  uuid: 5e3d788d-5b81-4e3e-8776-5a131d008cbc
>         Total devices 1 FS bytes used 1.41TiB
>         devid    1 size 1.82TiB used 1.43TiB path /dev/sdc1
> 
> 
> Regards,
> 
> Hideaki
> 

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to