更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
vfs_jffs2.c 文件参考

http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.html 更多...

浏览源代码.

函数

static void Jffs2SetVtype (struct jffs2_inode *node, struct Vnode *pVnode)
 设置vnode节点的文件类型 更多...
 
time_t Jffs2CurSec (void)
 
void Jffs2NodeLock (void)
 
void Jffs2NodeUnlock (void)
 
int VfsJffs2Bind (struct Mount *mnt, struct Vnode *blkDriver, const void *data)
 VfsJffs2Bind 挂载JFFS2分区 更多...
 
int VfsJffs2Unbind (struct Mount *mnt, struct Vnode **blkDriver)
 VfsJffs2Unbind 卸载JFFS2分区
更多...
 
int VfsJffs2Lookup (struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode)
 
int VfsJffs2Create (struct Vnode *parentVnode, const char *path, int mode, struct Vnode **ppVnode)
 创建一个jffs2 索引节点 更多...
 
int VfsJffs2Close (struct file *filep)
 
ssize_t VfsJffs2ReadPage (struct Vnode *vnode, char *buffer, off_t off)
 
ssize_t VfsJffs2Read (struct file *filep, char *buffer, size_t bufLen)
 
ssize_t VfsJffs2WritePage (struct Vnode *vnode, char *buffer, off_t pos, size_t buflen)
 
ssize_t VfsJffs2Write (struct file *filep, const char *buffer, size_t bufLen)
 
off_t VfsJffs2Seek (struct file *filep, off_t offset, int whence)
 
int VfsJffs2Ioctl (struct file *filep, int cmd, unsigned long arg)
 
int VfsJffs2Fsync (struct file *filep)
 
int VfsJffs2Dup (const struct file *oldFile, struct file *newFile)
 
int VfsJffs2Opendir (struct Vnode *pVnode, struct fs_dirent_s *dir)
 
int VfsJffs2Readdir (struct Vnode *pVnode, struct fs_dirent_s *dir)
 
int VfsJffs2Seekdir (struct Vnode *pVnode, struct fs_dirent_s *dir, unsigned long offset)
 
int VfsJffs2Rewinddir (struct Vnode *pVnode, struct fs_dirent_s *dir)
 
int VfsJffs2Closedir (struct Vnode *node, struct fs_dirent_s *dir)
 
int VfsJffs2Mkdir (struct Vnode *parentNode, const char *dirName, mode_t mode, struct Vnode **ppVnode)
 
static int Jffs2Truncate (struct Vnode *pVnode, unsigned int len)
 
int VfsJffs2Truncate (struct Vnode *pVnode, off_t len)
 
int VfsJffs2Truncate64 (struct Vnode *pVnode, off64_t len)
 
int VfsJffs2Chattr (struct Vnode *pVnode, struct IATTR *attr)
 
