다음을 통해 공유


oplock 요청 및 부여

네트워크 리다이렉터에서 원격 서버의 파일에 액세스하면 원격 서버에서 oplock을 요청합니다. 클라이언트 애플리케이션은 잠금이 로컬 서버의 파일에 대한 경우에만 oplock을 직접 요청합니다.

oplocksFSCTL을 통해 요청됩니다. 다음 FSCTL은 사용자 모드 애플리케이션과 커널 모드 드라이버가 모두 실행할 수 있는 다양한 oplock 형식의에 사용됩니다.

사용자 모드에서 Windows 7 oplock을 요청하려면 DeviceIoControl호출합니다.

비슷한 방식으로 커널 모드에서 Windows 7 oplock을 요청하려면 다음을 수행합니다.

필요한 4개의 Windows 7 oplock 중 하나를 지정하려면 REQUEST_OPLOCK_INPUT_BUFFER 구조체의 RequestedOplockLevel 멤버에서 다음 플래그 중 하나 이상을 설정합니다.

  • OPLOCK_LEVEL_CACHE_READ (읽기 캐시 잠금 수준)
  • OPLOCK_LEVEL_CACHE_HANDLE
  • OPLOCK_LEVEL_CACHE_WRITE

자세한 내용을 보려면 FSCTL_REQUEST_OPLOCK참조하십시오.

요청된 oplock을 부여할 수 있으면 파일 시스템은 STATUS_PENDING 상태를 반환합니다. 이러한 이유로, 동기 I/O에는 oplock이 절대 설정되지 않습니다. FSCTL IRP는 oplock이 깨질 때까지 완료되지 않습니다.

oplock을 부여할 수 없는 경우 파일 시스템에서 적절한 오류 코드가 반환됩니다. 주로 반환되는 오류 코드는 STATUS_OPLOCK_NOT_GRANTED 및 STATUS_INVALID_PARAMETER(그리고 이와 동등한 사용자 모드 버전)입니다.

필터 oplock을 사용하면 다른 애플리케이션/클라이언트가 동일한 스트림에 액세스하려고 할 때 애플리케이션이 "백아웃"할 수 있습니다. 이 메커니즘을 사용하면 스트림을 열려고 할 때 다른 스트림 접근자가 공유 위반을 수신하지 않고도 애플리케이션이 스트림에 액세스할 수 있습니다. 공유 위반을 방지하려면, 필터 oplock(FSCTL_REQUEST_FILTER_OPLOCK)을 요청하기 위해 다음의 3단계 절차를 따라야 합니다.

  1. 파일을 여는 데 요구되는 액세스 권한은 FILE_READ_ATTRIBUTES이며, 공유 모드는 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE입니다. 이 단계에서 열린 핸들은 데이터 액세스(FILE_READ_DATA)가 아닌 특성 액세스(FILE_READ_ATTRIBUTES)에 대해서만 열려 있으므로 다른 애플리케이션에서 공유 위반을 수신하지 않습니다. 이 핸들은 필터 잠금 요청에는 적합하지만, 데이터 스트림에서 실제 I/O를 수행하는 데는 적합하지 않습니다.

  2. 1단계에서 핸들에 필터 Oplock(옵록)을 요청합니다. 이 단계에서 부여된 oplock을 통해 oplock 소유자가 스트림에 액세스하려고 시도하는 다른 애플리케이션에 공유 위반을 일으키지 않도록 방해를 피할 수 있습니다.

  3. 읽기 액세스를 위해 파일을 다시 엽니다. 이 단계에서 핸들이 열리면 oplock 홀더가 스트림에서 I/O를 수행할 수 있습니다.

NTFS 파일 시스템은 FILE_RESERVE_OPFILTER 만들기 옵션 플래그를 통해 이 절차에 대한 최적화를 제공합니다. 이 플래그를 이전 절차의 1단계에서 지정하면 파일 시스템이 2단계가 실패할 것이라고 판단할 수 있는 경우 STATUS_OPLOCK_NOT_GRANTED로 만들어 요청을 실패시킬 수 있습니다. 1단계가 성공하면 만들기 요청에 대해 FILE_RESERVE_OPFILTER 지정되었더라도 2단계가 성공한다는 보장은 없습니다.

다음 표에서는 oplock을 부여하는 데 필요한 조건을 식별합니다.

요청 유형 여건

수준 1

필터

일괄

다음 조건이 모두 충족되는 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리인 경우 STATUS_INVALID_PARAMETER 반환됩니다.
  • 비동기적 액세스를 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스로 열 경우, STATUS_OPLOCK_NOT_GRANTED가 반환됩니다(동기 I/O 요청에 대해 oplock이 부여되지 않습니다).
  • 파일 스트림에는 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 스트림에 다른 열기가 없습니다(동일한 스레드에서도).
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

현재 oplock 상태가 다음과 같은 경우:

  • Oplock이 없을 경우: 요청이 승인되었습니다.

  • 수준 2: 원래 수준 2 요청이 FILE_OPLOCK_BROKEN_TO_NONE으로 손실되었습니다. 그런 다음 요청된 배타적 oplock이 부여됩니다.

  • 수준 1, 일괄 처리, 필터, 읽기, 읽기-핸들, 읽기-쓰기 또는 읽기-쓰기-핸들에서는 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

수준 2

