다음을 통해 공유


oplock 요청 및 부여

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

Oplock은FSCTL을 통해 요청됩니다. 다음 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 반환합니다. 이러한 이유로 oplock은 동기 I/O에 대해 부여되지 않습니다. FSCTL IRP는 oplock이 끊어질 때까지 완료되지 않습니다.

oplock을 부여할 수 없는 경우 파일 시스템에서 적절한 오류 코드가 반환됩니다. 가장 일반적으로 반환되는 오류 코드는 STATUS_OPLOCK_NOT_GRANTED 및 STATUS_INVALID_PARAMETER(및 해당 사용자 모드 유사체)입니다.

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

  1. FILE_READ_ATTRIBUTES 필요한 액세스 권한과 공유 모드의 FILE_SHARE_READ | 파일을 엽니다. FILE_SHARE_WRITE | FILE_SHARE_DELETE.

  2. 1단계에서 핸들에 대한 필터 oplock을 요청합니다.

  3. 읽기 액세스를 위해 파일을 다시 엽니다.

1단계에서 열린 핸들은 데이터 액세스(FILE_READ_DATA)가 아닌 특성 액세스(FILE_READ_ATTRIBUTES)에 대해서만 열려 있기 때문에 다른 애플리케이션에서 공유 위반을 수신하지 않습니다. 이 핸들은 필터 oplock을 요청하는 데 적합하지만 데이터 스트림에서 실제 I/O를 수행하는 데는 적합하지 않습니다. 3단계에서 열린 핸들을 사용하면 oplock의 소유자가 스트림에서 I/O를 수행할 수 있습니다. 2단계에서 부여된 oplock을 사용하면 oplock의 소유자가 스트림에 액세스하려고 시도하는 다른 애플리케이션에 대한 공유 위반을 일으키지 않고 "방해가 될 수 있습니다".

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

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

요청 유형 조건

수준 1

필터

Batch

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

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리가 있으면 STATUS_INVALID_PARAMETER 반환됩니다.
  • ASYNCHRONOUS 액세스를 위해 스트림이 열립니다.
    • 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 반환됩니다.
  • ASYNCHRONOUS 액세스를 위해 스트림이 열립니다.
    • SYNCHRONOUS 액세스를 위해 열면 STATUS_OPLOCK_NOT_GRANTED 반환됩니다.
  • 파일에 TxF 트랜잭션이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 반환됩니다.
  • 스트림에 현재 바이트 범위 잠금이 없습니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 반환됩니다.
    • Windows 7 이전에는 운영 체제가 마지막으로 열린 이후 스트림에 바이트 범위 잠금이 있는지 확인하고, 이 경우 요청에 실패합니다.

현재 oplock 상태가 인 경우:

  • oplock 없음: 요청이 부여됩니다.

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

읽기

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

  • 요청은 지정된 파일 스트림에 대한 것입니다.
  • ASYNCHRONOUS 액세스를 위해 스트림이 열립니다.
    • 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

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

  • 요청은 지정된 파일 스트림에 대한 것입니다.
  • ASYNCHRONOUS 액세스를 위해 스트림이 열립니다.
    • 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 반환됩니다.

읽기-쓰기

다음 조건이 모두 true인 경우에만 부여됩니다.

  • 요청은 지정된 파일 스트림에 대한 것입니다.
    • 디렉터리인 경우 STATUS_INVALID_PARAMETER 반환됩니다.
  • ASYNCHRONOUS 액세스를 위해 스트림이 열립니다.
    • 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 반환됩니다.

읽기-쓰기-핸들

다음이 모두 true인 경우에만 부여됩니다.

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

현재 oplock 상태가 인 경우:

  • oplock 없음: 요청이 부여됩니다.

  • 읽기, 읽기-핸들, 읽기-쓰기 또는 읽기-쓰기-핸들 및 기존 oplock에는 요청과 동일한 oplock 키가 있습니다. 기존 oplock의 IRP는 STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE 완료되고 요청이 부여됩니다.
    • 그렇지 않으면 STATUS_OPLOCK_NOT_GRANTED 반환됩니다.
  • 수준 2, 수준 1, 일괄 처리, 필터: STATUS_OPLOCK_NOT_GRANTED 반환됩니다.

참고

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