int VfsJffs2Rmdir (struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
 
int VfsJffs2Link (struct Vnode *oldVnode, struct Vnode *newParentVnode, struct Vnode **newVnode, const char *newName)
 
int VfsJffs2Symlink (struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target)
 
ssize_t VfsJffs2Readlink (struct Vnode *vnode, char *buffer, size_t bufLen)
 
int VfsJffs2Unlink (struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
 
int VfsJffs2Rename (struct Vnode *fromVnode, struct Vnode *toParentVnode, const char *fromName, const char *toName)
 
int VfsJffs2Stat (struct Vnode *pVnode, struct stat *buf)
 
int VfsJffs2Reclaim (struct Vnode *pVnode)
 
int VfsJffs2Statfs (struct Mount *mnt, struct statfs *buf)
 
int Jffs2MutexCreate (void)
 
void Jffs2MutexDelete (void)
 
 FSMAP_ENTRY (jffs_fsmap, "jffs2", jffs_operations, TRUE, TRUE)
 

变量

struct VnodeOps g_jffs2Vops
 jffs2 关于vnode操作接口实现 更多...
 
struct file_operations_vfs g_jffs2Fops
 jffs2 关于vfs接口实现 更多...
 
static LosMux g_jffs2FsLock
 
static pthread_mutex_t g_jffs2NodeLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
 
struct Vnodeg_jffs2PartList [CONFIG_MTD_PATTITION_NUM]
 
const struct MountOps jffs_operations
 

详细描述

http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-bundles-fs-support-jffs2.html

 基本概念
    JFFS2是Journalling Flash File System Version 2(日志文件系统)的缩写,是针对MTD设备的日志型文件系统。

    OpenHarmony内核的JFFS2主要应用于NOR FLASH闪存,其特点是:可读写、支持数据压缩、提供了崩溃/掉电安全保护、
    提供“写平衡”支持等。闪存与磁盘介质有许多差异,直接将磁盘文件系统运行在闪存设备上,会导致性能和安全问题。
    为解决这一问题,需要实现一个特别针对闪存的文件系统,JFFS2就是这样一种文件系统。

 运行机制
    关于JFFS2文件系统的在存储设备上的实际物理布局,及文件系统本身的规格说明,请参考JFFS2的官方规格说明文档。
    https://sourceware.org/jffs2/
    这里仅列举几个对开发者和使用者会有一定影响的JFFS2的重要机制/特征:

    1. Mount机制及速度问题:按照JFFS2的设计,所有的文件会按照一定的规则,切分成大小不等的节点,
        依次存储到flash设备上。在mount流程中,需要获取到所有的这些节点信息并缓存到内存里。
        因此,mount速度和flash设备的大小和文件数量的多少成线性比例关系。这是JFFS2的原生设计问题,
        对于mount速度非常介意的用户,可以在内核编译时开启“Enable JFFS2 SUMMARY”选项,可以极大提升mount的速度。
        这个选项的原理是将mount需要的信息提前存储到flash上,在mount时读取并解析这块内容,使得mount的速度变得相对恒定。
        这个实际是空间换时间的做法,会消耗8%左右的额外空间。
    2. 写平衡的支持:由于flash设备的物理属性,读写都只能基于某个特定大小的“块”进行,为了防止某些特定的块磨损过于严重,
        在JFFS2中需要对写入的块进行“平衡”的管理,保证所有的块的写入次数都是相对平均的,进而保证flash设备的整体寿命。
    3. GC(garbage collection)机制:在JFFS2里发生删除动作,实际的物理空间并不会立即释放,而是由独立的GC线程来做
        空间整理和搬移等GC动作,和所有的GC机制一样,在JFFS2里的GC会对瞬时的读写性能有一定影响。另外,为了有空间能
        被用来做空间整理,JFFS2会对每个分区预留3块左右的空间,这个空间是用户不可见的。
    4. 压缩机制:当前使用的JFFS2,底层会自动的在每次读/写时进行解压/压缩动作,实际IO的大小和用户请求读写的大小
        并不会一样。特别在写入时,不能通过写入大小来和flash剩余空间的大小来预估写入一定会成功或者失败。
    5. 硬链接机制:JFFS2支持硬链接,底层实际占用的物理空间是一份,对于同一个文件的多个硬连接,并不会增加空间的占用;
        反之,只有当删除了所有的硬链接时,实际物理空间才会被释放。
 开发指导
    对于基于JFFS2和nor flash的开发,总体而言,与其他文件系统非常相似,因为都有VFS层来屏蔽了具体文件系统的差异,
    对外接口体现也都是标准的POSIX接口。

    对于整个裸nor flash设备而言,没有集中的地方来管理和记录分区的信息。因此,需要通过其他的配置方式来传递这部分信息
    (当前使用的方式是在烧写镜像的时候,使用bootargs参数配置的),然后在代码中调用相应的接口来添加分区,再进行挂载动作。  
版本
作者
weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
日期
2021-11-22

在文件 vfs_jffs2.c 中定义.

函数说明

◆ FSMAP_ENTRY()

FSMAP_ENTRY ( jffs_fsmap  ,
"jffs2"  ,
jffs_operations  ,
TRUE  ,
TRUE   
)

◆ Jffs2CurSec()

time_t Jffs2CurSec ( void  )

在文件 vfs_jffs2.c130 行定义.

131{
132 struct timeval tv;
133 if (gettimeofday(&tv, NULL))
134 return 0;
135 return (uint32_t)(tv.tv_sec);
136}
int gettimeofday(struct timeval *tv, void *_tz) int gettimeofday(struct timeval *tv
gettimeofday
函数调用图:
这是这个函数的调用关系图:

◆ Jffs2MutexCreate()

int Jffs2MutexCreate ( void  )

在文件 vfs_jffs2.c1009 行定义.

1010{
1011 if (LOS_MuxInit(&g_jffs2FsLock, NULL) != LOS_OK) {
1012 PRINT_ERR("%s, LOS_MuxCreate failed\n", __FUNCTION__);
1013 return -1;
1014 } else {
1015 return 0;
1016 }
1017}
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
Definition: los_mux.c:262
static LosMux g_jffs2FsLock
Definition: vfs_jffs2.c:107
函数调用图:

◆ Jffs2MutexDelete()

void Jffs2MutexDelete ( void  )

在文件 vfs_jffs2.c1019 行定义.

1020{
1022}
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
销毁互斥锁
Definition: los_mux.c:289
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
函数调用图:

◆ Jffs2NodeLock()

void Jffs2NodeLock ( void  )

在文件 vfs_jffs2.c138 行定义.

139{
141}
int pthread_mutex_lock(pthread_mutex_t *mutex)
互斥锁加锁操作
static pthread_mutex_t g_jffs2NodeLock
Definition: vfs_jffs2.c:109
函数调用图:

◆ Jffs2NodeUnlock()

void Jffs2NodeUnlock ( void  )

在文件 vfs_jffs2.c143 行定义.

144{
146}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
解锁互斥锁
函数调用图:

◆ Jffs2SetVtype()

static void Jffs2SetVtype ( struct jffs2_inode *  node,
struct Vnode pVnode 
)
static

设置vnode节点的文件类型

在文件 vfs_jffs2.c112 行定义.

113{
114 switch (node->i_mode & S_IFMT) {
115 case S_IFREG:
116 pVnode->type = VNODE_TYPE_REG; // 普通文件
117 break;
118 case S_IFDIR:
119 pVnode->type = VNODE_TYPE_DIR; // 目录/文件夹
120 break;
121 case S_IFLNK:
122 pVnode->type = VNODE_TYPE_LNK; // 软链接
123 break;
124 default:
125 pVnode->type = VNODE_TYPE_UNKNOWN;
126 break;
127 }
128}
enum VnodeType type
Definition: vnode.h:165
@ VNODE_TYPE_LNK
Definition: vnode.h:142
@ VNODE_TYPE_DIR
Definition: vnode.h:137
@ VNODE_TYPE_UNKNOWN
Definition: vnode.h:135
@ VNODE_TYPE_REG
Definition: vnode.h:136
这是这个函数的调用关系图:

◆ Jffs2Truncate()

static int Jffs2Truncate ( struct Vnode pVnode,
unsigned int  len 
)
static

在文件 vfs_jffs2.c698 行定义.

699{
700 int ret;
701 struct IATTR attr = {0};
702
703 attr.attr_chg_size = len;
704 attr.attr_chg_valid = CHG_SIZE;
705
706 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
707 ret = jffs2_setattr((struct jffs2_inode *)pVnode->data, &attr);
709 return ret;
710}
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
释放锁
Definition: los_mux.c:559
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
拿互斥锁,
Definition: los_mux.c:437
此结构用于记录 vnode 的属性
Definition: vnode.h:81
unsigned attr_chg_size
节点大小
Definition: vnode.h:88
unsigned int attr_chg_valid
节点改变有效性 (CHG_MODE | CHG_UID | ... )
Definition: vnode.h:83
void * data
Definition: vnode.h:176
函数调用图:
这是这个函数的调用关系图:

◆ VfsJffs2Bind()

int VfsJffs2Bind ( struct Mount mnt,
struct Vnode blkDriver,
const void data 
)

VfsJffs2Bind 挂载JFFS2分区

    运行命令:
        OHOS # mount /dev/spinorblk1 /jffs1 jffs2
    将从串口得到如下回应信息,表明挂载成功。
    OHOS # mount /dev/spinorblk1 /jffs1 jffs2
    mount OK
    挂载成功后,用户就能对norflash进行读写操作。  
参数
blkDriver
data
mnt
返回

参见

在文件 vfs_jffs2.c165 行定义.

166{
167 int ret;
168 int partNo;
169 mtd_partition *p = NULL;
170 struct MtdDev *mtd = NULL;
171 struct Vnode *pv = NULL;
172 struct jffs2_inode *rootNode = NULL;
173
174 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
175 p = (mtd_partition *)((struct drv_data *)blkDriver->data)->priv; //分区结构
176 mtd = (struct MtdDev *)(p->mtd_info);//分区信息
177
178 /* find a empty mte in partition table */
179 if (mtd == NULL || mtd->type != MTD_NORFLASH) {
181 return -EINVAL;
182 }
183
184 partNo = p->patitionnum;
185
186 ret = jffs2_mount(partNo, &rootNode, mnt->mountFlags);
187 if (ret != 0) {
189 return ret;
190 }
191
192 ret = VnodeAlloc(&g_jffs2Vops, &pv);
193 if (ret != 0) {
195 goto ERROR_WITH_VNODE;
196 }
197 pv->type = VNODE_TYPE_DIR;
198 pv->data = (void *)rootNode;
199 pv->originMount = mnt;
200 pv->fop = &g_jffs2Fops;
201 mnt->data = p;
202 mnt->vnodeCovered = pv;
203 pv->uid = rootNode->i_uid;
204 pv->gid = rootNode->i_gid;
205 pv->mode = rootNode->i_mode;
206
207 (void)VfsHashInsert(pv, rootNode->i_ino);
208
209 g_jffs2PartList[partNo] = blkDriver;
210
212
213 return 0;
214ERROR_WITH_VNODE:
215 return ret;
216}
void * data
Definition: mount.h:78
struct Vnode * vnodeCovered
Definition: mount.h:72
unsigned long mountFlags
Definition: mount.h:80
flash MTD 层 描述符
Definition: mtd_dev.h:76
UINT32 type
Definition: mtd_dev.h:78
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
uint gid
Definition: vnode.h:169
mode_t mode
Definition: vnode.h:170
struct file_operations_vfs * fop
Definition: vnode.h:175
struct Mount * originMount
Definition: vnode.h:180
uint uid
Definition: vnode.h:168
通过mknod在/dev子目录下建立MTD块设备节点(主设备号为31)和MTD字符设备节点(主设备号为90)
UINT32 patitionnum
分区编号
VOID * mtd_info
int VfsHashInsert(struct Vnode *vnode, uint32_t hash)
插入哈希表
Definition: vnode_hash.c:128
int VnodeAlloc(struct VnodeOps *vop, struct Vnode **vnode)
申请分配一个 vnode 节点,vop为操作节点的驱动程序
Definition: vnode.c:166
struct Vnode * g_jffs2PartList[CONFIG_MTD_PATTITION_NUM]
Definition: vfs_jffs2.c:110
struct VnodeOps g_jffs2Vops
jffs2 关于vnode操作接口实现
Definition: vfs_jffs2.c:104
struct file_operations_vfs g_jffs2Fops
jffs2 关于vfs接口实现
Definition: vfs_jffs2.c:105
函数调用图:

◆ VfsJffs2Chattr()

int VfsJffs2Chattr ( struct Vnode pVnode,
struct IATTR attr 
)

在文件 vfs_jffs2.c724 行定义.

725{
726 int ret;
727 struct jffs2_inode *node = NULL;
728
729 if (pVnode == NULL) {
730 return -EINVAL;
731 }
732
733 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
734
735 node = pVnode->data;
736 ret = jffs2_setattr(node, attr);
737 if (ret == 0) {
738 pVnode->uid = node->i_uid;
739 pVnode->gid = node->i_gid;
740 pVnode->mode = node->i_mode;
741 }
743 return ret;
744}
函数调用图:

◆ VfsJffs2Close()

int VfsJffs2Close ( struct file filep)

在文件 vfs_jffs2.c350 行定义.

351{
352 return 0;
353}

◆ VfsJffs2Closedir()

int VfsJffs2Closedir ( struct Vnode node,
struct fs_dirent_s *  dir 
)

在文件 vfs_jffs2.c655 行定义.

656{
657 return 0;
658}

◆ VfsJffs2Create()

int VfsJffs2Create ( struct Vnode parentVnode,
const char *  path,
int  mode,
struct Vnode **  ppVnode 
)

创建一个jffs2 索引节点

在文件 vfs_jffs2.c314 行定义.

315{
316 int ret;
317 struct jffs2_inode *newNode = NULL;
318 struct Vnode *newVnode = NULL;
319
320 ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
321 if (ret != 0) {
322 return -ENOMEM;
323 }
324
325 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
326 ret = jffs2_create((struct jffs2_inode *)parentVnode->data, (const unsigned char *)path, mode, &newNode);
327 if (ret != 0) {
328 VnodeFree(newVnode);
330 return ret;
331 }
332
333 newVnode->type = VNODE_TYPE_REG;
334 newVnode->fop = parentVnode->fop;
335 newVnode->data = newNode;
336 newVnode->parent = parentVnode;
337 newVnode->originMount = parentVnode->originMount;
338 newVnode->uid = newNode->i_uid;
339 newVnode->gid = newNode->i_gid;
340 newVnode->mode = newNode->i_mode;
341
342 (void)VfsHashInsert(newVnode, newNode->i_ino);
343
344 *ppVnode = newVnode;
345
347 return 0;
348}
struct Vnode * parent
Definition: vnode.h:173
int VnodeFree(struct Vnode *vnode)
是否 vnode 节点
Definition: vnode.c:212
函数调用图:

◆ VfsJffs2Dup()

int VfsJffs2Dup ( const struct file oldFile,
struct file newFile 
)

在文件 vfs_jffs2.c608 行定义.

609{
610 PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
611 return -ENOSYS;
612}

◆ VfsJffs2Fsync()

int VfsJffs2Fsync ( struct file filep)

在文件 vfs_jffs2.c601 行定义.

602{
603 /* jffs2_write directly write to flash, sync is OK.
604 BUT after pagecache enabled, pages need to be flushed to flash */
605 return 0;
606}

◆ VfsJffs2Ioctl()

int VfsJffs2Ioctl ( struct file filep,
int  cmd,
unsigned long  arg 
)

在文件 vfs_jffs2.c595 行定义.

596{
597 PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
598 return -ENOSYS;
599}

◆ VfsJffs2Link()

int VfsJffs2Link ( struct Vnode oldVnode,
struct Vnode newParentVnode,
struct Vnode **  newVnode,
const char *  newName 
)

在文件 vfs_jffs2.c771 行定义.

772{
773 int ret;
774 struct jffs2_inode *oldInode = oldVnode->data;
775 struct jffs2_inode *newParentInode = newParentVnode->data;
776 struct Vnode *pVnode = NULL;
777
778 ret = VnodeAlloc(&g_jffs2Vops, &pVnode);
779 if (ret != 0) {
780 return -ENOMEM;
781 }
782
783 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
784 ret = jffs2_link(oldInode, newParentInode, (const unsigned char *)newName);
785 if (ret != 0) {
787 VnodeFree(pVnode);
788 return ret;
789 }
790
791 pVnode->type = VNODE_TYPE_REG;
792 pVnode->fop = &g_jffs2Fops;
793 pVnode->parent = newParentVnode;
794 pVnode->originMount = newParentVnode->originMount;
795 pVnode->data = oldInode;
796 pVnode->uid = oldVnode->uid;
797 pVnode->gid = oldVnode->gid;
798 pVnode->mode = oldVnode->mode;
799
800 *newVnode = pVnode;
801 (void)VfsHashInsert(*newVnode, oldInode->i_ino);
802
804 return ret;
805}
函数调用图:

◆ VfsJffs2Lookup()

int VfsJffs2Lookup ( struct Vnode parentVnode,
const char *  path,
int  len,
struct Vnode **  ppVnode 
)

在文件 vfs_jffs2.c263 行定义.

264{
265 int ret;
266 struct Vnode *newVnode = NULL;
267 struct jffs2_inode *node = NULL;
268 struct jffs2_inode *parentNode = NULL;
269
270 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
271
272 parentNode = (struct jffs2_inode *)parentVnode->data;//获取私有数据
273 node = jffs2_lookup(parentNode, (const unsigned char *)path, len);
274 if (!node) {
276 return -ENOENT;
277 }
278
279 (void)VfsHashGet(parentVnode->originMount, node->i_ino, &newVnode, NULL, NULL);
280 if (newVnode) {
281 if (newVnode->data == NULL) {
282 LOS_Panic("#####VfsHashGet error#####\n");
283 }
284 newVnode->parent = parentVnode;
285 *ppVnode = newVnode;
287 return 0;
288 }
289 ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
290 if (ret != 0) {
291 PRINT_ERR("%s-%d, ret: %x\n", __FUNCTION__, __LINE__, ret);
292 (void)jffs2_iput(node);
294 return ret;
295 }
296
297 Jffs2SetVtype(node, newVnode);
298 newVnode->fop = parentVnode->fop;
299 newVnode->data = node;
300 newVnode->parent = parentVnode;
301 newVnode->originMount = parentVnode->originMount;
302 newVnode->uid = node->i_uid;
303 newVnode->gid = node->i_gid;
304 newVnode->mode = node->i_mode;
305
306 (void)VfsHashInsert(newVnode, node->i_ino);
307
308 *ppVnode = newVnode;
309
311 return 0;
312}
NORETURN VOID LOS_Panic(const CHAR *fmt,...)
Kernel panic function.
int VfsHashGet(const struct Mount *mount, uint32_t hash, struct Vnode **vnode, VfsHashCmp *fun, void *arg)
通过哈希值获取节点信息
Definition: vnode_hash.c:89
static void Jffs2SetVtype(struct jffs2_inode *node, struct Vnode *pVnode)
设置vnode节点的文件类型
Definition: vfs_jffs2.c:112
函数调用图:
这是这个函数的调用关系图:

◆ VfsJffs2Mkdir()

int VfsJffs2Mkdir ( struct Vnode parentNode,
const char *  dirName,
mode_t  mode,
struct Vnode **  ppVnode 
)

在文件 vfs_jffs2.c660 行定义.

661{
662 int ret;
663 struct jffs2_inode *node = NULL;
664 struct Vnode *newVnode = NULL;
665
666 ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
667 if (ret != 0) {
668 return -ENOMEM;
669 }
670
671 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
672
673 ret = jffs2_mkdir((struct jffs2_inode *)parentNode->data, (const unsigned char *)dirName, mode, &node);
674 if (ret != 0) {
676 VnodeFree(newVnode);
677 return ret;
678 }
679
680 newVnode->type = VNODE_TYPE_DIR;
681 newVnode->fop = parentNode->fop;
682 newVnode->data = node;
683 newVnode->parent = parentNode;
684 newVnode->originMount = parentNode->originMount;
685 newVnode->uid = node->i_uid;
686 newVnode->gid = node->i_gid;
687 newVnode->mode = node->i_mode;
688
689 *ppVnode = newVnode;
690
691 (void)VfsHashInsert(newVnode, node->i_ino);
692
694
695 return 0;
696}
函数调用图:

◆ VfsJffs2Opendir()

int VfsJffs2Opendir ( struct Vnode pVnode,
struct fs_dirent_s *  dir 
)

在文件 vfs_jffs2.c614 行定义.

615{
616 dir->fd_int_offset = 0;
617 return 0;
618}

◆ VfsJffs2Read()

ssize_t VfsJffs2Read ( struct file filep,
char *  buffer,
size_t  bufLen 
)

在文件 vfs_jffs2.c382 行定义.

383{
384 struct jffs2_inode *node = NULL;
385 struct jffs2_inode_info *f = NULL;
386 struct jffs2_sb_info *c = NULL;
387 int ret;
388
389 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
390
391 node = (struct jffs2_inode *)filep->f_vnode->data;
392 f = JFFS2_INODE_INFO(node);
393 c = JFFS2_SB_INFO(node->i_sb);
394
395 off_t pos = min(node->i_size, filep->f_pos);
396 off_t len = min(bufLen, (node->i_size - pos));
397 ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, filep->f_pos, len);
398 if (ret) {
400 return ret;
401 }
402 node->i_atime = Jffs2CurSec();
403 filep->f_pos += len;
404
406
407 return len;
408}
loff_t f_pos
time_t Jffs2CurSec(void)
Definition: vfs_jffs2.c:130
函数调用图:

◆ VfsJffs2Readdir()

int VfsJffs2Readdir ( struct Vnode pVnode,
struct fs_dirent_s *  dir 
)

在文件 vfs_jffs2.c620 行定义.

621{
622 int ret;
623 int i = 0;
624
625 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
626
627 /* set jffs2_d */
628 while (i < dir->read_cnt) {
629 ret = jffs2_readdir((struct jffs2_inode *)pVnode->data, &dir->fd_position,
630 &dir->fd_int_offset, &dir->fd_dir[i]);
631 if (ret) {
632 break;
633 }
634
635 i++;
636 }
637
639
640 return i;
641}
函数调用图:

◆ VfsJffs2Readlink()

ssize_t VfsJffs2Readlink ( struct Vnode vnode,
char *  buffer,
size_t  bufLen 
)

在文件 vfs_jffs2.c842 行定义.

843{
844 struct jffs2_inode *inode = NULL;
845 struct jffs2_inode_info *f = NULL;
846 ssize_t targetLen;
847 ssize_t cnt;
848
849 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
850
851 inode = (struct jffs2_inode *)vnode->data;
852 f = JFFS2_INODE_INFO(inode);
853 targetLen = strlen((const char *)f->target);
854 if (bufLen == 0) {
856 return 0;
857 }
858
859 cnt = (bufLen - 1) < targetLen ? (bufLen - 1) : targetLen;
860 if (LOS_CopyFromKernel(buffer, bufLen, (const char *)f->target, cnt) != 0) {
861 cnt = 0;
863 return -EFAULT;
864 }
865 buffer[cnt] = '\0';
866
868
869 return cnt;
870}
INT64 ssize_t
Definition: los_typedef.h:79
INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将内核数据拷贝到用户空间
Definition: user_copy.c:88
函数调用图:

◆ VfsJffs2ReadPage()

ssize_t VfsJffs2ReadPage ( struct Vnode vnode,
char *  buffer,
off_t  off 
)

在文件 vfs_jffs2.c355 行定义.

356{
357 struct jffs2_inode *node = NULL;
358 struct jffs2_inode_info *f = NULL;
359 struct jffs2_sb_info *c = NULL;
360 int ret;
361
362 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
363
364 node = (struct jffs2_inode *)vnode->data;
365 f = JFFS2_INODE_INFO(node);
366 c = JFFS2_SB_INFO(node->i_sb);
367
368 off_t pos = min(node->i_size, off);
369 ssize_t len = min(PAGE_SIZE, (node->i_size - pos));
370 ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, off, len);
371 if (ret) {
373 return ret;
374 }
375 node->i_atime = Jffs2CurSec();
376
378
379 return len;
380}
函数调用图:

◆ VfsJffs2Reclaim()

int VfsJffs2Reclaim ( struct Vnode pVnode)

在文件 vfs_jffs2.c975 行定义.

976{
977 return 0;
978}

◆ VfsJffs2Rename()

int VfsJffs2Rename ( struct Vnode fromVnode,
struct Vnode toParentVnode,
const char *  fromName,
const char *  toName 
)

在文件 vfs_jffs2.c898 行定义.

899{
900 int ret;
901 struct Vnode *fromParentVnode = NULL;
902 struct Vnode *toVnode = NULL;
903 struct jffs2_inode *fromNode = NULL;
904
905 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
906 fromParentVnode = fromVnode->parent;
907
908 ret = VfsJffs2Lookup(toParentVnode, toName, strlen(toName), &toVnode);
909 if (ret == 0) {
910 if (toVnode->type == VNODE_TYPE_DIR) {
911 ret = VfsJffs2Rmdir(toParentVnode, toVnode, (char *)toName);
912 } else {
913 ret = VfsJffs2Unlink(toParentVnode, toVnode, (char *)toName);
914 }
915 if (ret) {
916 PRINTK("%s-%d remove newname(%s) failed ret=%d\n", __FUNCTION__, __LINE__, toName, ret);
918 return ret;
919 }
920 }
921 fromNode = (struct jffs2_inode *)fromVnode->data;
922 ret = jffs2_rename((struct jffs2_inode *)fromParentVnode->data, fromNode,
923 (const unsigned char *)fromName, (struct jffs2_inode *)toParentVnode->data, (const unsigned char *)toName);
924 fromVnode->parent = toParentVnode;
926
927 if (ret) {
928 return ret;
929 }
930
931 return 0;
932}
int VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode)
Definition: vfs_jffs2.c:263
int VfsJffs2Unlink(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
Definition: vfs_jffs2.c:872
int VfsJffs2Rmdir(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
Definition: vfs_jffs2.c:746
函数调用图:

◆ VfsJffs2Rewinddir()

int VfsJffs2Rewinddir ( struct Vnode pVnode,
struct fs_dirent_s *  dir 
)

在文件 vfs_jffs2.c648 行定义.

649{
650 dir->fd_int_offset = 0;
651
652 return 0;
653}

◆ VfsJffs2Rmdir()

int VfsJffs2Rmdir ( struct Vnode parentVnode,
struct Vnode targetVnode,
const char *  path 
)

在文件 vfs_jffs2.c746 行定义.

747{
748 int ret;
749 struct jffs2_inode *parentInode = NULL;
750 struct jffs2_inode *targetInode = NULL;
751
752 if (!parentVnode || !targetVnode) {
753 return -EINVAL;
754 }
755
756 parentInode = (struct jffs2_inode *)parentVnode->data;
757 targetInode = (struct jffs2_inode *)targetVnode->data;
758
759 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
760
761 ret = jffs2_rmdir(parentInode, targetInode, (const unsigned char *)path);
762
763 if (ret == 0) {
764 (void)jffs2_iput(targetInode);
765 }
766
768 return ret;
769}
函数调用图:
这是这个函数的调用关系图:

◆ VfsJffs2Seek()

off_t VfsJffs2Seek ( struct file filep,
off_t  offset,
int  whence 
)

在文件 vfs_jffs2.c559 行定义.

560{
561 struct jffs2_inode *node = NULL;
562 loff_t filePos;
563
564 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
565
566 node = (struct jffs2_inode *)filep->f_vnode->data;
567 filePos = filep->f_pos;
568
569 switch (whence) {
570 case SEEK_SET:
571 filePos = offset;
572 break;
573
574 case SEEK_CUR:
575 filePos += offset;
576 break;
577
578 case SEEK_END:
579 filePos = node->i_size + offset;
580 break;
581
582 default:
584 return -EINVAL;
585 }
586
588
589 if (filePos < 0)
590 return -EINVAL;
591
592 return filePos;
593}
函数调用图:

◆ VfsJffs2Seekdir()

int VfsJffs2Seekdir ( struct Vnode pVnode,
struct fs_dirent_s *  dir,
unsigned long  offset 
)

在文件 vfs_jffs2.c643 行定义.

644{
645 return 0;
646}

◆ VfsJffs2Stat()

int VfsJffs2Stat ( struct Vnode pVnode,
struct stat *  buf 
)

在文件 vfs_jffs2.c934 行定义.

935{
936 struct jffs2_inode *node = NULL;
937
938 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
939
940 node = (struct jffs2_inode *)pVnode->data;
941 switch (node->i_mode & S_IFMT) {
942 case S_IFREG:
943 case S_IFDIR:
944 case S_IFLNK:
945 buf->st_mode = node->i_mode;
946 break;
947
948 default:
949 buf->st_mode = DT_UNKNOWN;
950 break;
951 }
952
953 buf->st_dev = 0;
954 buf->st_ino = node->i_ino;
955 buf->st_nlink = node->i_nlink;
956 buf->st_uid = node->i_uid;
957 buf->st_gid = node->i_gid;
958 buf->st_size = node->i_size;
959 buf->st_blksize = BLOCK_SIZE;
960 buf->st_blocks = buf->st_size / buf->st_blksize;
961 buf->st_atime = node->i_atime;
962 buf->st_mtime = node->i_mtime;
963 buf->st_ctime = node->i_ctime;
964
965 /* Adapt to kstat member long tv_sec */
966 buf->__st_atim32.tv_sec = (long)node->i_atime;
967 buf->__st_mtim32.tv_sec = (long)node->i_mtime;
968 buf->__st_ctim32.tv_sec = (long)node->i_ctime;
969
971
972 return 0;
973}
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 ARG_NUM_1 ARG_NUM_4 ARG_NUM_4 ARG_NUM_5 ARG_NUM_3 ARG_NUM_2 void ARG_NUM_6 unsigned ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_3 ARG_NUM_3 ARG_NUM_2 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_1 char ARG_NUM_0 ARG_NUM_4 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_2 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_6 ARG_NUM_6 ARG_NUM_5 ARG_NUM_3 void ARG_NUM_3 ARG_NUM_3 ARG_NUM_5 ARG_NUM_1 unsigned ARG_NUM_3 long
函数调用图:

◆ VfsJffs2Statfs()

int VfsJffs2Statfs ( struct Mount mnt,
struct statfs *  buf 
)

在文件 vfs_jffs2.c980 行定义.

981{
982 unsigned long freeSize;
983 struct jffs2_sb_info *c = NULL;
984 struct jffs2_inode *rootNode = NULL;
985
986 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
987
988 rootNode = (struct jffs2_inode *)mnt->vnodeCovered->data;
989 c = JFFS2_SB_INFO(rootNode->i_sb);
990
991 freeSize = c->free_size + c->dirty_size;
992 buf->f_type = JFFS2_SUPER_MAGIC;
993 buf->f_bsize = PAGE_SIZE;
994 buf->f_blocks = (((uint64_t)c->nr_blocks) * c->sector_size) / PAGE_SIZE;
995 buf->f_bfree = freeSize / PAGE_SIZE;
996 buf->f_bavail = buf->f_bfree;
997 buf->f_namelen = NAME_MAX;
998 buf->f_fsid.__val[0] = JFFS2_SUPER_MAGIC;
999 buf->f_fsid.__val[1] = 1;
1000 buf->f_frsize = BLOCK_SIZE;
1001 buf->f_files = 0;
1002 buf->f_ffree = 0;
1003 buf->f_flags = mnt->mountFlags;
1004
1006 return 0;
1007}
函数调用图:

◆ VfsJffs2Symlink()

int VfsJffs2Symlink ( struct Vnode parentVnode,
struct Vnode **  newVnode,
const char *  path,
const char *  target 
)

在文件 vfs_jffs2.c807 行定义.

808{
809 int ret;
810 struct jffs2_inode *inode = NULL;
811 struct Vnode *pVnode = NULL;
812
813 ret = VnodeAlloc(&g_jffs2Vops, &pVnode);
814 if (ret != 0) {
815 return -ENOMEM;
816 }
817
818 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
819 ret = jffs2_symlink((struct jffs2_inode *)parentVnode->data, &inode, (const unsigned char *)path, target);
820 if (ret != 0) {
822 VnodeFree(pVnode);
823 return ret;
824 }
825
826 pVnode->type = VNODE_TYPE_LNK;
827 pVnode->fop = &g_jffs2Fops;
828 pVnode->parent = parentVnode;
829 pVnode->originMount = parentVnode->originMount;
830 pVnode->data = inode;
831 pVnode->uid = inode->i_uid;
832 pVnode->gid = inode->i_gid;
833 pVnode->mode = inode->i_mode;
834
835 *newVnode = pVnode;
836 (void)VfsHashInsert(*newVnode, inode->i_ino);
837
839 return ret;
840}
函数调用图:

◆ VfsJffs2Truncate()

int VfsJffs2Truncate ( struct Vnode pVnode,
off_t  len 
)

在文件 vfs_jffs2.c712 行定义.

713{
714 int ret = Jffs2Truncate(pVnode, (unsigned int)len);
715 return ret;
716}
static int Jffs2Truncate(struct Vnode *pVnode, unsigned int len)
Definition: vfs_jffs2.c:698
函数调用图:

◆ VfsJffs2Truncate64()

int VfsJffs2Truncate64 ( struct Vnode pVnode,
off64_t  len 
)

在文件 vfs_jffs2.c718 行定义.

719{
720 int ret = Jffs2Truncate(pVnode, (unsigned int)len);
721 return ret;
722}
函数调用图:

◆ VfsJffs2Unbind()

int VfsJffs2Unbind ( struct Mount mnt,
struct Vnode **  blkDriver 
)

VfsJffs2Unbind 卸载JFFS2分区

    调用int umount(const char *target)函数卸载分区,只需要正确给出挂载点即可。
   运行命令:
   OHOS # umount /jffs1
   将从串口得到如下回应信息,表明卸载成功。
    OHOS # umount /jffs1
    umount ok
参数
blkDriver
mnt
返回

参见

在文件 vfs_jffs2.c234 行定义.

235{
236 int ret;
237 mtd_partition *p = NULL;
238 int partNo;
239
240 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
241
242 p = (mtd_partition *)mnt->data;
243 if (p == NULL) {
245 return -EINVAL;
246 }
247
248 partNo = p->patitionnum;
249 ret = jffs2_umount((struct jffs2_inode *)mnt->vnodeCovered->data);
250 if (ret) {
252 return ret;
253 }
254
256 p->mountpoint_name = NULL;
257 *blkDriver = g_jffs2PartList[partNo];
258
260 return 0;
261}
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
CHAR * mountpoint_name
挂载点名称 例如: /
if(tv==NULL)
Definition: time.c:430
函数调用图:

◆ VfsJffs2Unlink()

int VfsJffs2Unlink ( struct Vnode parentVnode,
struct Vnode targetVnode,
const char *  path 
)

在文件 vfs_jffs2.c872 行定义.

873{
874 int ret;
875 struct jffs2_inode *parentInode = NULL;
876 struct jffs2_inode *targetInode = NULL;
877
878 if (!parentVnode || !targetVnode) {
879 PRINTK("%s-%d parentVnode=%x, targetVnode=%x\n", __FUNCTION__, __LINE__, parentVnode, targetVnode);
880 return -EINVAL;
881 }
882
883 parentInode = (struct jffs2_inode *)parentVnode->data;
884 targetInode = (struct jffs2_inode *)targetVnode->data;
885
886 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
887
888 ret = jffs2_unlink(parentInode, targetInode, (const unsigned char *)path);
889
890 if (ret == 0) {
891 (void)jffs2_iput(targetInode);
892 }
893
895 return ret;
896}
函数调用图:
这是这个函数的调用关系图:

◆ VfsJffs2Write()

ssize_t VfsJffs2Write ( struct file filep,
const char *  buffer,
size_t  bufLen 
)

在文件 vfs_jffs2.c463 行定义.

464{
465 struct jffs2_inode *node = NULL;
466 struct jffs2_inode_info *f = NULL;
467 struct jffs2_sb_info *c = NULL;
468 struct jffs2_raw_inode ri = {0};
469 struct IATTR attr = {0};
470 int ret;
471 off_t pos;
472 uint32_t writtenLen;
473
474 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
475
476 node = (struct jffs2_inode *)filep->f_vnode->data;
477 f = JFFS2_INODE_INFO(node);
478 c = JFFS2_SB_INFO(node->i_sb);
479 pos = filep->f_pos;
480
481#ifdef LOSCFG_KERNEL_SMP
482 struct super_block *sb = node->i_sb;
483 UINT16 gcCpuMask = LOS_TaskCpuAffiGet(sb->s_gc_thread);
484 UINT32 curTaskId = LOS_CurTaskIDGet();
485 UINT16 curCpuMask = LOS_TaskCpuAffiGet(curTaskId);
486 if (curCpuMask != gcCpuMask) {
487 if (curCpuMask != LOSCFG_KERNEL_CPU_MASK) {
488 (void)LOS_TaskCpuAffiSet(sb->s_gc_thread, curCpuMask);
489 } else {
490 (void)LOS_TaskCpuAffiSet(curTaskId, gcCpuMask);
491 }
492 }
493#endif
494 if (pos < 0) {
496 return -EINVAL;
497 }
498
499 ri.ino = cpu_to_je32(f->inocache->ino);
500 ri.mode = cpu_to_jemode(node->i_mode);
501 ri.uid = cpu_to_je16(node->i_uid);
502 ri.gid = cpu_to_je16(node->i_gid);
503 ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
504
505 if (pos > node->i_size) {
506 int err;
507 attr.attr_chg_valid = CHG_SIZE;
508 attr.attr_chg_size = pos;
509 err = jffs2_setattr(node, &attr);
510 if (err) {
512 return err;
513 }
514 }
515 ri.isize = cpu_to_je32(node->i_size);
516
517 ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, bufLen, &writtenLen);
518 if (ret) {
519 pos += writtenLen;
520
521 node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
522 if (pos > node->i_size)
523 node->i_size = pos;
524
525 filep->f_pos = pos;
526
528
529 return ret;
530 }
531
532 if (writtenLen != bufLen) {
533 pos += writtenLen;
534
535 node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
536 if (pos > node->i_size)
537 node->i_size = pos;
538
539 filep->f_pos = pos;
540
542
543 return -ENOSPC;
544 }
545
546 pos += bufLen;
547
548 node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
549 if (pos > node->i_size)
550 node->i_size = pos;
551
552 filep->f_pos = pos;
553
555
556 return writtenLen;
557}
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask)
Set the affinity mask of the task scheduling cpu.
Definition: los_task.c:1231
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
Obtain current running task ID.
Definition: los_task.c:331
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
查询任务被绑在哪个CPU上
Definition: los_task.c:1263
unsigned short UINT16
Definition: los_typedef.h:56
unsigned int UINT32
Definition: los_typedef.h:57
函数调用图:

