内核中操作文件函数与用户层read,write这样API不同,需要使用内核空间专用的一套函数。

 

文件API

struct file *filp_open(const char *filename, int flags, int mode);

打开文件

int filp_close(struct file *filp, fl_owner_t id);

关闭文件,参数id为POSIX线程ID,一般设NULL

 


struct file
{
struct path f_path; //文件路径
const struct file_operations *f_op; //文件操作结构,定义了读写等众多操作函数
spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */
...
};

/*
* NOTE:
* read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
* can be called without the big kernel lock held in all filesystems.
*/
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); //读
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); //写
...
}


 

 

测试


static void read_file( void )
{
char szBuff[210] = {};
mm_segment_t oldfs;

// 打开文件
fp = filp_open("/etc/redis/test.conf",O_RDWR,0);
if(!fp || IS_ERR(fp))
{
printk(KERN_ALERT "fail to open test.conf\n");
return -1;
}

// read
if(!fp->f_op || !fp->f_op->read)
{
printk(KERN_ALERT "Can't read file\n");
return -1;
}

oldfs = get_fs(); // 获取原先地址空间设置
set_fs(KERNEL_DS); // 设置为内核空间

if(fp->f_op->read(fp,szBuff,210,&fp->f_pos) == 0)// 执行fp的read函数
{
printk(KERN_ERR "Error in read file\n");
return -1;
}

set_fs(oldfs);// 还原为原先地址空间设置
printk(KERN_ALERT "%s\n",szBuff);

// 关闭文件
filp_close(fp);
return 0;
}