quarta-feira, 19 de dezembro de 2012

dc3dd e Advanced Format

No Zero Linux, o dc3dd é usado para escrever zeros no disco. Havia notado faz algum tempo que ele não identificava corretamente o tamanho dos setores de discos com Advanced Format (setores físicos de 4KiB). Dei uma olhada no código e acho que resolvi com as seguintes modificações na versão 7.1.614.

--- src/dc3dd.c.orig 2010-11-11 16:58:12.000000000 -0200
+++ src/dc3dd.c 2013-01-30 09:47:59.354745208 -0200
@@ -41,6 +41,7 @@
 #ifdef __linux__
    #include <sys/mount.h>
    #include <sys/mtio.h>
+   #include <linux/fs.h>
    #ifdef USE_HDPARM
    #include <linux/types.h>
    #include "hdparm/hpa_dco.h"
@@ -2139,23 +2140,14 @@
          file->is_device = true;
          file->is_block_device = S_ISBLK(file_info.st_mode);
          
-         uintmax_t size_in_sectors = 0;
-         uintmax_t sector_size = 0;
-         if (ioctl(file->descriptor, BLKGETSIZE, &size_in_sectors) == 0 && 
-             ioctl(file->descriptor, BLKSSZGET, &sector_size) == 0)
+         uintmax_t size_in_bytes = 0;
+         uintmax_t phys_sector_size = 0;
+         if (ioctl(file->descriptor, BLKGETSIZE64, &size_in_bytes) == 0 &&
+             ioctl(file->descriptor, BLKPBSZGET, &phys_sector_size) == 0)
          {
-            file->probed_sector_size = sector_size;
-            if (sector_size == 512)
-            {
-               file->probed_size_in_sectors = size_in_sectors;
-            }
-            else
-            {
-               // ioctl() reports device size in terms of 512 byte sectors, 
-               // regardless of actual sector size.
-               file->probed_size_in_sectors = size_in_sectors * 512 / sector_size; 
-            }
-            file->probed_size_in_bytes = file->probed_size_in_sectors * file->probed_sector_size;
+            file->probed_sector_size = phys_sector_size;
+            file->probed_size_in_bytes = size_in_bytes;
+            file->probed_size_in_sectors = file->probed_size_in_bytes / file->probed_sector_size;
             file->probed = true;
          }
       }

(BLKPBSZGET é suportado desde o kernel 2.6.32)

Acho pois não tenho nenhum HD com AF agora onde possa testar. O HD do meu Acer E1 não, pois não estou a fim de fazer uma imagem ou reinstalar tudo de novo.

O uso que dou para o dc3dd é restrito, por isso não sei se a mudança pode ter algum efeito colateral em outros cenários. Coloquei no ar o Zero Linux 1.13, que tem esse patch aplicado. Quem por acaso testar, por favor reporte -- o script zera precisa ser chamado com -t, para o dc3dd ser invocado com wipe=, que aciona o código acima.

Com o patch, ao usar wipe=, ssz= e cnt= são corretamente configuradas (de forma automática) em discos com AF, o que evitará ciclos read-modify-write.

Nenhum comentário:

Postar um comentário