목록 보기
zfs userspace와 zfs create 사이의 EBUSY 레이스 수정
백엔드

zfs userspace와 zfs create 사이의 EBUSY 레이스 수정

글루시스
글루시스
2026년 6월 24일

두줄요약

OpenZFS의 `zfs userspace`와 `zfs create`가 `ds_owner`에서 충돌해 `EBUSY`가 발생하는 레이스를 분석했습니다. 조회 경로를 `hold()` 기반으로 분리하고 잠금 순서를 조정해 업스트림 패치까지 반영했습니다.

문제 상황

  • OpenZFS 기반 스토리지에서 zfs create 직후 자동 마운트가 간헐적으로 mountpoint or dataset is busy로 실패하는 레이스
  • 모니터링 데몬의 zfs userspace 조회가 같은 dataset을 먼저 잡아 EBUSY를 유발하는 충돌
  • 실패 시 dataset은 생성만 되고 마운트되지 않은 orphan 상태로 남는 문제

원인 분석

  • zfs userspace와 zfs create가 모두 dmu_objset_own()으로 ds_owner를 선점하는 구조
  • 조회 연산임에도 마운트 경로와 같은 배타적 소유권을 요구해 충돌 발생
  • z_teardown_lock, dp_config_rwlock, ds_owner 중 실제 레이스는 ds_owner에서 발생

해결 방법

  • 조회 경로를 dmu_objset_own() 대신 dmu_objset_hold() 기반의 zfsvfs_create_hold()로 분리
  • zfsvfs_hold()와 zfsvfs_rele()에 z_use_hold 분기를 넣어 hold/own 경로를 구분
  • dmu_objset_hold()의 config lock 유지로 생긴 ABBA 교착을 피하기 위해 teardown 전에 config lock 해제

주의할 점

  • dmu_objset_hold()는 객체셋 타입을 자동 확인하지 않아 DMU_OST_ZFS 가드가 필요
  • ds_owner를 release 경로 분기 조건으로 직접 읽으면 레이스가 생길 수 있음
  • hold 전환은 단순 대체가 아니라 잠금 순서까지 함께 점검해야 함

적용해볼 점

  • 조회 전용 경로와 배타적 변경 경로를 분리해 락 요구사항을 최소화
  • 새로운 hold/rele 경로 도입 시 기존 잠금 순서와 교착 가능성 검증
  • 레이스 재현용 테스트를 반복 실행 형태로 추가해 회귀 방지

다음 읽기

#ZFS 주제를 이어서 읽기

Lustre의 파일 create & open 과정 분석 - 2

Lustre에서 파일 create/open이 MDS와 클라이언트에서 어떻게 이어지는지 단계별로 분석했습니다. 디버그 로그와 lfs getstripe, zdb로 OST 선택과 실제 저장 위치를 확인하는 방법도 정리했습니다.

글루시스
글루시스
백엔드

댓글 0개

댓글을 작성하려면 로그인이 필요합니다.

댓글을 불러오는 중...