Itsukaraの日記

最新IT技術を勉強・実践中。最近はDeep Learningに注力。

HDDの読み出しエラーへの対応(正常な状態に復帰)

FastCopyでファイルコピー中に読み出しエラーが発生

FastCopyで内臓HDD中のファイルを外部HDDにコピーしていたら、一部のファイルが読み出しできずにエラーとなってしまった... FastCopyでのファイルコピーを何回か試しましたが、読み出しできませんでした。

ReadFile(データ エラー (巡回冗長検査 (CRC) エラー) です。23) : W:\WORK\file1.mp4
ReadFile(データ エラー (巡回冗長検査 (CRC) エラー) です。23) : W:\WORK\file2.mp4

CrystalDiskInfoで状況確認(黄色で注意マークあり)

HDDの状態をCrystalDiskInfoで確認したところ、Wドライブで、「代替処理保留中のセクタ数」が0以外(2)になっており、この部分で黄色の注意マークが表示されていました。

f:id:Itsukara:20160331115444j:plain

注意マークが出ている「代替処理保留中のセクタ数」について調べたところ、下記の記載がありました。読み出しができずにペンディングになっているセクタの数とのことです。

https://pctrouble.net/repair/smart_badsectors.html

C5(197) - 代替処理保留中のセクタ数
ファームウェアによって認識されている不安定なセクタの数。
セクタ読み取りエラーが発生した場合に、ファームウェアによって代替処理保留セクタとして登録されます。
通称、ペンディングセクタ。

セクタ代替処理は、次のアクセスがあるまで一旦保留(ペンディング)されています。
該当セクタに対して、次回の読み取りに成功すれば、再び正常なセクタとして扱われ、この数値は減少します。
逆に失敗した場合、代替処理すべきセクタとして登録され、
次回このセクタへの書き込みがあった時に代替処理されます。

対応策

読み出しエラー発生ファイルの分離

何回か読みだしても、読み出しが成功しなかったので、エラーが出たファイルは、同じHDD内の、別のディレクトリに移動しておくこととしました。

読み出しエラーファイルへの書き込み

ただ、分離しておくだけでは気持ちが悪いので、別の対策を検討しました。上記で引用した説明によると「次回このセクタへの書き込みがあった時に代替処理されます」とのことなので、このファイルに書き込みを行うことにしました。これによって、「代替処理保留中のセクタ数」が0となり、「セクタ代替処理発生回数」が2になると予測されます。

Windowsでファイルに上書きして書き込みを行うプログラムを探したのですが、適切なものが直ぐに見つからなかったので、ツールを作成しました。具体的には、以前にインストールしたCygwin64の環境でプログラム(C言語)を作成し、これをCygwin64のgccコンパイルし、ファイル上書きツールとしました(ファイルの中身を0で埋めるツールです)。

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE 4096

int main(int argc, char *argv[])
{
    char *fname;
    struct stat sb;
    long long fsize, bcount, i;
    FILE *file;
    char buf[BUFSIZE];

   if (argc != 2) {
        fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

   fname = argv[1];
   if (stat(fname, &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }

    fsize = (long long) sb.st_size;
    printf("fsize = %lld\n", fsize);

    for (i = 0; i < BUFSIZE; i++) {
      buf[i] = 0;
    }
    bcount = (fsize + BUFSIZE - 1) / BUFSIZE;

    file = fopen(fname, "r+");
    for (i = 0; i < bcount; i++) {
      fwrite(buf, BUFSIZE, 1, file);
    }
    fclose(file);
}

ファイル上書き結果、何もなかったかのような状態に...

読み出しエラーが出ていたファイルを、上記のツールで順に上書きしました。それぞれの上書き後のCrystalDiskInfoの情報を下記に載せます。結果として、「代替処理保留中のセクタ数」は0となり、「正常」な状態に復帰しました。また、上書きよって、「セクタ代替処理発生回数」が増えるかと思ったのですが、0のままでした。結果、何事も起らなかったかのような状態となりました。

f:id:Itsukara:20160331115443j:plain

f:id:Itsukara:20160331115445j:plain

実行ファイル

Cygwin64の環境を持っていない人もいると思いますので、上記Cファイルをコンパイルした実行ファイルを下記にアップしました。「Download ZIP」ボタンを押すと、実行ファイルも含めてzipしたものがダウンロードされますので、展開してお使いください。共に、mingw32コンパイラコンパイルしたので、「cygwin1.dll」といったDLLなしで、単独で実行可能です。

https://github.com/Itsukara/fzero
mingw32-fzero.exe : 32ビットWindows環境用の実行ファイル
mingw64-fzero.exe : 32ビットWindows環境用の実行ファイル

今後

HDDは正常な状態に復帰しましたが、一度エラーが起こったHDDであり、少し注意が必要なので、今後は、一時的なデータの保管場所として使うことにしたいと思います。また、今後、定期的に、CrystalDiskInfoでエラーが起こっていないかチェックしていくつもりです。、