読者です 読者をやめる 読者になる 読者になる

xattr on jffs2

OSS/Linux

まだEBS(Erase Clock Summary)機能とxattrの実装で悩み中

Summaryが有効になっていると、jffs2_mark_node_obsolete()を呼び出しても、該当ノードがobsoleteであるという情報がメディア上には書き出されない。
つまり、次回マウント時のmedium-scan処理で、消したはずのノードが有効なものとして読み込まれてしまう。(少なくとも、version4.1のxattr実装では)
これを避けるには「このノードは削除されましたよ」ということを示すマーカーを書き込む処理が必要になる。

問題は2つ
1. メディアに何か書き込む処理は失敗する可能性があるので、今までは常に成功するとしていたdelete関連の処理でエラーハンドリングを行う必要がある。
2. JFFS2のガベージコレクタは、回収を行うErase-Blockを確率的に選択する。つまり、削除マーカが先にmedium上から消去されてobsoleteなノードが読み込まれてしまった場合、消したはずのxattrが復活してしまうことになる。

1. のロジック変更は頑張るしかない。つか、元々のjffs2_mark_node_obsolete()がエラーを無視していたので、エラーハンドリングを行いようがなかったというだけなので、むしろ真っ当になるというべきか。

2. に関しては、メディア上にobsoleteノードが残っている限り、削除マーカが消されないようにする工夫が必要。今までは、delete時に問答無用でjffs2_mark_node_obsolete()を呼べば済んでいたが、削除マーカにobsoleteフラグを付けるのは、メディア上に過去のバージョンのノードが残っていないことを確認してからでないといけない。

これが結構めんどい。

方法としては、xattrを参照している古いノードが存在することを示すために参照カウンタを追加し、GCがこれらのノードを回収する時に、旧バージョンであればobsoleteフラグを付けて、最新バージョンであれば別のErase-Blockに移すようにすればよい。
この時、参照カウンタが1でしかもそのノードが削除マーカであれば、そのノードは削除しても良いので、やっとobsoleteフラグを付けることができる。

うわー

まぁ、ジャーナリングらしいといえば、らしいのだが…。