You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.2 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2010-2020. All rights reserved.
* Description: common driver file define
* Author: Hisilicon
* Create: 2010-01-01
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <linux/path.h>
#include <linux/seq_file.h>
#include <linux/namei.h>
#include <linux/stat.h>
#include <linux/version.h>
#include "td_type.h"
#include "drv_sys_ext.h"
#include "drv_log_ext.h"
#include "drv_file_ext.h"
#include "drv_log.h"
#define PARENT_DIR_INODE_LOCK(d_inode) down_write_trylock(&(d_inode)->i_rwsem)
#define PARENT_DIR_INODE_UNLOCK(d_inode) up_write(&(d_inode)->i_rwsem)
struct file* ext_drv_file_open(const td_char *name, td_u32 flags)
{
struct file *file = NULL;
if (name == NULL) {
return NULL;
}
if (flags == 0) {
flags = O_RDONLY;
} else {
flags = O_WRONLY | O_CREAT | O_APPEND;
}
file = filp_open(name, flags | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (IS_ERR(file)) {
return NULL;
}
return file;
}
td_void ext_drv_file_close(struct file *file)
{
if (file != NULL) {
filp_close(file, NULL);
}
}
td_s32 ext_drv_file_read(struct file *file, td_u8 *buf, const td_u32 len)
{
td_s32 read_len;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
mm_segment_t old_fs = {0};
#endif
if ((file == NULL) || (buf == NULL)) {
return -ENOENT; /* No such file or directory */
}
if (((file->f_flags & O_ACCMODE) & (O_RDONLY | O_RDWR)) != 0) {
return -EACCES; /* Permission denied */
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
/* saved the original file space */
old_fs = get_fs();
/* extend to the kernel data space */
set_fs(KERNEL_DS);
#endif
read_len = vfs_read(file, buf, len, &file->f_pos);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
/* Restore the original file space */
set_fs(old_fs);
#endif
return read_len;
}
td_s32 ext_drv_file_write(struct file *file, const td_u8 *buf, const td_u32 len)
{
td_s32 write_len;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
mm_segment_t old_fs = {0};
#endif
if ((file == NULL) || (buf == NULL)) {
return -ENOENT; /* No such file or directory */
}
if (((file->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR)) == 0) {
return -EACCES; /* Permission denied */
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
old_fs = get_fs();
set_fs(KERNEL_DS);
#endif
write_len = vfs_write(file, buf, len, &file->f_pos);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
set_fs(old_fs);
#endif
return write_len;
}
loff_t ext_drv_file_lseek(struct file *file, const td_s32 offset, const td_s32 whence)
{
return vfs_llseek(file, offset, whence);
}
td_s32 ext_drv_file_get_store_path(td_char *path, const td_u32 len)
{
if ((path == NULL) || (len == 0)) {
return TD_FAILURE;
}
return ext_drv_log_get_store_path(path, len);
}
EXPORT_SYMBOL(ext_drv_file_open);
EXPORT_SYMBOL(ext_drv_file_close);
EXPORT_SYMBOL(ext_drv_file_read);
EXPORT_SYMBOL(ext_drv_file_write);
EXPORT_SYMBOL(ext_drv_file_lseek);
EXPORT_SYMBOL(ext_drv_file_get_store_path);