oplock'ları isteme ve verme

Ağ yeniden yönlendiricisi uzak sunuculardaki dosyalara eriştiğinde, uzak sunucudan oplock'u istemektedir. İstemci uygulamaları, yalnızca kilit yerel sunucudaki bir dosyaya yönelik olduğunda doğrudan oplock isteğinde bulunur.

OplocksFSCTLs aracılığıylaistenir. Aşağıdaki FSCTL'ler, farklı oplock türleri için kullanılmaktadır ve hem kullanıcı modu uygulamaları hem de çekirdek modu sürücüleri tarafından kullanılabilir.

Kullanıcı modunda oplock isteme

Kullanıcı modunda Bir Windows 7 oplock istemek için DeviceIoControlçağrısı yapın:

Daha fazla bilgi için bkz. FSCTL_REQUEST_OPLOCK.

İstenen oplock verilebilirse, DeviceIoControl FALSE döndürür ve GetLastError ERROR_IO_PENDING döndürür. Bu nedenle, eşzamanlı G/Ç için oplock'a hiçbir zaman izin verilmez. Çakışan işlem, oplok bozulana kadar tamamlanmaz. İşlem tamamlandıktan sonra, REQUEST_OPLOCK_OUTPUT_BUFFER oplock kesintisi hakkında bilgi içerir.

Oplock verilemiyorsa, dosya sistemi uygun bir hata kodu döndürür. En sık döndürülen hata kodları ERROR_OPLOCK_NOT_GRANTED ve ERROR_INVALID_PARAMETER.

Çekirdek modunda oplock isteme

Windows 7 oplock'larını çekirdek modda istemek için:

Dosya sistemi mini filtreleri

Dosya sistemi mini filtresinin FltAllocateCallbackData kullanması ve ayrılan FLT_CALLBACK_DATA şu şekilde doldurması gerekir:

  • Iopb->MajorFunction alanını IRP_MJ_FILE_SYSETM_CONTROLolarak ayarlayın.
  • Iopb->MinorFunction alanını IRP_MN_USER_FS_REQUEST olarak ayarlayın.
  • Iopb->Parametrelerini FileSystemControl.Buffered.FsControlCode üyesini FSCTL_REQUEST_OPLOCK olarak ayarlayın.
  • Boyutu, REQUEST_OPLOCK_INPUT_BUFFER veya REQUEST_OPLOCK_OUTPUT_BUFFERdeğerlerinden daha büyük olana eşit olan bir arabellek ayırın.
    • Ayrılan FLT_CALLBACK_DATA'ın Iopb->Parameters.FileSystemControl.Buffered.SystemBuffer üyesini, bu arabelleği gösterecek şekilde ayarlayın.
    • Ayrılan FLT_CALLBACK_DATA'nin Iopb->Parameters.FileSystemControl.Buffered.InputBufferLength ve Iopb->Parameters.FileSystemControl.Buffered.OutputBufferLength alanlarını, bu arabelleğin boyutuyla eşleşecek şekilde ayarlayın.

oplock isteğini biçimlendirme hakkında bilgi için REQUEST_OPLOCK_INPUT_BUFFER yapısının belgelerine bakın.

Ardından, dosya sistemi minifiltresi, ayrılmış FLT_CALLBACK_DATA parametresini CallbackData olarak geçirerek FltPerformAsynchronousIoçağrısını gerçekleştirmelidir.

İstenen oplock verilebilirse, FltPerformAsynchronousIo çağrısı STATUS_PENDING döndürür. Bu nedenle, eşzamanlı G/Ç için oplock'a hiçbir zaman izin verilmez. İşlem, oplock bozulana kadar tamamlanmaz. İşlem tamamlandıktan sonra, REQUEST_OPLOCK_OUTPUT_BUFFER oplock kesintisi hakkında bilgi içerir.

Oplock verilemiyorsa, dosya sistemi uygun bir hata kodu döndürür. En sık döndürülen hata kodları STATUS_OPLOCK_NOT_GRANTED ve STATUS_INVALID_PARAMETER.

Diğer Sürücü Türleri

Diğer sürücü türleri ZwFsControlFileçağırabilir:

  • FSCTL_REQUEST_OPLOCK 'ü FsControlCode olarakayarlayın.
  • Bir işaretçiyi, REQUEST_OPLOCK_INPUT_BUFFER yapısı içinde InputBuffer parametresine geçirin ve InputBufferLength parametresini bu arabelleğin boyutuna ayarlayın.
  • OutputBuffer parametresine REQUEST_OPLOCK_OUTPUT_BUFFER yapısına işaret eden bir işaretçi geçirin ve OutputBufferLength parametresini bu arabelleğin boyutuna ayarlayın.

oplock isteğini biçimlendirme hakkında bilgi için REQUEST_OPLOCK_INPUT_BUFFER yapısının belgelerine bakın.

İstenen oplock verilebilirse, ZwFsControlFile çağrısı STATUS_PENDING döndürür. Bu nedenle, eşzamanlı G/Ç için oplock'a hiçbir zaman izin verilmez. İşlem, oplock bozulana kadar tamamlanmaz. İşlem tamamlandıktan sonra, REQUEST_OPLOCK_OUTPUT_BUFFER oplock kesintisi hakkında bilgi içerir.

Oplock verilemiyorsa, dosya sistemi uygun bir hata kodu döndürür. En sık döndürülen hata kodları STATUS_OPLOCK_NOT_GRANTED ve STATUS_INVALID_PARAMETER.

Oplock İsterken Paylaşım İhlallerini Önleme

Atomic Create-With-Oplock Yöntemini Kullanma

Atomik create-with-oplock bir oplock türü değildir. Bunun yerine, açık işlemlerin dosya açma ile oplock alma arasındaki zaman aralığında paylaşım modu ihlallerine neden olmaktan kaçınmasına olanak tanıyan bir yordamdır. Eski tip oplock'larla, oplock filtrelemesi yapmak ve iki tutamacı açmak gerekir. Windows 7'deki oplock'larla, bir uygulama veya sürücü bu prosedürü kullanarak her tür oplock isteyebilir ve yalnızca bir tanıtıcı açması gerekir.

Atomik oplock ile oluşturma işlemini gerçekleştirmek için yapmanız gerekenler:

  1. Dosyayı açmak için FltCreateFileEx2 veya ZwCreateFilekullanın. CreateOptions parametresine FILE_OPEN_REQUIRING_OPLOCKbayrağını geçirin. Parametreleri istediğiniz gibi DesiredAccess ve ShareAccess olarak ayarlayabilirsiniz. Örneğin, dosyayı okuyabilmeniz için DesiredAccess parametre kümesinde GENERIC_READ ayarlayın ve dosyayı açıkken başkalarının onu okumasına, yeniden adlandırmasına ve/veya silme için işaretlemesine izin vermek için ShareAccess parametresinde FILE_SHARE_READ | FILE_SHARE_DELETE bayraklarını ayarlayın.
  2. Bir dosya nesnesi veya tanıtıcısında bir oplock istemek için FSCTL_REQUEST_OPLOCK denetim kodunu kullanın, çekirdek modunda oplock istemeyle ilgili bölümünde açıklandığı gibi.

1. ve 2. adımlar arasında dosya üzerinde herhangi bir dosya sistemi işlemi gerçekleştirmeyin. Bunu yapmak kilitlenmelere neden olabilir.

Bu yordamı kullanarak istekte bulunulacak en yaygın oplock, Read-Handle türüdür. Bu, diğer arayanlara mümkün olduğunca çok eş zamanlı erişim izni verirken, çakışan bir açıkta paylaşım ihlaline neden olmamak için tanıtıcıyı kapatmanız gerektiğinde size bildirim yapılmasını sağlar.

Eski Filtre Oplock'unu kullanma

Eski Filter oplock ayrıca diğer uygulamalar/istemciler aynı akışa erişmeye çalıştığında uygulamanın "geri çekmesine" olanak tanır, ancak atomik create-with-oplock yönteminden daha az esnektir. Bu mekanizma, bir uygulamanın akışı açmaya çalışırken akışın diğer erişimcilerinin paylaşım ihlalleri almasına neden olmadan bir akışa erişmesine olanak tanır. Paylaşım ihlallerini önlemek için, bir Filter oplock istemek üzere aşağıdaki üç adımlı prosedür kullanılmalıdır:

  1. Gerekli erişim FILE_READ_ATTRIBUTES ve bir paylaşım modu olarak FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ile dosyayı aç. Bu adımda açılan tanıtıcı, veri erişimi (FILE_READ_DATA) değil yalnızca öznitelik erişimi (FILE_READ_ATTRIBUTES) için açık olduğundan diğer uygulamaların paylaşım ihlalleri almasına neden olmaz. Bu kulp, Filtre işlem kilidini istemek için uygundur, ancak veri akışında gerçek G/Ç işlemlerini gerçekleştirmeye uygun değildir.

  2. 1. adımda elde edilen tanıtıcı üzerinde bir Filtre işlem kilidi (FSCTL_REQUEST_FILTER_OPLOCK) isteyin. Bu adımda verilen oplock, oplock sahibinin akışa erişmeye çalışan başka bir uygulamada paylaşım ihlaline neden olmadan "yoldan çıkmasını" sağlar.

  3. Dosyayı okuma erişimi için yeniden açın. Bu adımda açılan kol, oplok sahibinin veri akışında G/Ç yapmasına olanak tanır.

