OSSCA Chromium

기여 목록 / 8361809

FSA: Preserve target types for ancestor inotify moves

ContentfixMerged
  • 문제: 상위 디렉터리가 이동하면 감시 중인 하위 파일이 디렉터리로 잘못 보고되었습니다.
  • 해결: 변경 경로와 타입을 함께 반환하고, 감시 대상의 변경 전후 타입을 추적하도록 수정했습니다.
  • 결과: 상위 경로 이동과 대상 교체 시 올바른 타입을 전달하며, 심볼릭 링크를 파일로 취급하는 기존 규칙을 유지합니다.

문제 설명

inotify가 상위 디렉터리의 이동을 알리면 FilePathWatcher는 감시 중인 하위 경로에 대한 변경 알림을 생성합니다. 기존 구현은 알림에 담을 경로를 하위 경로로 바꾸면서도 타입에는 상위 디렉터리의 타입을 그대로 사용하여, 실제로는 파일인 감시 대상을 디렉터리로 보고했습니다.

상위 디렉터리가 이동해 대상 경로가 사라진 뒤에는 파일 시스템에서 기존 타입을 다시 조회하기 어렵습니다. 또한 같은 경로에 파일 대신 디렉터리가 새로 들어오는 경우에는 저장된 타입을 갱신해야 이후 알림도 올바르게 분류할 수 있습니다.

심볼릭 링크도 별도 처리가 필요합니다. FilePathWatcher는 경로의 마지막 구성 요소가 심볼릭 링크이면 이를 kFile로 표현합니다. 끊어진 링크의 대상이 나중에 생성될 때, 그 대상이 디렉터리라는 이유로 감시 중인 링크까지 kDirectory로 보고해서는 안 됩니다.

해결 내용

  1. 변경 경로와 타입을 함께 반환

    file_path_watcher_inotify.cc에 ChangeProcessResult를 추가하여 FindChangedPathAndUpdateWatches()가 변경 경로와 해당 경로의 타입을 함께 반환하도록 했습니다. 일반 이벤트와 이동 이벤트 콜백 모두 이 결과를 사용해 ChangeInfo를 구성합니다.

    struct ChangeProcessResult {
      base::FilePath changed_path;
      FilePathWatcher::FilePathType file_path_type;
    };
  2. 감시 대상 타입의 변경 전후 상태 추적

    감시 시작 시 target_path_type_을 초기화하고, 감시 정보를 갱신하기 전에 이전 타입을 저장합니다. 상위 경로 이동으로 대상이 사라진 경우에는 변경 전 타입을 사용하고, 대상이 다시 나타나면 갱신된 타입을 사용합니다. 삭제 시 저장 상태는 kUnknown으로 초기화합니다.

    리뷰에서는 삭제 후에도 이전 타입을 계속 보관한다는 인상을 주지 않도록 상태 이름을 target_path_type_으로 정리했습니다.

  3. 심볼릭 링크의 타입 규칙 유지

    GetFilePathType()은 base::File::Lstat()으로 경로의 타입을 조회합니다. 마지막 심볼릭 링크를 따라가지 않으므로 디렉터리를 가리키는 링크도 kFile로 분류합니다.

    끊어진 링크를 감시할 때는 링크 대상의 부모 디렉터리에서 발생한 이벤트인지 구분합니다. 링크 대상이 생성되더라도 알림은 감시 중인 링크 자체의 타입으로 구성합니다.

  4. 이벤트 누락 수정 분리

    초기 CQ 조사 중 다루었던 읽기 버퍼 경계의 이동 이벤트 누락 수정은 리뷰 요청에 따라 CL 8395074로 분리했습니다. 이 CL은 대상 타입 수정에 집중했으며, 선행 CL 병합 후 Patch Set 8을 main 위로 리베이스했습니다.

테스트 방법

file_path_watcher_unittest.cc에서 기존 이동 테스트의 기대 타입을 바로잡고 회귀 테스트 두 개를 추가했습니다.

테스트 또는 변경 검증 내용
IsMovedFile 기대값 수정 기존의 IsDirectory를 IsFile로 변경하여 파일 이동을 올바른 타입으로 검증하고 관련 TODO를 제거했습니다.
MoveParentWithTargetTypeChanged 상위 디렉터리 이동 시 파일 삭제 알림을 확인하고, 같은 경로를 디렉터리로 교체한 뒤 디렉터리 생성·삭제 알림이 올바른 타입으로 전달되는지 검증합니다.
CreateTargetLinkedDirectoryAndMoveParent 끊어진 링크의 대상 디렉터리를 생성한 뒤 링크의 부모를 이동시켜, 링크에 대한 생성·삭제 알림이 모두 파일 타입인지 검증합니다.

Gerrit 기록상 Patch Set 2에서는 MoveParentWithTargetTypeChanged/1의 간헐적 실패가 보고되었습니다. 이후 Patch Set 3과 이벤트 누락 수정 분리 후의 Patch Set 6은 CQ dry run을 통과했습니다. 이 이력만으로 초기 실패의 원인이 읽기 버퍼 경계 문제였다고 단정하지는 않습니다.

2026년 9월 22일 확인 시점에는 Patch Set 8에 코드 리뷰 승인 두 건과 Commit-Queue +2가 유지되어 있으며, 리베이스 후 CQ full run이 진행 중입니다. 최종 병합 완료 결과는 아직 확인되지 않았습니다. 위 내용은 패치와 Gerrit 기록을 기준으로 정리했으며, 보고서 작성 과정에서 Chromium 테스트를 별도로 실행하지는 않았습니다.

배운 점

  • 변경 알림의 경로와 타입은 같은 대상을 설명해야 하므로, 두 정보를 함께 반환하면 상위 이벤트의 타입을 잘못 재사용하는 실수를 줄일 수 있습니다.
  • 삭제나 이동 후에는 기존 경로를 조회할 수 없으므로, 변경 전 상태를 보관하는 시점과 변경 후 상태를 갱신하는 시점을 구분해야 합니다.
  • 심볼릭 링크 자체의 타입과 링크 대상의 타입은 다르며, lstat()을 사용하면 기존 알림 규칙에 맞게 마지막 링크를 분류할 수 있습니다.
  • 서로 다른 원인의 수정은 CL을 나누고 각각 회귀 테스트를 두면 변경 목적과 검증 범위를 명확하게 설명할 수 있습니다.

참고 자료