web-dev-qa-db-ja.com

BTRFSは、I / Oエラーを無視して、欠落しているドライブを削除します

3台のドライブに分散されたBTRFSファイルシステムがあります(RAIDなし)。私のドライブの1つが昨日死にました。私はまだファイルシステムを使用してマウントすることができます

Sudo mount $path -o degraded,ro

約120kファイル(1.1mのうち)が読み取りエラーをスローしますが、残りはまだそこにあります。バックアップがありますが、すべてのデータを破壊せずに、不足しているディスクをアレイから削除するにはどうすればよいですか?

私は試した

Sudo btrfs device delete missing $path

、しかしそれはERROR: error removing the device 'missing' - Read-only file systemを出力しますが、ドライブがないために読み取り/書き込みでマウントできません。

明らかな解決策は、すべての作業データを新しいファイルシステムにコピーすることですが、現在、別の4TBドライブがないため、破損したファイルのみを削除して、バックアップから復元できれば素晴らしいと思います。

2
phiresky

私は同じ問題に遭遇しました。 DATA:single、METADATA:raid1、SYSTEM:raid1のマルチデバイスアレイに新しいディスクを追加しました。新しいディスクは約2分後に失敗し、次のようになりました。

tassadar@sunfyre:~$ Sudo btrfs fi usage /mnt/store
Overall:
    Device size:                   7.28TiB
    Device allocated:              7.14TiB
    Device unallocated:          140.98GiB
    Device missing:                  0.00B
    Used:                          7.14TiB
    Free (estimated):            141.99GiB      (min: 71.50GiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              512.00MiB      (used: 96.00KiB)

Data,single: Size:7.06TiB, Used:7.05TiB
   /dev/sdc1       3.53TiB
   /dev/sdd1       3.53TiB
   missing         2.00GiB

Metadata,RAID1: Size:43.00GiB, Used:41.81GiB
   /dev/sdc1      43.00GiB
   /dev/sdd1      43.00GiB

System,RAID1: Size:32.00MiB, Used:880.00KiB
   /dev/sdc1      32.00MiB
   /dev/sdd1      32.00MiB

Unallocated:
   /dev/sdc1      70.99GiB
   /dev/sdd1      69.99GiB
   missing         3.71TiB

Ro、degradedでのみマウント可能でした。これは、不足しているデバイスを削除する必要がある場合には役に立ちません。これを修正する方法が見つからず、それらのディスク上のデータはそれほど重要ではなかったので、カーネルをハッキングし始めました。

Workaround

以下のすべては明らかに非常に危険であり、すべてを盲目的にコピーペーストすることは最善のアイデアではないかもしれません。

これらは私がVanilla4.7.4カーネルツリーに加えた変更であり、主に「私が本当に理解していないものをコメントアウトする」という古代の技術です( 構文の強調表示付き ):

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 864cf3b..bd10a1d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3588,6 +3588,8 @@ int btrfs_calc_num_tolerated_disk_barrier_failures(
        int num_tolerated_disk_barrier_failures =
                (int)fs_info->fs_devices->num_devices;

+       return num_tolerated_disk_barrier_failures;
+
        for (i = 0; i < ARRAY_SIZE(types); i++) {
                struct btrfs_space_info *tmp;

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 589f128..cbcb7b2 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2817,7 +2817,8 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
                }

                if (map->stripes[i].dev) {
-                       ret = btrfs_update_device(trans, map->stripes[i].dev);
+//                     ret = btrfs_update_device(trans, map->stripes[i].dev);
+                       ret = 0;
                        if (ret) {
                                mutex_unlock(&fs_devices->device_list_mutex);
                                btrfs_abort_transaction(trans, root, ret);
@@ -2878,13 +2879,15 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
         */
        ASSERT(mutex_is_locked(&root->fs_info->delete_unused_bgs_mutex));

-       ret = btrfs_can_relocate(extent_root, chunk_offset);
+//     ret = btrfs_can_relocate(extent_root, chunk_offset);
+       ret = 0;
        if (ret)
                return -ENOSPC;

        /* step one, relocate all the extents inside this chunk */
        btrfs_scrub_pause(root);
-       ret = btrfs_relocate_block_group(extent_root, chunk_offset);
+//     ret = btrfs_relocate_block_group(extent_root, chunk_offset);
+       ret = 0;
        btrfs_scrub_continue(root);
        if (ret)
                return ret;

基本的に、実際にエクステントを移動することなく、「エクステントを別のデバイスに移動する」部分全体を実行します->欠落しているドライブ上の古いものを削除するだけです。また、fsの読み取り/書き込みをマウントすることもできます。 この「パッチ」を(他の)正常なbtrfsシステムで使用することは安全ではありません。

デバイスの削除が「機能」するようになりました。

tassadar@sunfyre:~$ Sudo mount -o degraded /dev/sdd1 /mnt/store

tassadar@sunfyre:~$ Sudo btrfs device delete missing /mnt/store
ERROR: error removing device 'missing': No such file or directory

tassadar@sunfyre:~$ Sudo btrfs fi usage /mnt/store
Overall:
    Device size:                   7.28TiB
    Device allocated:              7.14TiB
    Device unallocated:          140.98GiB
    Device missing:                  0.00B
    Used:                          7.14TiB
    Free (estimated):            141.99GiB      (min: 71.50GiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              512.00MiB      (used: 96.00KiB)

Data,single: Size:7.06TiB, Used:7.05TiB
   /dev/sdc1       3.53TiB
   /dev/sdd1       3.53TiB

Metadata,RAID1: Size:43.00GiB, Used:41.81GiB
   /dev/sdc1      43.00GiB
   /dev/sdd1      43.00GiB

System,RAID1: Size:32.00MiB, Used:880.00KiB
   /dev/sdc1      32.00MiB
   /dev/sdd1      32.00MiB

Unallocated:
   /dev/sdc1      70.99GiB
   /dev/sdd1      69.99GiB
   missing           0.00B

tassadar@sunfyre:~$ Sudo umount /mnt/store

tassadar@sunfyre:~$ Sudo mount /dev/sdd1 /mnt/store

tassadar@sunfyre:~$ Sudo btrfs fi usage /mnt/store
Overall:
    Device size:                   7.28TiB
    Device allocated:              7.14TiB
    Device unallocated:          140.98GiB
    Device missing:                  0.00B
    Used:                          7.14TiB
    Free (estimated):            141.99GiB      (min: 71.50GiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              512.00MiB      (used: 0.00B)

Data,single: Size:7.06TiB, Used:7.05TiB
   /dev/sdc1       3.53TiB
   /dev/sdd1       3.53TiB

Metadata,RAID1: Size:43.00GiB, Used:41.81GiB
   /dev/sdc1      43.00GiB
   /dev/sdd1      43.00GiB

System,RAID1: Size:32.00MiB, Used:880.00KiB
   /dev/sdc1      32.00MiB
   /dev/sdd1      32.00MiB

Unallocated:
   /dev/sdc1      70.99GiB
   /dev/sdd1      69.99GiB

できるだけ早く回避策なしで元のカーネルに戻すようにしてください。

結果

私のfsは今は大丈夫のようです。障害が発生したディスクにあった少量のデータが失われた可能性がありますが、「シングル」モードで実行した場合はそれが予想されます。私は現在btrfsscrubを実行して、何かがひどく壊れているかどうかを確認しています。この投稿が終了したら編集します。

編集:スクラブは問題なく終了しましたが、fsはまだ破損しています-そこからいくつかのファイルを削除し始めたとき、カーネルは欠落しているドライブにあるいくつかのファイルを見つけ、エラーをスローしました。そこで、カーネルにもう一度パッチを適用しました(今回は、以前の変更なしで、クリーンな4.7.4の上にパッチを適用しました)。

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 82b912a..f10b3b6 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -6853,8 +6853,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,

                ret = update_block_group(trans, root, bytenr, num_bytes, 0);
                if (ret) {
-                       btrfs_abort_transaction(trans, extent_root, ret);
-                       goto out;
+                       btrfs_err(info, "update_block group has failed (%d)", ret);
+                       ret = 0;
+                       //btrfs_abort_transaction(trans, extent_root, ret);
+                       //goto out;
                }
        }
        btrfs_release_path(path);

FSは明らかに大丈夫ではないので、確かに良い解決策ではありません。しかし、現在は使用可能になっているので、実際には何も失うことはなく、これは優先度が高くありませんでした。ストレージ、私はかなり満足しています。

1
Tassadar