NTFS dosya sistemi, FILE_RESERVE_OPFILTER oluşturma seçeneği bayrağı aracılığıyla bu yordam için bir iyileştirme sağlar. Önceki prosedürün 1. adımında bu bayrak belirtilirse ve dosya sistemi 2. adımın başarısız olacağını saptayabiliyorsa, dosya sistemi oluşturma isteğini STATUS_OPLOCK_NOT_GRANTED ile başarısız olarak sonuçlandırabilir. 1. adım başarılı olursa, oluşturma isteği için FILE_RESERVE_OPFILTER belirtilmiş olsa bile 2. adımın başarılı olacağı garanti edilmez.

Oplock verme koşulları

Aşağıdaki tabloda bir oplock vermek için gereken koşullar tanımlanmıştır.

İstek türü Koşul -ları

Düzey 1

Filtre

Toplu iş

Yalnızca aşağıdaki koşulların tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
    • Bir dizin varsa, STATUS_INVALID_PARAMETER döndürülür.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • SENKRON erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür (senkron G/Ç istekleri için oplock verilmez).
  • Dosyanın herhangi bir akışında TxF işlemi yoktur.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta başka açık bağlantı yoktur (aynı iş parçacığı tarafından olsa bile).
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Düzey 2: Özgün Düzey 2 isteği, FILE_OPLOCK_BROKEN_TO_NONE ile bozulmuştur. İstenen özel oplock talebi daha sonra onaylanır.

  • Düzey 1, Batch, Filter, Read, Read-Handle, Read-Write veya Read-Write-Handle'da, STATUS_OPLOCK_NOT_GRANTED döndürülür.

Düzey 2

Yalnızca aşağıdaki koşulların tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
    • Bir dizin varsa, STATUS_INVALID_PARAMETER döndürülür.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • Senkron erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Dosyada TxF işlemi yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta geçerli Bayt Aralığı Kilitleri yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
    • Windows 7'den önce, işletim sistemi akışta en son açıldığından bu yana bir bayt aralığı kilidi olup olmadığını doğrular ve varsa istek başarısız olur.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Düzey 2 ve/veya Okuma: İstek kabul edildi. Aynı anda aynı akışta birden çok Düzey 2/Okuma oplock'u elde edebilirsiniz. Aynı tanıtıcıda birden çok Düzey 2 (ancak Okuma değil) oplock'ları bile bulunabilir.
    • Bir tanıtıcıda Okuma oplock'u talep edilirse ve zaten bir Okuma oplock'u bu tanıtıcıya verilmişse, ikinci Okuma oplock'u verilmeden önce birinci Okuma oplock'unun IRP'si STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ile tamamlanır.
  • Düzey 1, Batch, Filter, Read-Handle, Read-Write, Read-Write-Handle: STATUS_OPLOCK_NOT_GRANTED olarak döndürülür.

Okumak

Yalnızca aşağıdaki koşulların tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • Senkron erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Dosyada TxF işlemi yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta geçerli Bayt Aralığı Kilitleri yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışa yazılabilir kullanıcı eşlemeli bölümler yok.
    • Aksi takdirde, STATUS_CANNOT_GRANT_REQUESTED_OPLOCK döndürülür. REQUEST_OPLOCK_OUTPUT_BUFFER.Bayrak alanında REQUEST_OPLOCK_OUTPUT_FLAG_WRITABLE_SECTION_PRESENT bayrağı etkinleştirilir.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Düzey 2 ve/veya Okuma: İstek kabul edildi. Aynı anda aynı akışta birden çok Düzey 2/Okuma oplock'u elde edebilirsiniz.
    • Ayrıca, mevcut bir oplock yeni istekle aynı oplock anahtarına sahipse, IRP STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ile tamamlanır.
  • Read-Handle ve mevcut oplock'un yeni istekten farklı bir oplock anahtarı var: İstek kabul edildi. Birden çok Read ve Read-Handle oplock aynı veri akışında bulunabilir (bu tablodaki notu inceleyin).
    • Aksi halde (oplock tuşları aynıysa) STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Düzey 1, Yığın, Filtre, Okuma-Yazma, Okuma-Yazma-Tanıtıcı: STATUS_OPLOCK_NOT_GRANTED durumu geri döndürülür.

