パーティションを切らないフォーマットは危険(Linux/Windows)

## 要約
+ LinuxでexFATフォーマットする時に`/dev/sdb`のようにパーティションでなくドライブを単位としてフォーマットできてしまうが、`/dev/sdb1`のように1つだけでもパーティションを切ってからフォーマットするべき。
+ もし、ドライブ単位でフォーマットした後にデータを保存してしまったら、Windowsには決してつないではならない。**つないだだけで**読み出し不能になる。

## 環境
+ Ubuntu 20.04 LTS(一部18.04)
+ Windows 10 Pro 21H1
+ Ubuntu 18.04にはexfat-fuse, exfat-utils導入済み。20.04には導入なし。

## 動機
新しく買ったHDDをexFATフォーマットしようと調べていたら、[Linux側でフォーマットするとWindows側から読めなくなる](http://var.blog.jp/archives/84416558.html)という記事を見かけたので、どうやってフォーマットするか迷った。

## 検証
Ubuntu上でドライブは`/dev/sdb`だったものとする。先にgparted上でパーティションテーブルをGPTにした。

### ドライブ単位でフォーマット
いきなり`sudo mkfs.exfat /dev/sdb`でフォーマットしてgparted上で確認したが、フラグの設定などのメニューが選択できなかった。(Ubuntu 20.04ではexfat-fuse, exfat-utilsなしでもexFATを読むことは出来るが、インストールしないとmkfs.exfatがないと言われてフォーマットはできない。)

Gpartedで「表示 -> デバイス情報」で確認すると、パーティションテーブルが「なし」になっていた。

#### 警告表示
Gparted上で警告が表示され、「情報」を見ると「このファイルシステムの内容を読み込むことができません!これによりいくつかの操作が利用できません」と表示された。もっとも、つなぎ直すと警告が消えたり、後からつないだ他のドライブにも表示されたりされなかったりしたので、接続の順序などによる一時的なものだと思われる。

#### データ破損
検証のためこれをWindowsに接続すると、Windowsの「ディスク管理」からは、MBRのドライブとして扱われ、2048GBと残りの領域に分けられ、両者とも未割り当て領域として認識された。

これをLinux側に戻して接続しようとしたのだが、エラーが出てマウントされなくなってしまった。

### パーティションを切ってからフォーマット
gpartedでドライブを丸ごと1つの新規パーティションにすると、位置合わせをMiBにしたせいか後方に1MiBの未割り当て領域が出来た。余談だが位置合わせをシリンダにした場合は未割り当て領域は出現しなかった。

出来上がったパーティション`/dev/sdb1`を`sudo mkfs.exfat /dev/sdb1`でフォーマットすると、gparted上でフラグの設定が可能であった。

msftdataフラグを設定しないとWindows側からは認識されれず、「ディスク管理」でもドライブのプロパティは表示できるが、パーティションについては認識こそされるもののボリューム削除以外の操作はできず、ドライブ名の割り当ても不可であった。

msftdataフラグを立てて再度Windowsに接続すると、exFATとして認識され、ドライブ名も割り当てられた。


### Windows上でフォーマット
Windows 10上でフォーマットした(と記憶している)SDカードをgpartedで確認すると、パーティションを切ってある上、前方に32MiBの未割り当て領域があった。

HDDをフォーマットすると、`/dev/sdb1`はmsftresフラグありで
15.98MiBのMicrosoft reserved partitionとして隠しパーティションが作成されていた。

`/dev/sdb2`はmsftdataフラグあり、後方は2MiBの空き領域ができていた。


## 試さなかったこと
exFATの仕様書でドライブ内に1つだけでもパーティションを切ってからフォーマットするのが正式なのか調べた方がよいのかもしれないが、仕様書の場所もわからないし、わかっても膨大な仕様書のどこに書かれているか探せそうな気がしないし、パーティションテーブルはフォーマット形式の管轄外で書かれてすらいない可能性も高いので調べていない。

## 考察
### 技術的な推測
パーティションでなくドライブ単位でフォーマットすると、ドライブ先頭のパーティションテーブルの記録領域にフォーマット情報が書き込まれてパーティションテーブルが破壊されるのだと思われる。

そして、Windowsに接続すると「パーティションテーブルがない」ので「自動で」パーティションテーブルの記録領域にMBRが作成され、そこに書かれていたフォーマット情報が破壊されてフォーマットすらされていない状態になるのだろう。

他のフォーマット形式は試していないが、原理的にはexFatフォーマットに限らないことから、一般的にパーティションを切らずにドライブ単位でフォーマットするのは避けるべきといえる。

### 個人的な意見と感想
ドライブ単位でフォーマットしてもLinux側では普通に扱えてしまうことは、かえって問題発生を助長しているかも知れない。[こちらのページ](https://www.nemotos.net/?p=2083)に限らないが、mkfs.exfatの解説でパーティションを切らずにフォーマットしている例文を載せているページが複数あるのは、Windowsにつながないので問題に気づいていないからかではなかろうか。仕様上正しかったとしても、`/dev/sdb`のようにドライブを単位としたフォーマットは認めないか、開始前に十分な警告が表示されるべきだと思う。

exFATフォーマットの主な使い道といえばWindows, Mac, Linuxの間でデータをやりとりするメディア用なので、必然的に物理媒体1つを丸ごとexFATにする展開となり、このような状況に直面することは多いのではと思った。Linuxでしか使わないから大丈夫と思っていても、今回のように何かの拍子にWindowsにつないでしまうことはあるかもしれない。

exfat-utilsのバージョンが1.0.1くらいだった頃からSDカードをLinux上でexFATにするのと、Winodws上でするのとでは、`/dev/`以下に表示される構造に違いがあるのが気になっていたので、その点はすっきりすることができた。~~代償は大きかったが。~~


## 補足: 破損データの復旧作業
ドライブ単位でフォーマットした後、Windowsに接続して破損したドライブの復旧記録。

### GParted
GPartedに「デバイス -> データの救出を試みる」というのがあるが、gpartを利用しており、gpartを調べてみると対応するフォーマット形式がかなり限定されていた。試しに少し動かしてみたが、数時間しても終わる気配がないので中断した。

### シェル
GPTには末尾にパーティションテーブルの[バックアップデータがある](https://jp.easeus.com/partition-manager/mbr-gpt-features-differences-convert-methods.html)という話だが、GPTだと認識できないためか`gdisk -l`のようなコマンドを使ってもバックアップデータの存在が確認できなかった。

### ファイナルデータ
[前回の記事](https://qiita.com/sskki/items/762cc6b47ed1b0693150)で試用版にお世話になった。まさかこんな形で購入することになろうとは。
一応、ほぼ全てのファイルが復旧できたのだが、どうも2-3個行方不明になったファイルが出てしまった模様。もしかしたらコピーし忘れていて、始めから存在しなかった可能性もあるにはあるが、割と直近に触ったファイルだし、フォルダのデータをコピーする前のフォルダデータが優先されてしまったのかもしれない。

復旧に要した時間は1TBあたり3時間くらいだったろうか。新品のHDDが復旧データで一杯になってしまった。

## 改訂履歴(表現の修正などは除く)
+ 2021/8/27: 作成開始。
+ 2021/9/2: 検証を記載。
+ 2021/9/19: データ破損に関して全面改訂。
+ 2021/10/10: さらに手直しして公開。
+ 2021/10/20: タイトルと構成の変更。表現の統一。