Meminta dan memberikan oplock
Ketika pengalih jaringan mengakses file di server jarak jauh, ia meminta oplock dari server jarak jauh. Aplikasi klien secara langsung meminta oplock hanya ketika kunci ditujukan untuk file di server lokal.
Oplocks diminta melalui FSCTL . Berikut ini adalah FSCTL yang digunakan untuk berbagai jenis oplock, yang dapat dikeluarkan oleh aplikasi mode pengguna dan driver mode kernel.
- Untuk meminta oplock pada Windows 7:
- Untuk meminta oplock warisan:
Meminta oplock dalam mode pengguna
Untuk meminta oplock Windows 7 dalam mode pengguna, panggil DeviceIoControl:
- Tetapkan dwIoControlCode ke FSCTL_REQUEST_OPLOCK.
- Teruskan penunjuk ke struktur REQUEST_OPLOCK_INPUT_BUFFER dalam parameter lpInBuffer.
- Lihat dokumentasi struktur tersebut untuk informasi tentang cara memformat permintaan oplock.
- Berikan penunjuk ke struktur REQUEST_OPLOCK_OUTPUT_BUFFER dalam parameter lpOutBuffer.
Untuk informasi selengkapnya, lihat FSCTL_REQUEST_OPLOCK.
Jika oplock yang diminta dapat diberikan, DeviceIoControl mengembalikan FALSE dan GetLastError mengembalikan ERROR_IO_PENDING. Untuk alasan ini, oplock tidak pernah diberikan untuk I/O sinkron. Operasi yang tumpang tindih tidak selesai sampai oplock rusak. Setelah operasi selesai, REQUEST_OPLOCK_OUTPUT_BUFFER akan berisi informasi tentang pemutusan oplock.
Jika oplock tidak dapat diberikan, sistem file mengembalikan kode kesalahan yang sesuai. Kode kesalahan yang paling umum dikembalikan adalah ERROR_OPLOCK_NOT_GRANTED dan ERROR_INVALID_PARAMETER.
Meminta oplock dalam mode kernel
Untuk meminta oplock Windows 7 dalam mode kernel:
Minifilter sistem file
Minifilter sistem file harus menggunakan FltAllocateCallbackData dan mengisi FLT_CALLBACK_DATA yang dialokasikan seperti:
- Atur bidang Iopb->MajorFunction menjadi IRP_MJ_FILE_SYSTEM_CONTROL.
- Setel bidang Iopb->MinorFunction ke IRP_MN_USER_FS_REQUEST.
- Atur parameter Iopb->. FileSystemControl.Buffered.FsControlCode anggota menjadi FSCTL_REQUEST_OPLOCK.
- Alokasikan buffer yang ukurannya sama dengan yang lebih besar dari REQUEST_OPLOCK_INPUT_BUFFER atau REQUEST_OPLOCK_OUTPUT_BUFFER.
- Atur FLT_CALLBACK_DATAyang dialokasikan untuk Iopb->Parameters.FileSystemControl.Buffered.SystemBuffer agar anggotanya menunjuk ke buffer tersebut.
- Atur parameter FLT_CALLBACK_DATAIopb->.FileSystemControl.Buffered.InputBufferLength dan Iopb->Parameters.FileSystemControl.Buffered.OutputBufferLength ke ukuran buffer tersebut.
Rujuk pada dokumentasi struktur REQUEST_OPLOCK_INPUT_BUFFER untuk informasi tentang cara memformat permintaan oplock.
Kemudian minifilter sistem file harus memanggil FltPerformAsynchronousIo, melewati FLT_CALLBACK_DATA yang dialokasikan sebagai parameter CallbackData.
Jika oplock yang diminta dapat diberikan, panggilan FltPerformAsynchronousIo mengembalikan STATUS_PENDING. Untuk alasan ini, oplock tidak pernah diberikan untuk input/output (I/O) sinkron. Operasi tidak akan selesai sampai oplock tersebut dihentikan. Setelah operasi selesai, REQUEST_OPLOCK_OUTPUT_BUFFER akan berisi informasi tentang pemutusan oplock.
Jika oplock tidak dapat diberikan, sistem file mengembalikan kode kesalahan yang sesuai. Kode kesalahan yang paling sering dikembalikan adalah STATUS_OPLOCK_NOT_GRANTED dan STATUS_INVALID_PARAMETER.
Jenis Driver Lainnya
Jenis driver lain dapat memanggil ZwFsControlFile:
- Atur FsControlCode ke FSCTL_REQUEST_OPLOCK.
- Teruskan penunjuk ke struktur REQUEST_OPLOCK_INPUT_BUFFER dalam parameter InputBuffer dan atur parameter InputBufferLength dengan ukuran buffer tersebut.
- Teruskan penunjuk ke struktur REQUEST_OPLOCK_OUTPUT_BUFFER dalam parameter OutputBuffer dan atur parameter OutputBufferLength ke ukuran buffer tersebut.
Lihat dokumentasi struktur REQUEST_OPLOCK_INPUT_BUFFER untuk mengetahui cara memformat permintaan oplock.
Jika oplock yang diminta dapat diberikan, panggilan ZwFsControlFile akan mengembalikan STATUS_PENDING. Untuk alasan ini, oplock tidak pernah diberikan untuk I/O sinkron. Operasi tidak selesai sampai oplock rusak. Setelah operasi selesai, REQUEST_OPLOCK_OUTPUT_BUFFER akan berisi informasi tentang pemutusan oplock.
Jika oplock tidak dapat diberikan, sistem file mengembalikan kode kesalahan yang sesuai. Kode kesalahan yang paling umum dikembalikan adalah STATUS_OPLOCK_NOT_GRANTED dan STATUS_INVALID_PARAMETER.
Menghindari Pelanggaran Pembagian Sumber Daya Saat Meminta Oplocks
Menggunakan Metode Atomic Create-With-Oplock
Atom create-with-oplock bukan jenis oplock. Sebaliknya, ini adalah prosedur yang memungkinkan operasi terbuka untuk menghindari menyebabkan pelanggaran mode berbagi dalam rentang waktu antara membuka file dan menerima oplock. Dengan oplock warisan, memfilter oplock dan membuka dua pegangan diperlukan. Dengan oplock Windows 7, aplikasi atau driver dapat meminta segala jenis oplock menggunakan prosedur ini dan hanya perlu membuka satu pegangan.
Untuk melakukan prosedur atom create-with-oplock, Anda perlu:
- Gunakan FltCreateFileEx2 atau ZwCreateFile, yang sesuai, untuk membuka file. Dalam parameter CreateOptions, sisipkan flag FILE_OPEN_REQUIRING_OPLOCK. Anda dapat mengatur parameter DesiredAccess dan ShareAccess sesuai keinginan. Misalnya, dalam parameter DesiredAccess diatur GENERIC_READ sehingga Anda dapat membaca file, dan dalam parameter ShareAccess atur FILE_SHARE_READ | FILE_SHARE_DELETE bendera untuk memungkinkan orang lain membaca, mengganti nama, dan/atau menandai file untuk dihapus saat Anda membukanya.
- Gunakan kode kontrol FSCTL_REQUEST_OPLOCK untuk mengajukan oplock pada objek atau handle file yang dihasilkan, seperti yang dijelaskan dalam Meminta Oplock Dalam Mode Kernel.
Jangan lakukan operasi sistem file apa pun pada file antara langkah 1 dan 2. Melakukannya dapat menyebabkan kebuntuan.
Oplock yang paling umum untuk diminta menggunakan prosedur ini adalah jenis Read-Handle. Ini memungkinkan Anda untuk memberikan akses bersamaan sebanyak mungkin kepada penelepon lain, sambil tetap memberi tahu Anda jika perlu menutup handle untuk menghindari terjadinya pelanggaran berbagi yang bertentangan.
Menggunakan Filter Warisan Oplock
Oplock Filter klasik juga memungkinkan aplikasi untuk "mundur" ketika aplikasi/klien lain mencoba mengakses aliran data yang sama, tetapi kurang fleksibel daripada metode pembuatan-dengan-oplock atomik. Mekanisme ini memungkinkan aplikasi untuk mengakses aliran tanpa menyebabkan aksesor aliran lain menerima pelanggaran berbagi saat mencoba membuka aliran. Untuk menghindari pelanggaran berbagi akses, gunakan prosedur tiga langkah berikut untuk meminta Filter oplock:
Buka file dengan akses FILE_READ_ATTRIBUTES yang diperlukan dan mode berbagi FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE. Handle yang dibuka dalam langkah ini tidak akan menyebabkan aplikasi lain menerima pelanggaran berbagi akses karena hanya dibuka untuk akses atribut (FILE_READ_ATTRIBUTES) dan bukan akses data (FILE_READ_DATA). Pegangan ini cocok untuk meminta oplock Filter, tetapi tidak untuk melakukan masukan/keluaran aktual pada aliran data.
Minta Filter oplock (FSCTL_REQUEST_FILTER_OPLOCK) pada handle pada langkah 1. Oplock yang diberikan dalam langkah ini memungkinkan pemegang oplock untuk "keluar dari jalan" tanpa menyebabkan pelanggaran berbagi ke aplikasi lain yang mencoba mengakses aliran.
Buka file lagi untuk akses baca. Pegangan yang dibuka dalam langkah ini memungkinkan pemegang oplock untuk melakukan I/O pada stream.
Sistem file NTFS menyediakan optimasi untuk prosedur ini melalui opsi pembuatan FILE_RESERVE_OPFILTER. Jika flag ini ditentukan di langkah 1 dari prosedur sebelumnya, flag ini memungkinkan sistem file untuk menolak permintaan pembuatan dengan STATUS_OPLOCK_NOT_GRANTED jika sistem file dapat menentukan bahwa langkah 2 akan gagal. Jika langkah 1 berhasil, tidak ada jaminan bahwa langkah 2 akan berhasil, bahkan jika FILE_RESERVE_OPFILTER ditentukan untuk permintaan pembuatan.
Kondisi Untuk Memberikan Oplock
Tabel berikut mengidentifikasi kondisi yang diperlukan untuk memberikan oplock.
Jenis permintaan | Kondisi |
---|---|
Tingkat 1 Filter Lot |
Diberikan hanya jika semua kondisi berikut ini benar:
Jika status oplock saat ini adalah:
|
Tingkat 2 |
Diberikan hanya jika semua kondisi berikut ini benar:
Jika status oplock saat ini adalah:
|
Membaca |
Diberikan hanya jika semua kondisi berikut ini benar:
Jika status oplock saat ini adalah:
|
Read-Handle |
Diberikan hanya jika semua kondisi berikut ini benar:
Jika status oplock saat ini adalah:
|
Read-Write |
Diberikan hanya jika semua kondisi berikut ini benar:
Jika status oplock saat ini adalah:
|
Baca-Write-Handle |
Diberikan hanya jika semua hal berikut ini benar:
Jika status oplock saat ini adalah:
|
Nota
Oplock Baca dan Level 2 dapat hidup berdampingan pada aliran yang sama, dan oplock Baca dan Read-Handle dapat hidup berdampingan, tetapi oplock Level 2 dan Read-Handle tidak dapat hidup berdampingan.