rename()을 사용하여 기존 파일을 교체할 때 fsync()가 충돌로부터 안전해야 하는 파일 시스템은 무엇입니까?

rename()을 사용하여 기존 파일을 교체할 때 fsync()가 충돌로부터 안전해야 하는 파일 시스템은 무엇입니까?

auto_da_alloc광범위한 불만이 제기된 후 ext4는 기본적으로 충돌 안전 보장을 활성화했습니다. 다른 파일 시스템은 어떻습니까? 가장 잘 알려진 파일 시스템 중에서 동일한 보장을 제공하는 파일 시스템과 제공하지 않는 파일 시스템은 무엇입니까?

개인적으로 나는 다음에 대해 듣고 싶습니다.

  • XFS - Red Hat Enterprise Linux 기본 파일 시스템입니다.
  • btrfs - SuSE Enterprise 기본 파일 시스템입니다.
  • bcachefs- bcache에서 파생된 트리 외부 Linux 파일 시스템입니다. "Linux의 COW 파일 시스템은 데이터를 차지하지 않습니다."

아래 기록을 바탕으로 이 질문은 주로 Linux에 관한 것입니다. ZFS가 어떻게 동작하는지 보는 것도 흥미로울 것입니다. 그러나 저는 ZFS가 이를 구현하지 않을 것이라고 가정하고 싶습니다.

무엇인가요 auto_da_alloc?

fsync()는 텍스트 편집기에서 "저장"을 누를 때와 같이 파일 데이터를 쓰는 올바른 방법으로 잘 문서화되어 있습니다. 예를 들어, 텍스트 편집기는 기존 파일을 원자적으로 교체하기 위해 rename()을 사용해야 한다는 것이 일반적으로 받아들여집니다. 이는 정전을 방지하고 항상 오래된 파일을 유지하거나 새 파일을 가져오도록 하기 위한 것입니다(이름을 바꾸기 전에 fsync()됨). 새 파일의 절반만 작성된 버전만 남기고 싶지는 않을 것입니다.

그러나 가장 널리 사용되는 Linux 파일 시스템인 ext3에서 fsync()를 호출하면 전체 시스템이 수십 초 동안 중단될 수 있다는 문제가 있습니다. 애플리케이션이 이에 대해 할 수 있는 일이 없기 때문에 fsync() 대신 rename()을 낙관적으로 사용하는 것이 일반적입니다. 이 모드는 시스템의 전원이 꺼진 경우에도 이 파일 시스템에서 합리적으로 잘 작동하는 것 같습니다.

따라서 fsync()를 올바르게 사용하지 않는 응용 프로그램이 있습니다.

파일 시스템의 다음 버전인 ext4는 일반적으로 fsync() 중단을 방지합니다. 동시에 fsync()의 올바른 사용에 더 의존하기 시작했습니다.

다 나쁘다. 논란의 여지가 있지만, 많은 충돌하는 커널 개발자가 사용하는 무시하는 문구는 이 역사를 이해하는 데 도움이 되지 않습니다.

이 문제는 ext4에서 해결되었습니다.충돌 안전을 위해 fsync() 없이 rename() 모드를 지원합니다.이전 ext3 파일 시스템과 동일한 충돌 동작을 제공합니다. 옵션을 사용하여 마운트하면 이 동작을 다시 비활성화할 수 있습니다 noauto_da_alloc.

답변1

이 질문에는 버그가 있습니다. 이 질문은 시나리오가 다음과 같다는 것을 의미합니다.완전히충돌 안전 auto_da_alloc. ext4에서는 그렇지 않습니다. 나는 이것이 오래된 ext3에서도 마찬가지라고 생각하지 않습니다. 그러나 그것은이는 btrfs와 bachefs 모두에 해당됩니다.

최근 ext4에는 이름 바꾸기 시 새 데이터 블록을 강제로 삭제하여 이름 바꾸기 대체를 통해 길이가 0인 파일을 생성할 가능성을 줄이는 특별한 해결 방법이 있습니다. 그러나 이름 바꾸기는 새로 고침이 완료될 때까지 기다리지 않으므로 원자성이 보장되지 않습니다. 충돌 후에는 부분적인 새 콘텐츠만 얻을 수 있습니다. 우리가 테스트한 파일 시스템 중에서 btrfs는 이름 바꾸기에 의한 교체 원자성을 보장하는 유일한 시스템입니다.

https://homes.cs.washington.edu/~lijl/papers/ferrite-asplos16.pdf


우수한 btrfs,문서rename()을 사용하여 파일을 바꾸면 완전한 원자성이 제공되며 데이터 손상을 방지하기 위해 명시적인 fsync()가 필요하지 않음을 나타냅니다. 이거 추가된거 같은데ext4와 거의 같은 시기auto_da_alloc. 또한 btrfs 구현은 rename() 호출을 기다리지 않기 때문에 성능 저하를 방지한다는 주장도 확인했습니다. 하지만 최근 커널에서는 적어도 fsync()를 사용하면 다음 rename()이fsync() 상위 디렉토리를 호출하고 전체 "로그 ​​트리"가 기록될 때까지 기다립니다..

bcachefs현재 문서를 찾을 수 없지만 완전한 보호가 있는 것 같습니다. 코드를 확인하세요. "filemap_write_and_wait_range" 함수에 대한 호출이 보입니다.

XFS가지다거부하다rename()에 대한 충돌 방지 해결 방법을 추가합니다. 다양한 시나리오에서 데이터 손실 위험을 줄이는(제거하지는 않지만) 코드를 얻는 것으로 보입니다.

UBIFS(예: 많은 Openwrt 장치에서 사용됨) rename()에 대한 충돌로부터 안전한 해결 방법은 포함되어 있지 않습니다. 받아들일 수는 있지만 많은 노력이 필요합니다. http://www.linux-mtd.infradead.org/doc/ubifs.html#L_sync_Exceptionions

관련 정보