Read-Handle

Yalnızca aşağıdaki koşulların tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • Senkron erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Dosyada TxF işlemi yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta geçerli Bayt Aralığı Kilitleri yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta yazılabilir kullanıcı eşlemeli bir kesit bulunmuyor.
    • Aksi takdirde, STATUS_CANNOT_GRANT_REQUESTED_OPLOCK döndürülür. REQUEST_OPLOCK_OUTPUT_BUFFER.Bayrak alanında REQUEST_OPLOCK_OUTPUT_FLAG_WRITABLE_SECTION_PRESENT bayrağı etkinleştirilir.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Okundu: İstek onaylandı.
    • Mevcut bir Read oplock yeni istekle aynı oplock anahtarına sahipse, IRP STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ile tamamlanır. Sonuç olarak, oplock'un durumu Okuma'dan Read-Handle olarak yükseltilir.
    • Yeni istekle aynı oplock anahtarına sahip olmayan mevcut bir Read oplock değişmeden kalır.
  • Düzey 2, Düzey 1, Yığın, Filtre, Okuma-Yazma, Okuma-Yazma-Tutamak: STATUS_OPLOCK_NOT_GRANTED döndürülür.

Okuma-Yazma

Yalnızca aşağıdaki koşulların tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
    • Bir dizin varsa, STATUS_INVALID_PARAMETER döndürülür.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • Senkron erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Dosyada TxF işlemi yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta başka açıklıklar varsa (hatta aynı iş parçacığı tarafından bile), hepsinin aynı oplock anahtarına sahip olmaları gerekir.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta yazılabilir kullanıcı eşlemeli bölüm yok.
    • Aksi takdirde, STATUS_CANNOT_GRANT_REQUESTED_OPLOCK döndürülür. REQUEST_OPLOCK_OUTPUT_BUFFER.Bayrak alanında REQUEST_OPLOCK_OUTPUT_FLAG_WRITABLE_SECTION_PRESENT bayrağı etkinleştirilir.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Okuma veya Read-Write ve mevcut oplock, istekle aynı oplock anahtarına sahiptir: mevcut oplock'un IRP'si STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ile tamamlanır ve istek kabul edilir.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Düzey 2, Düzey 1, Toplu İş, Filtre, Okuma Tutamacı, Okuma-Yazma-Tutamacı: STATUS_OPLOCK_NOT_GRANTED döndürülür.

Okuma-Yazma-Kullanım

Yalnızca aşağıdakilerin tümü doğruysa verilir:

  • İstek, belirli bir dosya akışına yöneliktir.
    • Bir dizin varsa, STATUS_INVALID_PARAMETER döndürülür.
  • Akış EŞZAMANSIZ erişim için açılmıştır.
    • Senkron erişim için açılırsa, STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Dosyada TxF işlemi yok.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta, aynı iş parçacığı tarafından bile yapılmış olan başka açık istekler varsa, bunların aynı oplock anahtarına sahip olmaları gerekir.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Akışta yazılabilir kullanıcı eşlemeli bölümler yoktur.
    • Aksi takdirde, STATUS_CANNOT_GRANT_REQUESTED_OPLOCK döndürülür. REQUEST_OPLOCK_OUTPUT_BUFFER.Bayrak alanında REQUEST_OPLOCK_OUTPUT_FLAG_WRITABLE_SECTION_PRESENT bayrağı etkinleştirilir.

Geçerli oplock durumu ise:

  • Oplock yok: İstek kabul edildi.

  • Read, Read-Handle, Read-Write veya Read-Write-Handle ve mevcut oplock, istekle aynı oplock anahtarına sahipse: mevcut oplock'un IRP'si STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ile tamamlanır ve istek kabul edilir.
    • Aksi takdirde STATUS_OPLOCK_NOT_GRANTED döndürülür.
  • Düzey 2, Düzey 1, Küme, Filtre: STATUS_OPLOCK_NOT_GRANTED geri döndürülür.

Not

Okuma ve Düzey 2 oplock'ları aynı akışta birlikte var olabilir ve Okuma ile Okuma-Kolu (Read-Handle) oplock'ları bir arada bulunabilir, ancak Düzey 2 ve Okuma-Kolu oplock'ları birlikte olamaz.