Keberhasilan buffered write() umumnya tidak berarti data file yang baru sudah mencapai storage non-volatile. Pada Linux, jalur buffered I/O yang umum menempatkan data file di page cache, menandai state cache terkait sebagai dirty, lalu membiarkan I/O ke storage berlangsung kemudian.
Pemisahan ini merupakan bagian utama dari I/O filesystem normal. Memori menyerap write aplikasi dengan akses yang cepat bagi CPU, sementara kernel dapat menjadwalkan traffic ke backing device secara terpisah. Mekanisme tersebut memberi fleksibilitas dan dapat mengurangi stall storage secara langsung, tetapi juga membentuk batas antara selesainya syscall dan persistensi.
Buffered write biasanya masuk ke page cache
Page cache adalah antarmuka utama antara I/O file normal dan filesystem Linux. Read dapat dilayani dari data file yang sudah berada di cache, sedangkan buffered write biasa memperbarui isi file di cache alih-alih melewati memori dan menerbitkan operasi device sinkron untuk setiap syscall.
Kode kernel modern mengelola memori page cache dalam bentuk folio. Ketika data file yang di-buffer berubah, state cache terkait menjadi dirty. State dirty mencatat bahwa isi file di memori berbeda dari salinan yang direpresentasikan oleh backing storage.
Kondisi tersebut tidak membuat write belum selesai dari sudut pandang syscall aplikasi. write() dapat kembali dengan sukses setelah kernel menerima data ke jalur buffered I/O, sesuai kondisi filesystem dan error yang terlibat. Persistensi storage merupakan peristiwa terpisah.
Pemisahan ini juga memungkinkan serangkaian write aplikasi mengakumulasi dirty memory sebelum seluruh operasi storage terkait selesai.
Writeback memindahkan data file dirty menuju storage
Writeback Linux mencari data page cache yang dirty dan mengirimkannya melalui filesystem serta stack block I/O menuju backing device. Writeback dapat dimulai di background, akibat tekanan dirty memory, atau sebagai bagian dari permintaan sinkronisasi eksplisit.
Kontrol VM kernel menyediakan threshold yang memengaruhi proses ini. Sebagai contoh, batas dirty untuk background dapat memulai aktivitas flusher sebelum dirty memory bertambah tanpa kendali. Proses yang menghasilkan write juga dapat mengalami throttling ketika dirty memory mencapai batas yang lebih kuat.
Kontrol tersebut merupakan kebijakan pengelolaan resource, bukan janji bahwa setiap write() langsung menghasilkan satu perintah device yang sepadan. Kernel dapat mengelompokkan dan menjadwalkan pekerjaan buffered sesuai perilaku filesystem, VM, dan block layer.
Writeback juga memiliki state in-progress tersendiri. Folio yang sedang dikirim menuju storage tidak sama dengan folio yang persistensinya telah dikonfirmasi melalui setiap layer yang relevan.
fsync() membentuk batas yang lebih kuat
Aplikasi yang memerlukan titik durability menggunakan operasi sinkronisasi, bukan menganggap buffered write yang sukses sebagai bukti persistensi. fsync() meminta kernel menyinkronkan state file yang diperlukan oleh operasi tersebut dan menunggu I/O terkait selesai.
Pekerjaan tepatnya bergantung pada filesystem dan stack storage. Data file mungkin memerlukan writeback, metadata filesystem mungkin memerlukan ordering atau persistensi, dan block layer mungkin perlu menangani cache device yang volatile.
Hal ini penting karena banyak storage device dapat mengakui write sebelum data mencapai media non-volatile. Linux menyediakan mekanisme cache flush dan Force Unit Access yang dapat digunakan filesystem saat menerapkan ordering integritas data pada device dengan volatile write-back cache.
Kontrak durability yang terlihat oleh aplikasi dengan demikian melintasi beberapa layer. Writeback page cache adalah salah satu bagian jalur tersebut; ordering filesystem dan perilaku cache device juga relevan.
Batas dirty memory mengendalikan tekanan, bukan semantik transaksi
Linux menyediakan pengaturan seperti dirty_background_bytes, dirty_background_ratio, dirty_bytes, dan dirty_ratio. Pengaturan ini memengaruhi kapan background writeback dimulai dan kapan task yang menghasilkan data dirty harus ikut melakukan atau menunggu writeback.
Nilai tersebut dapat mengubah perilaku workload secara nyata. Sistem yang mengizinkan lebih banyak dirty memory dapat menyerap burst lebih besar sebelum storage menjadi pembatas utama. Batas yang lebih ketat dapat membuat throughput backing device terasa lebih cepat.
Pengaturan itu tidak mengubah buffered write menjadi transaksi filesystem. Pengaturan tersebut juga tidak menggantikan sinkronisasi di level aplikasi ketika program memerlukan titik persistensi yang terdefinisi.
Writeback periodik juga merupakan mekanisme pemeliharaan. Data dirty yang lama dapat dipilih untuk writeout di background, tetapi aktivitas periodik bukan pengganti operasi durability eksplisit pada titik ketika correctness aplikasi bergantung pada persistensi.
Memory reclaim dapat memicu writeback
Memori page cache yang clean sering dapat di-reclaim karena isinya dapat dibaca kembali dari backing file. Data file dirty berbeda: membuangnya sebelum sinkronisasi akan menghilangkan perubahan yang hanya ada di memori.
Tekanan memori karena itu dapat memicu writeback ketika VM berusaha membuat state cache dirty dapat di-reclaim. Hubungan ini mengaitkan latensi I/O filesystem dengan tekanan memori meskipun aplikasi tidak menerbitkan syscall sinkronisasi pada saat tersebut.
Efeknya bergantung pada workload. Laju dirtying, memori yang tersedia, perilaku filesystem, throughput backing device, dan kebijakan VM semuanya memengaruhi kapan writer menghadapi tekanan.
Direct I/O mengikuti jalur cache yang berbeda
Model buffered I/O tidak berlaku untuk setiap operasi file. O_DIRECT dapat melewati page cache untuk I/O yang didukung, dengan tetap mengikuti batasan filesystem dan alignment. Write pada file yang di-memory-map juga berinteraksi dengan state page cache melalui antarmuka aplikasi yang berbeda.
Bahkan di luar page cache, completion dan state media yang durable dapat tetap berbeda ketika cache volatile atau layer storage asynchronous terlibat. Melewati page cache menghapus satu layer buffering; tindakan itu tidak otomatis menghapus setiap batas persistensi di bawah filesystem.
Completion dan persistensi adalah dua peristiwa sistem
Buffered I/O bekerja karena Linux dapat mengakui write aplikasi sebelum seluruh pekerjaan backing storage selesai. State page cache dirty mencatat jarak tersebut, writeback memajukan state menuju storage, dan operasi sinkronisasi menyediakan batas persistensi yang lebih kuat saat software memerlukannya.
Untuk analisis performa, latensi syscall dan latensi storage bukan ukuran yang dapat dipertukarkan. Untuk correctness, buffered write() yang sukses dan operasi durability yang selesai membawa jaminan berbeda. Perbedaan ini merupakan sifat stack I/O, bukan kasus khusus.