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