다음 조건이 모두 충족되는 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리인 경우 STATUS_INVALID_PARAMETER 반환됩니다.
  • 비동기 액세스를 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스를 위해 열린 경우 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 스트림에 현재 바이트 범위 잠금이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
    • Windows 7 이전에는 운영 체제가 마지막으로 열렸을 때부터 스트림에 바이트 범위 잠금이 존재했는지를 확인하고, 존재할 경우 요청을 실패로 처리합니다.

현재 oplock 상태가 다음과 같은 경우:

  • oplock 없음: 요청이 승인되었습니다.

  • 2레벨 및/또는 읽기: 요청이 허가되었습니다. 동일한 스트림에서 동시에 여러 개의 Level 2/읽기 oplock을 부여할 수 있습니다. 여러 수준 2(읽기가 아님) oplock은 동일한 핸들에도 존재할 수 있습니다.
    • 읽기 oplock이 이미 부여된 핸들에 대해 또 다른 읽기 oplock이 요청될 경우, 두 번째 읽기 oplock이 부여되기 전에 첫 번째 읽기 oplock의 IRP는 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE로 완료됩니다.
  • 수준 1, 일괄 처리, 필터, 읽기 핸들, 읽기-쓰기, 읽기-쓰기 핸들: STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

읽다

다음 조건이 모두 충족되는 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
  • 비동기 액세스를 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스를 위해 열린 경우 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환될 것입니다.
  • 스트림에 현재 바이트 범위 잠금이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

현재 oplock 상태가 다음과 같은 경우:

  • oplock 없음: 요청이 승인되었습니다.

  • 2단계와/또는 읽기: 요청이 승인되었습니다. 동일한 스트림에서 동시에 여러 수준 2/읽기 oplock을 부여할 수 있습니다.
    • 또한 기존의 oplock에 새 요청과 동일한 oplock 키가 있는 경우, 해당 IRP는 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE로 완료됩니다.
  • Read-Handle 기존 oplock은 새 요청과 다른 oplock 키를 가지고 있습니다. 요청이 승인됩니다. 여러 읽기와 Read-Handle oplock이 동일한 스트림에서 공존할 수 있습니다(이 표 다음의 참고 사항을 참조하세요).
    • 만약 oplock 키가 동일하다면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 수준 1, 일괄 처리, 필터, 읽기-쓰기, 읽기-쓰기-핸들: STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

Read-Handle

다음 조건이 모두 충족되는 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
  • 비동기 접속을 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스를 위해 열린 경우에는 STATUS_OPLOCK_NOT_GRANTED이 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 값이 반환됩니다.
  • 스트림에 현재 바이트 범위 잠금이 없습니다.
    • 그렇지 않다면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

현재 oplock 상태가 다음과 같은 경우:

  • oplock 없음: 요청이 승인되었습니다.

  • 요청이 승인되었습니다.
    • 기존 읽기 oplock에 새 요청과 동일한 oplock 키가 있는 경우, 해당 IRP는 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE 상태 코드로 완료됩니다. 그 결과 oplock이 읽기에서 읽기-핸들로 업그레이드됩니다.
    • 새 요청과 동일한 oplock 키가 없는 기존 읽기 oplock은 변경되지 않은 상태로 유지됩니다.
  • 수준 2, 수준 1, 일괄 처리, 필터, 읽기-쓰기, 읽기-쓰기-핸들: STATUS_OPLOCK_NOT_GRANTED 반환됩니다.

Read-Write

다음 조건이 모두 충족되는 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리인 경우 STATUS_INVALID_PARAMETER 반환됩니다.
  • 비동기 액세스를 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스로 열렸을 경우, STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 반환됩니다.
  • 스트림에 다른 열기가 있는 경우(동일한 스레드에서도) 동일한 oplock 키가 있어야 합니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 값이 반환됩니다.

현재 oplock 상태가 다음과 같은 경우:

  • oplock 없음: 요청이 승인되었습니다.

  • 읽기 또는 Read-Write이 기존 oplock와 요청의 oplock 키가 동일한 경우, 기존 oplock의 IRP는 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE로 완료되며 요청이 승인됩니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED이 반환됩니다.
  • 수준 2, 수준 1, 일괄 처리, 필터, 읽기 핸들, 읽기-쓰기 핸들의 경우 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

읽기:Write-Handle

다음이 모두 true인 경우에만 허용됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리인 경우 STATUS_INVALID_PARAMETER 반환됩니다.
  • 비동기 액세스를 위해 스트림이 열립니다.
    • 동기식 액세스로 열렸을 경우, STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED이(가) 반환됩니다.
  • 스트림에 다른 열린 요청이 있을 경우, 동일한 스레드에서도 동일한 oplock 키를 사용해야 합니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED이 반환됩니다.

현재 oplock 상태가 다음과 같은 경우:

  • oplock 없음: 요청이 승인되었습니다.

  • 읽기, 읽기-핸들, 읽기-쓰기, 또는 읽기Write-Handle와 같은 작업의 경우, 기존 oplock이 요청과 동일한 oplock 키를 가집니다. 그러면 기존 oplock의 IRP가 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE로 완료되고, 요청이 승인됩니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.
  • 수준 2, 수준 1, 일괄 처리, 필터: STATUS_OPLOCK_NOT_GRANTED가 반환됩니다.

메모

읽기 및 Level 2 oplock은 동일한 스트림에서 공존할 수 있으며 읽기 및 Read-Handle oplock은 공존할 수 있지만 Level 2 및 Read-Handle oplock은 공존할 수 없습니다.