그냥 사는 이야기

FUA (Force Unit Access) 관련 본문

Development/System

FUA (Force Unit Access) 관련

없다캐라 2021. 2. 2. 12:24
반응형

What is Forced Unit Access (FUA)?

FUA란 write 명령을 직접 스토리지에 사용하는 것을 말하며 디스크 캐시 사용 여부와는 관계 없습니다.

SCSI T10스펙에서 처음 나왔으며,(WRITE DMA FUA EXT 3Dh, WRITE DMA QUEUED FUA EXT 3Eh, WRITE MULTIPLE FUA EXT CEh) 와 같은 SCSI 명령어들이 있습니다.

FUA는 디스크 미디어에 직접 쓰기가 마무리 되어야 하므로 flush 같은 명령이 떨어지기 전에 파워문제가 발생해도 data에 consistent를 보장할 수 있습니다.

SCSI에서 나온 스펙이지만 이 후에 ATA T7(2002)스펙에도 포함 되었습니다. (이상 위키내용 발췌)

Windows

윈도우즈에서는 Transactional NTFS(이하 TxF)에서 SCSI, Fiber Channel 장비의 경우는 지원합니다. 그 외 (ATA/SATA/USB) 에선 지원이 안되기에 power failure 문제에 위험성을 가지고 있기에 캐시 disable 같은 다른 대안을 사용해야 합니다.

Disk Cache Disabling

디스크 장치에 대한 cache disable을 하기 위해서는 DeviceIOControl의 아래 code를 사용하여 정할 수 있습니다.

MSDNQuerying for the Write Cache Property에서 살펴볼 수 있습니다.

ATA스펙에 FUA가 포함되었지만 그것이 제대로 구현되었는지 gurantee 되지 않아서 Windows 에서는 채용하지 않았으며 SATA 같은 디스크에서 지원하지 않습니다.

NTFS에서는 SCSI 경우 meta data의 integrity를 지켜주기 위해 FUA가 사용됩니다. 그 외의 데이터 영역이 FUA 사용에 대한 것은 기능이 support 된다고 하는데 어떻게 사용하는지는 확인 할 수 없습니다.

Transactional 이란 용어에서 meta를 의식한 표현으로 짐작되며 meta는 확실히 FUA를 쓴다고는 하는데 data 부분에 대한 write는 찾지 못했습니다.

그리고 MSDN에서는 TxF를 대체할 수 있는 방법을 찾으라고 강력하게 권장하는데 TxF의 API들이 강력하지만 복잡해서 deprecating시키는 것을 고려중이기에 다른 시나리오를 권고하고 있습니다. (Alternatives to using Transactional NTFS)

TxF에서 FUA 사용한다는데 TxF를 안쓰면??? 거기까진 언급되지 않아서 알수 없습니다.

하지만, Windows 8, Windows Server 2012 부터는 metadata에 대한 FUA를 사용하지 않고 대신 캐시를 사용하여 바로 flush 시키는 방식으로 변경하였다고 합니다.

그 내용은 Windows Server 2012 64TB NTFS Volumes and the Flush CommandWindows Server 2012 64TB NTFS Volumes and the Flush Command 문서에서 확인할 수 있습니다.

FUA 구현을 직접적으로 하기 위해서는 User layer에서는 FILE_FLAG_NO_BUFFERINGFILE_FLAG_WRITE_THROUGH 플래그가 있는 write를 구현하면 됩니다.

커널 드라이버에서는 file system, volume 단에서는 IRP_MJ_WRITE의 IRP Stack Location의 Flags에서 SL_WRITE_THROUGH | SL_FT_SEQUENTIAL_WRITE 을 추가시켜주면 됩니다.

SL_WRITE_THROUGH 은 밑의 linux에서 request io의 REQ_FUA와 같은 거라고 보여집니다.

SL_FT_SEQUENTIAL_WRITE은 FT에서 사용하는 값 같은데 정확히 무엇인지는 모르겠다(OSR 참조). 다만, 2개를 같이 묶어서 사용하는 것 같습니다.

Linux

리눅스에서는 이런 FUA가 block layer lever에서 지원 됩니다.

SATA 같은 경우는 2007년 즈음 Linux가 NCQ를 지원했고 이런 SATA/NCQ 에 대한 FUA 기능은 2012까지는 안되었습니다.

리눅스 커널 코드에서는

#define REQ_FUA         (1ULL << __REQ_FUA)

file system 단에서는 bio의 r/w flag에 매스킹 시켜 FUA를 요청할 수 있으며 실 구현은 block device 밑단에서 FUA 관련 기능이 구현되어 있습니다.

물론 이것은 FUA가 지원되는 device에 한하며 그렇지 못한 경우는 Linux 3.14 kernel document 중 writeback_cache_control.txt 를 보면 마지막에

If the FUA bit is not natively supported the block layer turns it into an empty REQ_FLUSH request after the actual write.

write이후 FLUSH를 연이어 요청하여 비슷한 동작을 하게끔 한 것 같습니다. 물론 거기에 대한 payload를 지불할 만하면....

Reference

Comments