Powinieneś być świadomy, że powinieneś unikać wejścia / wyjścia plików z jądra Linuksa, jeśli to możliwe. Głównym pomysłem jest pójście „o jeden poziom głębiej” i bezpośrednie wywołanie funkcji poziomu VFS zamiast obsługi wywołania systemowego :
Obejmuje:
#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
Otwieranie pliku (podobnie jak otwieranie):
struct file *file_open(const char *path, int flags, int rights)
{
struct file *filp = NULL;
mm_segment_t oldfs;
int err = 0;
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);
if (IS_ERR(filp)) {
err = PTR_ERR(filp);
return NULL;
}
return filp;
}
Zamknij plik (podobnie do zamknięcia):
void file_close(struct file *file)
{
filp_close(file, NULL);
}
Odczytywanie danych z pliku (podobnie do pread):
int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
{
mm_segment_t oldfs;
int ret;
oldfs = get_fs();
set_fs(get_ds());
ret = vfs_read(file, data, size, &offset);
set_fs(oldfs);
return ret;
}
Zapisywanie danych do pliku (podobnie do pwrite):
int file_write(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size)
{
mm_segment_t oldfs;
int ret;
oldfs = get_fs();
set_fs(get_ds());
ret = vfs_write(file, data, size, &offset);
set_fs(oldfs);
return ret;
}
Synchronizacja zmienia plik (podobnie do fsync):
int file_sync(struct file *file)
{
vfs_fsync(file, 0);
return 0;
}
[Edytuj] Początkowo zaproponowałem użycie file_fsync, który zniknął w nowszych wersjach jądra. Dzięki biednemu facetowi, który sugerował zmianę, ale którego zmiana została odrzucona. Zmiana została odrzucona, zanim mogłem ją sprawdzić.
Od wersji 4.14 jądra Linuksa funkcje
vfs_read
ivfs_write
funkcje nie są już eksportowane do użytku w modułach. Zamiast tego dostępne są funkcje wyłącznie dla dostępu do plików jądra:Ponadto
filp_open
nie akceptuje już ciągu znaków przestrzeni użytkownika, więc może być używany do bezpośredniego dostępu do jądra (bez tańca zset_fs
).źródło