Debe tener en cuenta que debe evitar la E / S de archivos desde el kernel de Linux cuando sea posible. La idea principal es ir "un nivel más profundo" y llamar a las funciones de nivel VFS en lugar del controlador syscall directamente:
Incluye:
#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>
Abrir un archivo (similar a abrir):
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;
}
Cerrar un archivo (similar a cerrar):
void file_close(struct file *file)
{
filp_close(file, NULL);
}
Lectura de datos de un archivo (similar a 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;
}
Escribir datos en un archivo (similar a 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;
}
La sincronización cambia un archivo (similar a fsync):
int file_sync(struct file *file)
{
vfs_fsync(file, 0);
return 0;
}
[Editar] Originalmente, propuse usar file_fsync, que ya no está en las versiones más recientes del kernel. Gracias al pobre que sugirió el cambio, pero cuyo cambio fue rechazado. La edición fue rechazada antes de que pudiera revisarla.