📄 file.c
字号:
son->eno = enum_fs_no_error;
}else if(open_result == cn_fs_item_exist) //目录存在,但模式不匹配
{
goto exit_open_err;
}else
{//目录不存在,看是否需要创建。
if(need_to_creat)
{//需要创建
attr.all = 0; //先把所有属性初始化为false
attr.bits.folder = 1; //创建的是目录
if(DBX_device_tag->create_item(name,parent,attr) == false)
{//创建目录失败
mb_free(pg_content_pool,son);
goto exit_open_err;
}else
{
if(DBX_device_tag->open_item(name,parent,son,my_mode)
== cn_fs_open_success)
{
//打开目录实际上就是把目录结点挂到打开的文件资源树。
rsc_add_eldest_son(&parent->file_node,
&son->file_node,
sizeof(struct file_rsc),
son->name);
if(DBX_device_tag->opened_sum != cn_limit_uint32)
DBX_device_tag->opened_sum ++;
son->open_counter = 1;
son->eno = enum_fs_no_error;
}else
{
mb_free(pg_content_pool,son);
goto exit_open_err;
}
}
}else
{//不需要创建,当以r或r+方式打开文件时,不存在也不创建。
mb_free(pg_content_pool,son);
goto exit_open_err;
}
}
//被打开的项目(目录)所属文件柜
son->home_DBX = (struct pan_device*)DBX_lhdl->dev_interfase;
}
parent = son; //以当前打开的目录为下次使用的父目录
}
//至此,目录已经全部打开(或创建),下面打开文件
if(__pick_filename_word(synname,name)) //synname串中包含文件名吗?
{//打开文件
if((son = (struct file_rsc *)rsc_search_son(&parent->file_node,name))
== NULL)
{//文件尚未打开
if(!(son = mb_malloc(pg_content_pool,0)))
goto exit_open_err; //分配内存失败
son->home_DBX = parent->home_DBX;
//查找并打开文件
open_result = DBX_device_tag->open_item(name,parent,son,my_mode);
if(open_result == cn_fs_open_success)
{//文件存在并且可以按my_mode模式打开,已经初始化文件信息
rsc_add_eldest_son(&parent->file_node,&son->file_node,
sizeof(struct file_rsc),son->name);
if(DBX_device_tag->opened_sum != cn_limit_uint32)
DBX_device_tag->opened_sum ++;
son->open_counter = 1;
son->eno = enum_fs_no_error;
}else if(open_result == cn_fs_item_exist) //文件存在,但模式不匹配
{
goto exit_open_err;
}else
{//文件不存在,看是否需要创建。
if(need_to_creat)
{//需要创建
attr.all = 0;
attr.bits.archive = 1; //是文件
if(DBX_device_tag->create_item(name,parent,attr) == false)
{//创建文件失败
mb_free(pg_content_pool,son);
goto exit_open_err;
}else
{
if(DBX_device_tag->open_item(name,parent,son,my_mode)
== cn_fs_open_success)
{
rsc_add_eldest_son(&parent->file_node,
&son->file_node,
sizeof(struct file_rsc),
son->name);
son->open_counter = 1;
son->eno = enum_fs_no_error;
if(DBX_device_tag->opened_sum != cn_limit_uint32)
DBX_device_tag->opened_sum ++;
}else
{
mb_free(pg_content_pool,son);
goto exit_open_err;
}
}
}else
{//r或r+方式,不需要创建。
mb_free(pg_content_pool,son);
goto exit_open_err;
}
}
}else
{//文件已经打开
if(my_mode == son->open_mode)
{//已经打开的文件,只能以相同的方式再次打开。并且读写指针不改变
if(son->open_counter != cn_limit_uint32)
son->open_counter ++;
return son;
}else
return NULL;
}
}else //打开目录,目录在if(index != 0)语句前已经打开,且无需计打开次数
return son;
son->home_DBX = (struct pan_device*)DBX_lhdl->dev_interfase;
return son;
exit_open_err:
//删除已经添加的资源节点和释放分配的内存,opened保存的是本次增加的
//第一个资源节点的上一级节点。
if(opened == NULL)
return NULL;
son = (struct file_rsc *)rsc_get_twig(&opened->file_node);
while(son != NULL)
{
rsc_del_node(&son->file_node);
mb_free(pg_content_pool,son);
son = (struct file_rsc *)rsc_get_twig(&opened->file_node);
}
rsc_del_node(&opened->file_node);
mb_free(pg_content_pool,opened);
return NULL;
}
//----文件系统设备左手控制函数-------------------------------------------------
//功能:顾名思义,执行一系列上层发下来的文件系统控制命令
//参数:fs_lhdl,左手设备句柄指针
// left_cmd,左手命令字,使用时转换成enum fs_left_cmd类型
// data1、data2,跟命令字相关的数据
//返回:与命令字相关
//-----------------------------------------------------------------------------
ptu32_t djyfs_fs_left_ctrl(struct dev_handle *fs_lhdl,uint32_t left_cmd,
ptu32_t data1,ptu32_t data2)
{
switch(left_cmd)
{
case enum_fs_work_path:
{
}break; //for enum_fs_work_path
default:break;
}
return 0;
}
//----文件系统设备右手控制函数-------------------------------------------------
//功能:顾名思义,执行一系列存储设备driver发出的文件系统控制命令
//参数:fs_rhdl,右手设备句柄指针
// right_cmd,右手命令字,使用时转换成enum fs_right_cmd类型
// data1、data2,跟命令字相关的数据
//返回:与命令字相关,参见源程序注释
//-----------------------------------------------------------------------------
ptu32_t djyfs_fs_right_ctrl(struct dev_handle *fs_rhdl,uint32_t right_cmd,
ptu32_t data1,ptu32_t data2)
{
struct pan_device *DBX_device;
struct file_rsc *root_folder;
struct st_DBX_device_tag *DBX_device_tag;
struct dev_handle *DBX_lhdl;
switch(right_cmd)
{
case enum_fs_add_DBX:
{//成功添加返回enum_fs_no_error,否则返回enum_fs_creat_dbx_error
//data1为文件柜专有数据结构指针
//data2为信号量数据结构struct DBX_semp_para指针.虽然可以通过data1找到信
//号量,但从模块独立角度,不能这样做。以下是从data1找到信号量的方法:
//data1是 struct st_DBX_device_tag* 类型,指向文件柜专有数据结构,
//通过data1的medium_tag成员可以找到具体芯片数据结构,从而找到该芯片
//的信号量。但是,文件系统不应该访问medium_tag成员,故用data2传入。
//提取文件柜设备专有数据结构
DBX_device_tag = (struct st_DBX_device_tag*)data1;
DBX_device = dev_add_device(pg_fs_dev,DBX_device_tag->name,
((struct DBX_semp_para *)data2)->right,
((struct DBX_semp_para *)data2)->left,
(dev_write_func) NULL_func,
(dev_read_func ) NULL_func,
(dev_ctrl_func ) DBX_right_ctrl,
(dev_write_func ) djyfs_DBX_left_write,
(dev_read_func ) djyfs_DBX_left_read,
(dev_ctrl_func ) DBX_left_ctrl
);
if(DBX_device == NULL)
return enum_fs_creat_dbx_error;
//文件柜设备私有标签指向文件柜结构专用数据结构
DBX_device->private_tag = (ptu32_t)DBX_device_tag;
if(DBX_device_tag->formatted) //这是已经格式化好的文件柜
{
//申请根目录资源结点内存
root_folder = mb_malloc(pg_content_pool,0);
if(root_folder == NULL)
{ //申请不到内存,释放早先建立的设备
dev_delete_device(DBX_device);
return enum_fs_creat_dbx_error;
}
memset(root_folder,0,sizeof(struct file_rsc));
//把新文件柜的根目录资源节点加入到文件根资源结点下,成为满子结点
rsc_add_son(&tg_opened_file_root,&root_folder->file_node,
sizeof(struct file_rsc),DBX_device_tag->name);
//文件柜设备的打开文件的根结点指向该根资源结点。
DBX_device_tag->opened_root = root_folder;
root_folder->home_DBX = DBX_device;
}else //这是未格式化的文件柜
DBX_device_tag->opened_root = NULL;
return enum_fs_no_error;
}break; //for enum_fs_add_DBX
case enum_fs_del_DBX:
{
//提取文件柜设备专有数据结构
DBX_device_tag = (struct st_DBX_device_tag*)data1;
if(rsc_del_node(&DBX_device_tag->opened_root->file_node))
{
DBX_lhdl = dev_open_left(DBX_device_tag->name,0);
if(DBX_lhdl != NULL)
{
DBX_device = DBX_lhdl->dev_interfase;
dev_close_left(DBX_lhdl);
}else
return enum_fs_remove_error;
dev_delete_device(DBX_device);
return enum_fs_no_error;
}else
return enum_fs_remove_error;
}break; //for enum_fs_del_DBX
default:break;
}
return enum_fs_no_error;
}
//----左手写文件柜------------------------------------------------------------
//功能: 从文件柜设备左手接口把数据写入文件,本函数由文件柜的左手写函数调用,
// 调用顺序:
// 用户调用fwrite
// -->dev_write
// -->DBX_device->left_hand.io_write
// -->djyfs_DBX_left_write
//参数: DBX_lhdl,文件所属文件柜
// buf,写入数据缓冲区指针
// write_para,写入参数
// file,被写的文件指针。
//----------------------------------------------------------------------------
uint32_t djyfs_DBX_left_write(struct dev_handle *DBX_lhdl,ptu32_t buf,
ptu32_t write_para,ptu32_t file)
{
struct rw_para *pl_write_para = (struct rw_para *)write_para;
uint32_t write_len; //需要写入的数据长度
sint64_t rest_len;
uint32_t result;
struct file_rsc *fp = (struct file_rsc *)file; //取得文件指针
struct st_DBX_device_tag *DBX_device_tag = (struct st_DBX_device_tag *)
DBX_lhdl->dev_interfase->private_tag;
write_len = pl_write_para->nmemb * pl_write_para->size; //计算需写入的长度
//查询物理设备空闲空间
rest_len = DBX_device_tag->query_file_cubage(fp);
if(rest_len >= write_len)
{//物理设备上有足够的空间
result=DBX_device_tag->write(fp,(uint8_t*)buf,write_len);
result = result / pl_write_para->nmemb;
}else
{//物理设备上没有足够的空间,写入整数个完整记录
write_len = (rest_len / pl_write_para->nmemb) * pl_write_para->nmemb;
result=DBX_device_tag->write(fp,(uint8_t*)buf,write_len);
result = result / pl_write_para->nmemb;
}
return result;
}
//----左手读文件柜------------------------------------------------------------
//功能: 从文件柜设备左手接口读出文件,本函数由文件柜的左手读函数调用,调用顺序:
// 用户调用fread
// -->dev_read
// -->DBX_device->left_hand.io_read
// -->djyfs_DBX_left_read
//参数: DBX_lhdl,文件所属文件柜
// buf,保存数据的缓冲区指针
// read_para,读出参数
// file,被读的文件指针。
//----------------------------------------------------------------------------
ptu32_t djyfs_DBX_left_read(struct dev_handle *DBX_lhdl,ptu32_t buf,
ptu32_t read_para,ptu32_t file)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -