WinBtrfs v1.0.1を動かす

# はじめに
Linuxファイルシステムの1つにbtrfsというものがあります。そのbtrfsをWindowsから扱うことができるWinBtrfs[^1]というものがあり、2017/9にversion 1がリリースされました。これはLinuxでのbtrfsとは完全に独立して実装されており、コミットログを見る限りではほぼすべてを1人で作っているようです。

[^1]: https://github.com/maharmstone/btrfs/

githubのREADMEを読むとbtrfsの機能の大部分がすでに実装されています。しかしながらREADME以外にドキュメントがない上、動かしている人を見たことがないので、実際に動作を確認してみます。

# 注意事項
当然ながら100%無保証です。データを飛ばしてもいい人だけがやりましょう。

# 検証環境
- Windows 10 Home Edition
- ArchLinux (kernel 4.15.6, btrfs-progs 4.15.1)

# btrfsについて
linuxのbtrfsについては公式wiki[^2]やマニュアル[^3]、ArchWiki[^4]を参照してください。

[^2]: https://btrfs.wiki.kernel.org/index.php/Main_Page
[^3]: https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs
[^4]: https://wiki.archlinux.jp/index.php/Btrfs

# インストール
READMEに書いてある通り、githubからversion 1.0.1のzipをダウンロードし、その中のbtrfs.infを右クリックしてインストールを選択するだけです。

# 使用方法
ディスクのフォーマット以外はGUI環境で行うことが可能です。今回は物理ディスク上ではなく、VHD上にbtrfsファイルシステムを作成して動作を確認します。

## 前準備 (VHDの作成)
スタートメニューのWindowsアイコンを右クリックして「ディスクの管理」を開きます。次に「操作(A)」→「VHDの作成」をクリックし、ダイアログに従い適当なサイズのイメージを作成します。

VHDの作成が完了したら続いて適当にパーティションを作成します。今回は2つパーティションを用意します。

![disk-manage.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/33102ad2-0c7c-7b35-87e1-4718a096167b.png)


## フォーマット
GUI環境からフォーマットを行うことはできないため、CLI上で行います。PowerShellを管理者として開いた後、

```
format /fs:btrfs E: (E:の部分はフォーマットしたいドライブ名)
```

でフォーマットを行います。またはダウンロードしたフォルダの中にあるmkbtrfsを用いて、

```
mkbtrfs E:
```

とします。mkbtrfsを使用した場合はセクタサイズ等をオプションで変更できます。

なおlinuxのmkfs.btrfsではmkfs時にマルチデバイスを指定することが可能ですが、WinBtrfsではできないようです。

## ディスクプロファイル/容量の確認
フォーマット以外の操作はすべてGUI環境から行うことができます。フォルダからフォーマットしたディスクを選択し、プロパティを開くと「Btrfs」というタブが確認できます。

![disk-property1.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/9b674bfb-f4c2-7dad-8761-797a362f651d.png)

項目中の「Show usage」をクリックすると、linuxでのbtrfsユーザーツールである、btrfs-progsの"filesystem usage"に対応する情報が表示されます。
![disk-property2.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/567f5fe0-c15d-4e34-fa5c-7df35e3ec8c0.png)

linuxのmkfs.btrfsでシングルデバイスを指定してデフォルトでフォーマットしたときと同様に、dataはsingle, metadata/systemはdupにフォーマットされています。

## デバイスの追加
次に「Devices」をクリックすると、ファイルシステムを構成するデバイスの一覧が表示されます。
![disk-property3.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/c9ad6d60-e831-b097-c44c-ef21728b8808.png)

デバイスを追加するために「Add Device」を選択し、追加するディスクを選びます(今回はVHD上の別のパーティションを選びます)。
![disk-property4.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/28a883b4-e3b8-c7d8-e384-7635e757db0d.png)

## balance/convert
ディスクが2台になったのでRAID0/1にプロファイルを変更します。

「Balance」を選択すると次のダイアログが表示されます。
![disk-property5.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/7d82b784-8830-dc34-9e47-2313f16dcc39.png)

「Data」を選択し、オプションダイアログでProfilesに「Single」, convertに「RAID0」を選択します。
![disk-property6.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/a2964788-14e7-f602-8078-c64c537c8bf5.png)
同様に「Metadata/System」は「Dup」/「RAID1」を選択し、OKを押してbalanceを開始します。

終了後再び「Show usage」を選択すると、プロファイルが変更されていることが確認できます。
![disk-property7.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/c2423cdc-e23a-5b4a-7923-4a5a9be5b185.png)

## scrub
「Scrub」を選択するとファイルシステム上のメタデータ/データに破損がないかをチェックし、可能な場合は修復を行います。

## subvolumeの操作
### subvolume作成
右クリックから新しいフォルダを作る感覚で新しいsubvolumeを作ることができます。
![op1.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/7e15d170-291f-6a51-fa96-16e9eede2203.png)

### subvolume削除
通常のファイルやフォルダのように削除でき、デフォルトではごみ箱の中に入ります。

### propertyの確認
フォルダ(subvolume)やファイルを右クリックしてプロパティを確認すると、「btrfs properties」のタブがあります。ここからread onlyの設定や透過圧縮の設定を行うことができます。
![op2.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/d0f75654-7a6d-b5c8-dfe9-4b6fe175027a.png)

ここで「Details」を選択すると、ディスク上のサイズが表示されます。透過圧縮を有効にしている場合は圧縮後のサイズが分かります。
![op3.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/60138977-08f4-f5e3-9bee-ec4f3dd6e53f.png)

### snapshot作成
subvolumeを右クリックして「Create Snapshot」を選択すると、同じフォルダ上にsnapshotが作成されます。
![op5.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/4643b52f-868c-3058-7b8a-6c5c4658d520.png)

### send/receive
sendを行うためにはsubvolumeがread onlyである必要があります。先ほどのプロパティの画面を開き、「Readonly Subvolume」にチェックを入れます。続いて右クリックのメニューからから「Send subvolume」を選択します。表示されるダイアログでsend streamの保存先や、parent/clone subvolumeを選択し、「Write」を押すとsend streamが作成されます。
![op7.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/03b8781f-49c8-c09a-793a-2f50d0376d67.png)

ストリームのreceiveを行うためにはフォルダの好きなところで右クリックし、「Receive Subvolume」からsend streamを選択します。sendしたものと同じ名前/内容のsubvolumeが作成されます。
![op8.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/0f5403f6-df32-02e9-d650-bf00fd8a3431.png)

## reflink copy
ファイルのコピー/貼り付けを行う際に、右クリックから「Reflink Paste」を選択することができます。
![op4.PNG](https://qiita-image-store.s3.amazonaws.com/0/241792/f3c46eae-6f24-91d6-2f51-e844c3384305.png)

# WindowsでフォーマットしたFSをLinuxでマウント
次にWinBtrfsのmkbtrfsでフォーマットしたファイルシステムがLinuxで読み込めるのかを確認します。

まず「ディスクの管理」からVHDを切断します。つぎに適当なLinuxをVM上にインストールし、作成したVHDをストレージに接続して起動します。今回はArchLinux(kernel 4.15.6/btrfs-progs 4.15.1)を使用します。

以下のように無事にマウントができ、プロファイルやsubvolumeの一覧を確認することができました。

```
$ sudo mount /dev/sdb2 /mnt

$ sudo btrfs filesystem usage /mnt
Overall:
    Device size:		  24.87GiB
    Device allocated:		   2.56GiB
    Device unallocated:		  22.31GiB
    Device missing:		     0.00B
    Used:			   1.16MiB
    Free (estimated):		  24.31GiB	(min: 13.15GiB)
    Data ratio:			      1.00
    Metadata ratio:		      2.00
    Global reserve:		  16.00MiB	(used: 0.00B)

Data,RAID0: Size:2.00GiB, Used:832.00KiB
   /dev/sdb2	   1.00GiB
   /dev/sdb3	   1.00GiB

Metadata,RAID1: Size:256.00MiB, Used:160.00KiB
   /dev/sdb2	 256.00MiB
   /dev/sdb3	 256.00MiB

System,RAID1: Size:32.00MiB, Used:16.00KiB
   /dev/sdb2	  32.00MiB
   /dev/sdb3	  32.00MiB

Unallocated:
   /dev/sdb2	   8.48GiB
   /dev/sdb3	  13.83GiB

$ sudo btrfs subvolume list /mnt
ID 265 gen 33 top level 5 path New subvolume
ID 266 gen 21 top level 5 path Snapshot of New subvolume (2018-03-03)
ID 268 gen 29 top level 5 path receive/Snapshot of New subvolume (2018-03-03)
```


# LinuxでフォーマットしたFSをWindowsでマウント
これまでとは逆にlinuxのmkfs.btrfsでフォーマットしたファイルシステムがWindowsで認識できるのかについても試してみましたが、無事に認識できました。

# 問題点
ここまではよかったのですが、Windowsでマウント⇔Linuxでマウントのやり取りを数回行うと、高確率でWindowsでVHDの接続ができずにフリーズしました。理由は不明ですが、物理ディスクを使用する場合は問題ないのかもしれません。

# 機能比較
ざっと見たところ、WinBtrfsとlinuxのbtrfsには機能面で以下のような違いがあります。

winbtrfsが対応していない機能:

- defrag
- qgroup
- seed device
- device replace
- zstd compression

ユーザーツールの機能がbtrfs-progsと違う点:

- 一般ユーザーでもsubvolumeの削除が可能
- subvolumeの中にsubvolumeが含まれていても削除可能
- 圧縮後のファイルサイズの確認が可能
- sub list/showや各種オフラインツール(check/restore/rescue/inspect-internal)に対応するコマンドがない

とは言うものの、機能面ではかなりの部分がすでに実装されていると思います。

# おわりに
安定性/性能については測定していないため実用に耐えうるのかは不明ですが、そもそもここまで動くと思っていなかったというのが正直な感想です。操作に関するドキュメントはほぼありませんが、GUIからの操作はlinuxでの操作が分かっている人ならば問題なく行えると思います。また、CLIでの操作方法はREADMEに書いてあります。ただしすべてのコマンドが実行できない上、エラーが発生したか分からないということなので、CLIだけで操作を行うのは厳しいでしょう。

何らかの理由でWindowsにbtrfsファイルシステムをマウントして中身を確認したい場合は試してみても良いかもしれません。