◆ VfsJffs2WritePage()

ssize_t VfsJffs2WritePage ( struct Vnode vnode,
char *  buffer,
off_t  pos,
size_t  buflen 
)

在文件 vfs_jffs2.c410 行定义.

411{
412 struct jffs2_inode *node = NULL;
413 struct jffs2_inode_info *f = NULL;
414 struct jffs2_sb_info *c = NULL;
415 struct jffs2_raw_inode ri = {0};
416 struct IATTR attr = {0};
417 int ret;
418 uint32_t writtenLen;
419
420 LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
421
422 node = (struct jffs2_inode *)vnode->data;
423 f = JFFS2_INODE_INFO(node);
424 c = JFFS2_SB_INFO(node->i_sb);
425
426 if (pos < 0) {
428 return -EINVAL;
429 }
430
431 ri.ino = cpu_to_je32(f->inocache->ino);
432 ri.mode = cpu_to_jemode(node->i_mode);
433 ri.uid = cpu_to_je16(node->i_uid);
434 ri.gid = cpu_to_je16(node->i_gid);
435 ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
436
437 if (pos > node->i_size) {
438 int err;
439 attr.attr_chg_valid = CHG_SIZE;
440 attr.attr_chg_size = pos;
441 err = jffs2_setattr(node, &attr);
442 if (err) {
444 return err;
445 }
446 }
447 ri.isize = cpu_to_je32(node->i_size);
448
449 ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, buflen, &writtenLen);
450 if (ret) {
451 node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
453 return ret;
454 }
455
456 node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
457
459
460 return (ssize_t)writtenLen;
461}
函数调用图:

