1

У меня есть файловая система BTRFS, распределенная на 3 диска (без рейда). Один из моих дисков умер вчера. Я все еще могу смонтировать файловую систему, используя

sudo mount $path -o degraded,ro

Около 120 тыс. Файлов (из 1,1 м) выдают ошибки чтения, остальное все еще там. У меня есть резервные копии, но как мне удалить отсутствующий диск из массива, не уничтожив все данные?

Я старался

sudo btrfs device delete missing $path

, но это выдает ERROR: error removing the device 'missing' - Read-only file system , но я не могу смонтировать ее для чтения / записи из-за отсутствующего диска ...

Очевидным решением было бы скопировать все рабочие данные в новую файловую систему, но в настоящее время у меня нет другого диска емкостью 4 ТБ, поэтому было бы здорово, если бы я мог просто удалить только поврежденные файлы, а затем восстановить их из резервной копии.

2 ответа2

1

Я столкнулся с той же проблемой. Я добавил новый диск в массив для нескольких устройств: 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, деградировавшим, что бесполезно, когда мне нужно удалить отсутствующее устройство. Я не мог найти способ исправить это, и данные на этих дисках были не очень важны, поэтому я начал взламывать ядро.

Временное решение

Все нижеприведенное, очевидно, очень небезопасно, и слепое копирование может быть не самой лучшей идеей.

Это изменения, которые я сделал в дереве ядра vanilla 4.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

Обязательно вернитесь к исходному ядру без обходного пути как можно скорее.

Результат

Кажется, с моим фс теперь все в порядке. Возможно, я потерял небольшое количество данных, которые были на неисправном диске, но это ожидалось, когда я запустил его в "одиночном" режиме. В настоящее время я запускаю btrfs scrub, чтобы увидеть, если что-то ужасно сломано или нет, отредактирую этот пост, как только он закончится.

РЕДАКТИРОВАТЬ: очистка завершена без каких-либо проблем, но файловая система по-прежнему повреждена - когда я начал удалять некоторые файлы из него, ядро обнаружило некоторые файлы, которые были на отсутствующем диске и выдало ошибку. Итак, я исправил ядро еще раз (на этот раз поверх чистой 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 явно не в порядке. Но так как он теперь пригоден для использования, я ничего не потерял, и это не было высокоприоритетным хранилищем, я вполне доволен.

0

Ухудшенная файловая система должна быть смонтирована как readwrite, прежде чем начинать с btrfs device delete missing btrfs. Монтаж с -o degraded должен ухудшиться .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .