BTRFS exclui a unidade ausente, ignorando os erros de E / S

1

Eu tenho um sistema de arquivos BTRFS, distribuído em 3 unidades (sem invasão). Um dos meus drives morreu ontem. Eu ainda posso montar o sistema de arquivos usando

sudo mount $path -o degraded,ro

Cerca de 120k arquivos (de 1,1m) lançam erros de leitura, o restante ainda está lá. Eu tenho backups, mas como remover o disco ausente da matriz, sem destruir todos os dados?

Eu tentei

sudo btrfs device delete missing $path

, mas isso gera ERROR: error removing the device 'missing' - Read-only file system , mas não consigo montá-lo como leitura / gravação devido à unidade ausente ...

A solução óbvia seria copiar todos os dados de trabalho para um novo sistema de arquivos, mas atualmente não tenho outra unidade de 4TB, então seria ótimo se eu pudesse simplesmente ter apenas os arquivos corrompidos excluídos e, em seguida, restaurados de backup.

    
por phiresky 28.07.2015 / 17:25

2 respostas

1

Eu encontrei o mesmo problema. Eu adicionei um novo disco em uma matriz de vários dispositivos que foi DATA: single, METADATA: raid1, SYSTEM: raid1. O novo disco falhou cerca de 2 minutos depois, deixando-me com isto:

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

Era apenas montável com ro, degradado, o que é inútil quando preciso remover o dispositivo ausente. Eu não encontrei nenhuma maneira de consertar isso e os dados nesses discos não eram muito importantes, então eu comecei a hacking no kernel.

Solução alternativa

Todos os itens abaixo são obviamente muito inseguros e copiar tudo às cegas pode não ser a melhor ideia.

Estas são as mudanças que eu fiz na vanilla 4.7.4, principalmente o antigo ofício de "comentar coisas que eu realmente não entendo" ( com realce de sintaxe ):

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;

Basicamente, ele faz a parte "mover extensões para outro dispositivo" sem realmente mover as extensões - > apenas apaga os antigos na unidade ausente. Também me permite montar o fs read-write. Usar este "patch" com outros sistemas btrfs saudáveis não é seguro.

A exclusão de dispositivos "funciona" agora:

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

Certifique-se de voltar ao kernel original sem a solução alternativa o mais rápido possível.

Resultado

Meu fs parece estar bem agora. Eu poderia ter perdido uma pequena quantidade de dados que estava no disco com falha, mas isso é esperado quando eu o executei no modo "único". No momento, estou executando o scrubs do btrfs para ver se algo está terrivelmente quebrado ou não, editei este post assim que terminar.

EDIT: O scrub terminou sem nenhum problema, mas o fs ainda está corrompido - quando eu comecei a deletar alguns arquivos dele, o kernel encontrou alguns arquivos que estavam na unidade ausente e jogou um erro. Então, eu atualizei o kernel mais uma vez (desta vez no topo do 4.7.4 limpo, sem as mudanças anteriores):

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);

Então, sim, definitivamente não é uma boa solução, já que o FS obviamente não está bem. Mas desde que agora é utilizável, eu realmente não perdi nada e isso não era um armazenamento de alta prioridade, estou bastante satisfeito.

    
por 23.09.2016 / 13:09
0

O sistema de arquivos degradado deve ser montado readwrite antes de iniciar com btrfs device delete missing . A montagem com -o degraded deve funcionar.

    
por 26.08.2016 / 11:10