变量说明

◆ g_jffs2Fops

struct file_operations_vfs g_jffs2Fops
初始值:
= {
.read = VfsJffs2Read,
.write = VfsJffs2Write,
.mmap = OsVfsFileMmap,
.seek = VfsJffs2Seek,
.close = VfsJffs2Close,
.fsync = VfsJffs2Fsync,
}
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
ssize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
Definition: vfs_jffs2.c:382
int VfsJffs2Fsync(struct file *filep)
Definition: vfs_jffs2.c:601
off_t VfsJffs2Seek(struct file *filep, off_t offset, int whence)
Definition: vfs_jffs2.c:559
ssize_t VfsJffs2Write(struct file *filep, const char *buffer, size_t bufLen)
Definition: vfs_jffs2.c:463
int VfsJffs2Close(struct file *filep)
Definition: vfs_jffs2.c:350

jffs2 关于vfs接口实现

在文件 vfs_jffs2.c105 行定义.

◆ g_jffs2FsLock

LosMux g_jffs2FsLock
static

在文件 vfs_jffs2.c107 行定义.

◆ g_jffs2NodeLock

pthread_mutex_t g_jffs2NodeLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
static

在文件 vfs_jffs2.c109 行定义.

◆ g_jffs2PartList

struct Vnode* g_jffs2PartList[CONFIG_MTD_PATTITION_NUM]

