您的位置:首页 > 运维架构 > Linux

Linux内核读写文件

2010-12-21 21:24 621 查看
drivers/mtd/nandsim.c

<1>:打开文件

cfile = filp_open(cache_file, O_CREAT | O_RDWR | O_LARGEFILE, 0600);
if (IS_ERR(cfile))
return PTR_ERR(cfile);
if (!cfile->f_op || (!cfile->f_op->read && !cfile->f_op->aio_read)) {
NS_ERR("alloc_device: cache file not readable/n");
err = -EINVAL;
goto err_close;
}
if (!cfile->f_op->write && !cfile->f_op->aio_write) {
NS_ERR("alloc_device: cache file not writeable/n");
err = -EINVAL;
goto err_close;
}

<2>:读文件

static ssize_t read_file(struct nandsim *ns, struct file *file, void *buf, size_t count, loff_t *pos)
{
mm_segment_t old_fs;
ssize_t tx;
int err, memalloc;

err = get_pages(ns, file, count, *pos);
if (err)
return err;
old_fs = get_fs();
set_fs(get_ds()); //将地址空间设置为内核空间,防止vfs_read返回失败
memalloc = set_memalloc();
tx = vfs_read(file, (char __user *)buf, count, pos);
clear_memalloc(memalloc);
set_fs(old_fs);
put_pages(ns);
return tx;
}

<3>:写文件

static ssize_t write_file(struct nandsim *ns, struct file *file, void *buf, size_t count, loff_t *pos)
{
mm_segment_t old_fs;
ssize_t tx;
int err, memalloc;

err = get_pages(ns, file, count, *pos);
if (err)
return err;
old_fs = get_fs();
set_fs(get_ds()); //#define get_ds() (KERNEL_DS)
memalloc = set_memalloc();
tx = vfs_write(file, (char __user *)buf, count, pos);
clear_memalloc(memalloc);
set_fs(old_fs);
put_pages(ns);
return tx;
}

/*
* createfile.c
* Author: Woody <Pecker.hu@gmail.com>
*
* Use kernel APIs to create a file
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/

#include <linux/module.h>     /* MODULE_LICENSE     */
#include <linux/kernel.h>     /* printk,pr_info     */
#include <linux/errno.h>      /* EINVAL,EAGAIN,etc. */
#include <linux/err.h>        /* IS_ERR             */
#include <linux/init.h>       /* module_init        */
#include <linux/delay.h>      /* mdelay,msleep      */
#include <linux/hrtimer.h>    /* hrtimer APIs       */
#include <linux/time.h>       /* struct timespec    */
#include <linux/device.h>     /* device_create      */
#include <linux/fs.h>
#include <linux/slab.h>       /* kzalloc            */
#include <asm/uaccess.h>	  /* get_fs				*/
#include <linux/mutex.h>	  /* struct mutex       */
struct kernel_test {	/* Just for kernel test code */
wait_queue_head_t waitq;
struct mutex test_lock;
struct class *sys_print_class;
struct device *dev;
int rw_flag;
int print_flag;
};
static struct kernel_test *data;
static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
int ret = 0;
DECLARE_WAITQUEUE(wait, current);
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&data->waitq, &wait);
if (data->rw_flag == 0) {
printk("Begin to sched...>/n");
schedule();
}

printk("@@@@@@@@@@@@Wake up the current/n");
remove_wait_queue(&data->waitq, &wait);
set_current_state(TASK_RUNNING);
ret = sprintf(buf, "%d/n", data->print_flag);

data->rw_flag = 0;
return ret;
}

static ssize_t enable_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
sscanf(buf, "%d", &data->print_flag);

data->rw_flag = 1;
wake_up(&data->waitq);
return size;
}
static DEVICE_ATTR(enable, 0644, enable_show, enable_store);
static int open_file(void)
{
struct file * cfile;
uint32_t err = 0;
mm_segment_t old_fs;
ssize_t tx;
uint8_t buf[16] = "Hello World!";
loff_t pos = 0;

cfile = filp_open("/kernel_test", O_CREAT | O_RDWR | O_LARGEFILE, 0644);
if (IS_ERR(cfile))
return PTR_ERR(cfile);

if (!cfile->f_op || (!cfile->f_op->read && !cfile->f_op->aio_read)) {
printk("alloc_device: cache file not readable/n");
err = -EINVAL;
goto err_close;
}
if (!cfile->f_op->write && !cfile->f_op->aio_write) {
printk("alloc_device: cache file not writeable/n");
err = -EINVAL;
goto err_close;
}
printk("Open the file /huyugui/log/n");
old_fs = get_fs();
set_fs(get_ds());
tx = vfs_write(cfile, (char __user *)buf, 16, &pos);
set_fs(old_fs);

err_close:
filp_close(cfile, NULL);
return err;
}
static int __init file_init_module(void)
{
int ret = 0;
printk("[%s,%d]/n", __FUNCTION__, __LINE__);
data = kzalloc(sizeof(struct kernel_test), GFP_KERNEL);
if (data == NULL) {
printk("[%s,%d]out of memory!/n", __FUNCTION__, __LINE__);
return -ENOMEM;
}

mutex_init(&data->test_lock);
init_waitqueue_head(&data->waitq);
data->rw_flag = 0;	/* when write new data,the rw_flag will be set to "1" */
data->sys_print_class = class_create(THIS_MODULE, "kernel_test");
if (IS_ERR(data->sys_print_class)) {
ret = PTR_ERR(data->sys_print_class);
goto fail;
} else {
printk("Create the /sys/class/kernel_test/n");
}

data->dev = device_create(data->sys_print_class,
NULL, MKDEV(255, 0), NULL, "file");
printk("Create the foder:/sys/class/kernel_test/file/n");
ret = device_create_file(data->dev, &dev_attr_enable);
ret = open_file();
if (ret == 0) {
printk("Create file successfully!/n");
} else {
printk("Create file failed!/n");
}
goto out;

fail:
kfree(data);
out:
return ret;
}

static void __exit file_cleanup_module(void)
{
printk("[%s,%d]/n", __FUNCTION__, __LINE__);

device_remove_file(data->dev, &dev_attr_enable);
device_destroy(data->sys_print_class, MKDEV(255, 0));
class_destroy(data->sys_print_class);
kfree(data);	/* free the memory when remove modules */

}
module_init(file_init_module);
module_exit(file_cleanup_module);

MODULE_AUTHOR("Woody <Pecker.hu@gmail.com>");
MODULE_DESCRIPTION("Use Kernel APIs to create files");
MODULE_LICENSE("GPL");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: