"loff_t" adalah "offset panjang", yaitu posisi pencarian yang menyatukan keragaman gila off_t
, off64_t
, dan seterusnya, sehingga driver dapat menggunakan loff_t dan tidak perlu khawatir.
Pointer itu sendiri, pada saat Anda masuk ke driver, menunjuk ke offset yang disediakan oleh pengguna (dengan asumsi itu adalah kode pengguna yang melakukan akses driver — secara teknis kernel dapat menyediakannya sendiri, tetapi kasus penggunalah yang harus dipikirkan) melalui lseek
atau llseek
atau lseek64
, dll., lalu dengan operasi baca dan tulis biasa. Pertimbangkan kasus file on-disk biasa:ketika Anda pertama kali open
file, Anda (sebagai pengguna) mendapatkan kernel untuk menyediakan struktur data yang melacak posisi Anda saat ini di file, sehingga jika Anda read
atau write
beberapa byte, selanjutnya read
atau write
melanjutkan dari bagian terakhir yang Anda tinggalkan.
Selanjutnya, jika Anda dup
deskriptor file, atau lakukan hal yang setara dengan (mis.) fork
dan exec
dalam hal menjalankan urutan perintah, posisi pencarian itu digunakan bersama oleh semua proses pewarisan. Oleh karena itu, pada prompt shell, perintah:
(prog1; prog2; prog3) > outputfile
membuat file keluaran, lalu dup
Ini deskriptor untuk ketiga program tersebut, sehingga menghasilkan prog2
tulis masuk ke file segera setelah output dari prog1
, dan keluaran dari prog3
mengikuti dua lainnya—semuanya karena ketiga proses terpisah berbagi struktur data kernel dasar yang sama dengan loff_t
internal yang sama .
Hal yang sama berlaku untuk file driver perangkat. Saat fungsi baca dan tulis Anda dipanggil, Anda menerima "offset saat ini" seperti yang disediakan oleh pengguna, dan Anda dapat (dan harus) memperbaruinya sesuai kebutuhan ... dengan asumsi ada kebutuhan (mis., Anda ingin memberi pengguna tampilan file biasa, termasuk fakta bahwa mencari offset bergerak saat Anda membaca dan menulis). Jika perangkat memiliki beberapa aplikasi logis dari offset pencarian, Anda dapat menggunakannya di sini.
Tentu saja, ada lebih banyak driver perangkat, itulah sebabnya ada seluruh bab buku tentang hal ini (q.v.). :-)
Jawaban Torek sangat bagus. Hanya menambahkan sedikit detail/konteks tambahan ... Dari kernel Linux sebelumnya (2.6.28), berikut adalah contoh offset yang digunakan dalam panggilan sistem ... ini menyalin offset dari ruang pengguna ke variabel sementara sebelum mendapatkan ke dalam mekanisme pemanggilan driver kernel, dan kemudian menyalinnya kembali ke file pengguna. Beginilah cara offset yang dilihat pengemudi dipisahkan dari tampilan pengguna, dan memfasilitasi situasi saat offset adalah NULL dalam panggilan sistem, sehingga tidak terjadi SEGVIO.
SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
{
loff_t pos;
ssize_t ret;
if (offset) {
if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
return -EFAULT;
ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
if (unlikely(put_user(pos, offset)))
return -EFAULT;
return ret;
}
return do_sendfile(out_fd, in_fd, NULL, count, 0);
}