jffs2 分区列表

在文件 vfs_jffs2.c110 行定义.

◆ g_jffs2Vops

struct VnodeOps g_jffs2Vops
初始值:
= {
.Lookup = VfsJffs2Lookup,
.Create = VfsJffs2Create,
.ReadPage = VfsJffs2ReadPage,
.WritePage = VfsJffs2WritePage,
.Rename = VfsJffs2Rename,
.Mkdir = VfsJffs2Mkdir,
.Getattr = VfsJffs2Stat,
.Opendir = VfsJffs2Opendir,
.Readdir = VfsJffs2Readdir,
.Closedir = VfsJffs2Closedir,
.Rewinddir = VfsJffs2Rewinddir,
.Unlink = VfsJffs2Unlink,
.Rmdir = VfsJffs2Rmdir,
.Chattr = VfsJffs2Chattr,
.Reclaim = VfsJffs2Reclaim,
.Truncate = VfsJffs2Truncate,
.Truncate64 = VfsJffs2Truncate64,
.Link = VfsJffs2Link,
.Symlink = VfsJffs2Symlink,
.Readlink = VfsJffs2Readlink,
}
int VfsJffs2Reclaim(struct Vnode *pVnode)
Definition: vfs_jffs2.c:975
int VfsJffs2Truncate64(struct Vnode *pVnode, off64_t len)
Definition: vfs_jffs2.c:718
int VfsJffs2Link(struct Vnode *oldVnode, struct Vnode *newParentVnode, struct Vnode **newVnode, const char *newName)
Definition: vfs_jffs2.c:771
int VfsJffs2Create(struct Vnode *parentVnode, const char *path, int mode, struct Vnode **ppVnode)
创建一个jffs2 索引节点
Definition: vfs_jffs2.c:314
ssize_t VfsJffs2Readlink(struct Vnode *vnode, char *buffer, size_t bufLen)
Definition: vfs_jffs2.c:842
int VfsJffs2Rewinddir(struct Vnode *pVnode, struct fs_dirent_s *dir)
Definition: vfs_jffs2.c:648
int VfsJffs2Mkdir(struct Vnode *parentNode, const char *dirName, mode_t mode, struct Vnode **ppVnode)
Definition: vfs_jffs2.c:660
int VfsJffs2Symlink(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target)
Definition: vfs_jffs2.c:807
int VfsJffs2Stat(struct Vnode *pVnode, struct stat *buf)
Definition: vfs_jffs2.c:934
int VfsJffs2Readdir(struct Vnode *pVnode, struct fs_dirent_s *dir)
Definition: vfs_jffs2.c:620
ssize_t VfsJffs2ReadPage(struct Vnode *vnode, char *buffer, off_t off)
Definition: vfs_jffs2.c:355
int VfsJffs2Truncate(struct Vnode *pVnode, off_t len)
Definition: vfs_jffs2.c:712
ssize_t VfsJffs2WritePage(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen)
Definition: vfs_jffs2.c:410
int VfsJffs2Rename(struct Vnode *fromVnode, struct Vnode *toParentVnode, const char *fromName, const char *toName)
Definition: vfs_jffs2.c:898
int VfsJffs2Opendir(struct Vnode *pVnode, struct fs_dirent_s *dir)
Definition: vfs_jffs2.c:614
int VfsJffs2Chattr(struct Vnode *pVnode, struct IATTR *attr)
Definition: vfs_jffs2.c:724
int VfsJffs2Closedir(struct Vnode *node, struct fs_dirent_s *dir)
Definition: vfs_jffs2.c:655

jffs2 关于vnode操作接口实现

在文件 vfs_jffs2.c104 行定义.

◆ jffs_operations

const struct MountOps jffs_operations
初始值:
= {
.Mount = VfsJffs2Bind,
.Unmount = VfsJffs2Unbind,
.Statfs = VfsJffs2Statfs,
}
int VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data)
VfsJffs2Bind 挂载JFFS2分区
Definition: vfs_jffs2.c:165
int VfsJffs2Statfs(struct Mount *mnt, struct statfs *buf)
Definition: vfs_jffs2.c:980
int VfsJffs2Unbind(struct Mount *mnt, struct Vnode **blkDriver)
VfsJffs2Unbind 卸载JFFS2分区
Definition: vfs_jffs2.c:234

在文件 vfs_jffs2.c1024 行定义.