10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci *
40d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
50d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
60d163575Sopenharmony_ci *
70d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
80d163575Sopenharmony_ci *    conditions and the following disclaimer.
90d163575Sopenharmony_ci *
100d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
110d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
120d163575Sopenharmony_ci *    provided with the distribution.
130d163575Sopenharmony_ci *
140d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
150d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
160d163575Sopenharmony_ci *    permission.
170d163575Sopenharmony_ci *
180d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
200d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
210d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
220d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
230d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
240d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
250d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
260d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
270d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
280d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
290d163575Sopenharmony_ci */
300d163575Sopenharmony_ci
310d163575Sopenharmony_ci#include "vfs_jffs2.h"
320d163575Sopenharmony_ci
330d163575Sopenharmony_ci#include "fcntl.h"
340d163575Sopenharmony_ci#include "sys/stat.h"
350d163575Sopenharmony_ci#include "sys/statfs.h"
360d163575Sopenharmony_ci#include "errno.h"
370d163575Sopenharmony_ci
380d163575Sopenharmony_ci#include "los_config.h"
390d163575Sopenharmony_ci#include "los_typedef.h"
400d163575Sopenharmony_ci#include "los_mux.h"
410d163575Sopenharmony_ci#include "los_tables.h"
420d163575Sopenharmony_ci#include "los_vm_filemap.h"
430d163575Sopenharmony_ci#include "los_crc32.h"
440d163575Sopenharmony_ci#include "capability_type.h"
450d163575Sopenharmony_ci#include "capability_api.h"
460d163575Sopenharmony_ci
470d163575Sopenharmony_ci#include "fs/dirent_fs.h"
480d163575Sopenharmony_ci#include "fs/fs.h"
490d163575Sopenharmony_ci#include "fs/driver.h"
500d163575Sopenharmony_ci#include "vnode.h"
510d163575Sopenharmony_ci#include "mtd_list.h"
520d163575Sopenharmony_ci#include "mtd_partition.h"
530d163575Sopenharmony_ci#include "jffs2_hash.h"
540d163575Sopenharmony_ci
550d163575Sopenharmony_ci#include "os-linux.h"
560d163575Sopenharmony_ci#include "jffs2/nodelist.h"
570d163575Sopenharmony_ci
580d163575Sopenharmony_ci#ifdef LOSCFG_FS_JFFS
590d163575Sopenharmony_ci
600d163575Sopenharmony_ci/* forward define */
610d163575Sopenharmony_cistruct VnodeOps g_jffs2Vops;
620d163575Sopenharmony_cistruct file_operations_vfs g_jffs2Fops;
630d163575Sopenharmony_ci
640d163575Sopenharmony_cistatic LosMux g_jffs2FsLock;  /* lock for all jffs2 ops */
650d163575Sopenharmony_ci
660d163575Sopenharmony_cistatic pthread_mutex_t g_jffs2NodeLock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
670d163575Sopenharmony_cistruct Vnode *g_jffs2PartList[CONFIG_MTD_PATTITION_NUM];
680d163575Sopenharmony_ci
690d163575Sopenharmony_cistatic void Jffs2SetVtype(struct jffs2_inode *node, struct Vnode *pVnode)
700d163575Sopenharmony_ci{
710d163575Sopenharmony_ci    switch (node->i_mode & S_IFMT) {
720d163575Sopenharmony_ci        case S_IFREG:
730d163575Sopenharmony_ci            pVnode->type = VNODE_TYPE_REG;
740d163575Sopenharmony_ci            break;
750d163575Sopenharmony_ci        case S_IFDIR:
760d163575Sopenharmony_ci            pVnode->type = VNODE_TYPE_DIR;
770d163575Sopenharmony_ci            break;
780d163575Sopenharmony_ci        case S_IFLNK:
790d163575Sopenharmony_ci            pVnode->type = VNODE_TYPE_LNK;
800d163575Sopenharmony_ci            break;
810d163575Sopenharmony_ci        default:
820d163575Sopenharmony_ci            pVnode->type = VNODE_TYPE_UNKNOWN;
830d163575Sopenharmony_ci            break;
840d163575Sopenharmony_ci    }
850d163575Sopenharmony_ci}
860d163575Sopenharmony_ci
870d163575Sopenharmony_citime_t Jffs2CurSec(void)
880d163575Sopenharmony_ci{
890d163575Sopenharmony_ci    struct timeval tv;
900d163575Sopenharmony_ci    if (gettimeofday(&tv, NULL))
910d163575Sopenharmony_ci        return 0;
920d163575Sopenharmony_ci    return (uint32_t)(tv.tv_sec);
930d163575Sopenharmony_ci}
940d163575Sopenharmony_ci
950d163575Sopenharmony_civoid Jffs2NodeLock(void)
960d163575Sopenharmony_ci{
970d163575Sopenharmony_ci    (void)pthread_mutex_lock(&g_jffs2NodeLock);
980d163575Sopenharmony_ci}
990d163575Sopenharmony_ci
1000d163575Sopenharmony_civoid Jffs2NodeUnlock(void)
1010d163575Sopenharmony_ci{
1020d163575Sopenharmony_ci    (void)pthread_mutex_unlock(&g_jffs2NodeLock);
1030d163575Sopenharmony_ci}
1040d163575Sopenharmony_ci
1050d163575Sopenharmony_ciint VfsJffs2Bind(struct Mount *mnt, struct Vnode *blkDriver, const void *data)
1060d163575Sopenharmony_ci{
1070d163575Sopenharmony_ci    int ret;
1080d163575Sopenharmony_ci    int partNo;
1090d163575Sopenharmony_ci    mtd_partition *p = NULL;
1100d163575Sopenharmony_ci    struct MtdDev *mtd = NULL;
1110d163575Sopenharmony_ci    struct Vnode *pv = NULL;
1120d163575Sopenharmony_ci    struct jffs2_inode *rootNode = NULL;
1130d163575Sopenharmony_ci
1140d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
1150d163575Sopenharmony_ci    p = (mtd_partition *)((struct drv_data *)blkDriver->data)->priv;
1160d163575Sopenharmony_ci    mtd = (struct MtdDev *)(p->mtd_info);
1170d163575Sopenharmony_ci
1180d163575Sopenharmony_ci    /* find a empty mte in partition table */
1190d163575Sopenharmony_ci    if (mtd == NULL || mtd->type != MTD_NORFLASH) {
1200d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
1210d163575Sopenharmony_ci        return -EINVAL;
1220d163575Sopenharmony_ci    }
1230d163575Sopenharmony_ci
1240d163575Sopenharmony_ci    partNo = p->patitionnum;
1250d163575Sopenharmony_ci
1260d163575Sopenharmony_ci    ret = jffs2_mount(partNo, &rootNode, mnt->mountFlags);
1270d163575Sopenharmony_ci    if (ret != 0) {
1280d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
1290d163575Sopenharmony_ci        return ret;
1300d163575Sopenharmony_ci    }
1310d163575Sopenharmony_ci
1320d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &pv);
1330d163575Sopenharmony_ci    if (ret != 0) {
1340d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
1350d163575Sopenharmony_ci        goto ERROR_WITH_VNODE;
1360d163575Sopenharmony_ci    }
1370d163575Sopenharmony_ci    pv->type = VNODE_TYPE_DIR;
1380d163575Sopenharmony_ci    pv->data = (void *)rootNode;
1390d163575Sopenharmony_ci    pv->originMount = mnt;
1400d163575Sopenharmony_ci    pv->fop = &g_jffs2Fops;
1410d163575Sopenharmony_ci    mnt->data = p;
1420d163575Sopenharmony_ci    mnt->vnodeCovered = pv;
1430d163575Sopenharmony_ci    pv->uid = rootNode->i_uid;
1440d163575Sopenharmony_ci    pv->gid = rootNode->i_gid;
1450d163575Sopenharmony_ci    pv->mode = rootNode->i_mode;
1460d163575Sopenharmony_ci
1470d163575Sopenharmony_ci    (void)VfsHashInsert(pv, rootNode->i_ino);
1480d163575Sopenharmony_ci
1490d163575Sopenharmony_ci    g_jffs2PartList[partNo] = blkDriver;
1500d163575Sopenharmony_ci
1510d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
1520d163575Sopenharmony_ci
1530d163575Sopenharmony_ci    return 0;
1540d163575Sopenharmony_ciERROR_WITH_VNODE:
1550d163575Sopenharmony_ci    return ret;
1560d163575Sopenharmony_ci}
1570d163575Sopenharmony_ci
1580d163575Sopenharmony_ciint VfsJffs2Unbind(struct Mount *mnt, struct Vnode **blkDriver)
1590d163575Sopenharmony_ci{
1600d163575Sopenharmony_ci    int ret;
1610d163575Sopenharmony_ci    mtd_partition *p = NULL;
1620d163575Sopenharmony_ci    int partNo;
1630d163575Sopenharmony_ci
1640d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
1650d163575Sopenharmony_ci
1660d163575Sopenharmony_ci    p = (mtd_partition *)mnt->data;
1670d163575Sopenharmony_ci    if (p == NULL) {
1680d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
1690d163575Sopenharmony_ci        return -EINVAL;
1700d163575Sopenharmony_ci    }
1710d163575Sopenharmony_ci
1720d163575Sopenharmony_ci    partNo = p->patitionnum;
1730d163575Sopenharmony_ci    ret = jffs2_umount((struct jffs2_inode *)mnt->vnodeCovered->data);
1740d163575Sopenharmony_ci    if (ret) {
1750d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
1760d163575Sopenharmony_ci        return ret;
1770d163575Sopenharmony_ci    }
1780d163575Sopenharmony_ci
1790d163575Sopenharmony_ci    free(p->mountpoint_name);
1800d163575Sopenharmony_ci    p->mountpoint_name = NULL;
1810d163575Sopenharmony_ci    *blkDriver = g_jffs2PartList[partNo];
1820d163575Sopenharmony_ci
1830d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
1840d163575Sopenharmony_ci    return 0;
1850d163575Sopenharmony_ci}
1860d163575Sopenharmony_ci
1870d163575Sopenharmony_ciint VfsJffs2Lookup(struct Vnode *parentVnode, const char *path, int len, struct Vnode **ppVnode)
1880d163575Sopenharmony_ci{
1890d163575Sopenharmony_ci    int ret;
1900d163575Sopenharmony_ci    struct Vnode *newVnode = NULL;
1910d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
1920d163575Sopenharmony_ci    struct jffs2_inode *parentNode = NULL;
1930d163575Sopenharmony_ci
1940d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
1950d163575Sopenharmony_ci
1960d163575Sopenharmony_ci    parentNode = (struct jffs2_inode *)parentVnode->data;
1970d163575Sopenharmony_ci    node = jffs2_lookup(parentNode, (const unsigned char *)path, len);
1980d163575Sopenharmony_ci    if (!node) {
1990d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
2000d163575Sopenharmony_ci        return -ENOENT;
2010d163575Sopenharmony_ci    }
2020d163575Sopenharmony_ci
2030d163575Sopenharmony_ci    (void)VfsHashGet(parentVnode->originMount, node->i_ino, &newVnode, NULL, NULL);
2040d163575Sopenharmony_ci    if (newVnode) {
2050d163575Sopenharmony_ci        if (newVnode->data == NULL) {
2060d163575Sopenharmony_ci            LOS_Panic("#####VfsHashGet error#####\n");
2070d163575Sopenharmony_ci        }
2080d163575Sopenharmony_ci        newVnode->parent = parentVnode;
2090d163575Sopenharmony_ci        *ppVnode = newVnode;
2100d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
2110d163575Sopenharmony_ci        return 0;
2120d163575Sopenharmony_ci    }
2130d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
2140d163575Sopenharmony_ci    if (ret != 0) {
2150d163575Sopenharmony_ci        PRINT_ERR("%s-%d, ret: %x\n", __FUNCTION__, __LINE__, ret);
2160d163575Sopenharmony_ci        (void)jffs2_iput(node);
2170d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
2180d163575Sopenharmony_ci        return ret;
2190d163575Sopenharmony_ci    }
2200d163575Sopenharmony_ci
2210d163575Sopenharmony_ci    Jffs2SetVtype(node, newVnode);
2220d163575Sopenharmony_ci    newVnode->fop = parentVnode->fop;
2230d163575Sopenharmony_ci    newVnode->data = node;
2240d163575Sopenharmony_ci    newVnode->parent = parentVnode;
2250d163575Sopenharmony_ci    newVnode->originMount = parentVnode->originMount;
2260d163575Sopenharmony_ci    newVnode->uid = node->i_uid;
2270d163575Sopenharmony_ci    newVnode->gid = node->i_gid;
2280d163575Sopenharmony_ci    newVnode->mode = node->i_mode;
2290d163575Sopenharmony_ci
2300d163575Sopenharmony_ci    (void)VfsHashInsert(newVnode, node->i_ino);
2310d163575Sopenharmony_ci
2320d163575Sopenharmony_ci    *ppVnode = newVnode;
2330d163575Sopenharmony_ci
2340d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
2350d163575Sopenharmony_ci    return 0;
2360d163575Sopenharmony_ci}
2370d163575Sopenharmony_ci
2380d163575Sopenharmony_ciint VfsJffs2Create(struct Vnode *parentVnode, const char *path, int mode, struct Vnode **ppVnode)
2390d163575Sopenharmony_ci{
2400d163575Sopenharmony_ci    int ret;
2410d163575Sopenharmony_ci    struct jffs2_inode *newNode = NULL;
2420d163575Sopenharmony_ci    struct Vnode *newVnode = NULL;
2430d163575Sopenharmony_ci
2440d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
2450d163575Sopenharmony_ci    if (ret != 0) {
2460d163575Sopenharmony_ci        return -ENOMEM;
2470d163575Sopenharmony_ci    }
2480d163575Sopenharmony_ci
2490d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
2500d163575Sopenharmony_ci    ret = jffs2_create((struct jffs2_inode *)parentVnode->data, (const unsigned char *)path, mode, &newNode);
2510d163575Sopenharmony_ci    if (ret != 0) {
2520d163575Sopenharmony_ci        VnodeFree(newVnode);
2530d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
2540d163575Sopenharmony_ci        return ret;
2550d163575Sopenharmony_ci    }
2560d163575Sopenharmony_ci
2570d163575Sopenharmony_ci    newVnode->type = VNODE_TYPE_REG;
2580d163575Sopenharmony_ci    newVnode->fop = parentVnode->fop;
2590d163575Sopenharmony_ci    newVnode->data = newNode;
2600d163575Sopenharmony_ci    newVnode->parent = parentVnode;
2610d163575Sopenharmony_ci    newVnode->originMount = parentVnode->originMount;
2620d163575Sopenharmony_ci    newVnode->uid = newNode->i_uid;
2630d163575Sopenharmony_ci    newVnode->gid = newNode->i_gid;
2640d163575Sopenharmony_ci    newVnode->mode = newNode->i_mode;
2650d163575Sopenharmony_ci
2660d163575Sopenharmony_ci    (void)VfsHashInsert(newVnode, newNode->i_ino);
2670d163575Sopenharmony_ci
2680d163575Sopenharmony_ci    *ppVnode = newVnode;
2690d163575Sopenharmony_ci
2700d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
2710d163575Sopenharmony_ci    return 0;
2720d163575Sopenharmony_ci}
2730d163575Sopenharmony_ci
2740d163575Sopenharmony_ciint VfsJffs2Close(struct file *filep)
2750d163575Sopenharmony_ci{
2760d163575Sopenharmony_ci    return 0;
2770d163575Sopenharmony_ci}
2780d163575Sopenharmony_ci
2790d163575Sopenharmony_cissize_t VfsJffs2ReadPage(struct Vnode *vnode, char *buffer, off_t off)
2800d163575Sopenharmony_ci{
2810d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
2820d163575Sopenharmony_ci    struct jffs2_inode_info *f = NULL;
2830d163575Sopenharmony_ci    struct jffs2_sb_info *c = NULL;
2840d163575Sopenharmony_ci    int ret;
2850d163575Sopenharmony_ci
2860d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
2870d163575Sopenharmony_ci
2880d163575Sopenharmony_ci    node = (struct jffs2_inode *)vnode->data;
2890d163575Sopenharmony_ci    f = JFFS2_INODE_INFO(node);
2900d163575Sopenharmony_ci    c = JFFS2_SB_INFO(node->i_sb);
2910d163575Sopenharmony_ci
2920d163575Sopenharmony_ci    off_t pos = min(node->i_size, off);
2930d163575Sopenharmony_ci    ssize_t len = min(PAGE_SIZE, (node->i_size - pos));
2940d163575Sopenharmony_ci    ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, off, len);
2950d163575Sopenharmony_ci    if (ret) {
2960d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
2970d163575Sopenharmony_ci        return ret;
2980d163575Sopenharmony_ci    }
2990d163575Sopenharmony_ci    node->i_atime = Jffs2CurSec();
3000d163575Sopenharmony_ci
3010d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
3020d163575Sopenharmony_ci
3030d163575Sopenharmony_ci    return len;
3040d163575Sopenharmony_ci}
3050d163575Sopenharmony_ci
3060d163575Sopenharmony_cissize_t VfsJffs2Read(struct file *filep, char *buffer, size_t bufLen)
3070d163575Sopenharmony_ci{
3080d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
3090d163575Sopenharmony_ci    struct jffs2_inode_info *f = NULL;
3100d163575Sopenharmony_ci    struct jffs2_sb_info *c = NULL;
3110d163575Sopenharmony_ci    int ret;
3120d163575Sopenharmony_ci
3130d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
3140d163575Sopenharmony_ci    node = (struct jffs2_inode *)filep->f_vnode->data;
3150d163575Sopenharmony_ci    f = JFFS2_INODE_INFO(node);
3160d163575Sopenharmony_ci    c = JFFS2_SB_INFO(node->i_sb);
3170d163575Sopenharmony_ci
3180d163575Sopenharmony_ci    off_t pos = min(node->i_size, filep->f_pos);
3190d163575Sopenharmony_ci    off_t len = min(bufLen, (node->i_size - pos));
3200d163575Sopenharmony_ci    ret = jffs2_read_inode_range(c, f, (unsigned char *)buffer, filep->f_pos, len);
3210d163575Sopenharmony_ci    if (ret) {
3220d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
3230d163575Sopenharmony_ci        return ret;
3240d163575Sopenharmony_ci    }
3250d163575Sopenharmony_ci    node->i_atime = Jffs2CurSec();
3260d163575Sopenharmony_ci    filep->f_pos += len;
3270d163575Sopenharmony_ci
3280d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
3290d163575Sopenharmony_ci
3300d163575Sopenharmony_ci    return len;
3310d163575Sopenharmony_ci}
3320d163575Sopenharmony_ci
3330d163575Sopenharmony_cissize_t VfsJffs2WritePage(struct Vnode *vnode, char *buffer, off_t pos, size_t buflen)
3340d163575Sopenharmony_ci{
3350d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
3360d163575Sopenharmony_ci    struct jffs2_inode_info *f = NULL;
3370d163575Sopenharmony_ci    struct jffs2_sb_info *c = NULL;
3380d163575Sopenharmony_ci    struct jffs2_raw_inode ri = {0};
3390d163575Sopenharmony_ci    struct IATTR attr = {0};
3400d163575Sopenharmony_ci    int ret;
3410d163575Sopenharmony_ci    uint32_t writtenLen;
3420d163575Sopenharmony_ci
3430d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
3440d163575Sopenharmony_ci
3450d163575Sopenharmony_ci    node = (struct jffs2_inode *)vnode->data;
3460d163575Sopenharmony_ci    f = JFFS2_INODE_INFO(node);
3470d163575Sopenharmony_ci    c = JFFS2_SB_INFO(node->i_sb);
3480d163575Sopenharmony_ci
3490d163575Sopenharmony_ci    if (pos < 0) {
3500d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
3510d163575Sopenharmony_ci        return -EINVAL;
3520d163575Sopenharmony_ci    }
3530d163575Sopenharmony_ci
3540d163575Sopenharmony_ci    ri.ino = cpu_to_je32(f->inocache->ino);
3550d163575Sopenharmony_ci    ri.mode = cpu_to_jemode(node->i_mode);
3560d163575Sopenharmony_ci    ri.uid = cpu_to_je16(node->i_uid);
3570d163575Sopenharmony_ci    ri.gid = cpu_to_je16(node->i_gid);
3580d163575Sopenharmony_ci    ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
3590d163575Sopenharmony_ci
3600d163575Sopenharmony_ci    if (pos > node->i_size) {
3610d163575Sopenharmony_ci        int err;
3620d163575Sopenharmony_ci        attr.attr_chg_valid = CHG_SIZE;
3630d163575Sopenharmony_ci        attr.attr_chg_size = pos;
3640d163575Sopenharmony_ci        err = jffs2_setattr(node, &attr);
3650d163575Sopenharmony_ci        if (err) {
3660d163575Sopenharmony_ci            LOS_MuxUnlock(&g_jffs2FsLock);
3670d163575Sopenharmony_ci            return err;
3680d163575Sopenharmony_ci        }
3690d163575Sopenharmony_ci    }
3700d163575Sopenharmony_ci    ri.isize = cpu_to_je32(node->i_size);
3710d163575Sopenharmony_ci
3720d163575Sopenharmony_ci    ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, buflen, &writtenLen);
3730d163575Sopenharmony_ci    if (ret) {
3740d163575Sopenharmony_ci        node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
3750d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
3760d163575Sopenharmony_ci        return ret;
3770d163575Sopenharmony_ci    }
3780d163575Sopenharmony_ci
3790d163575Sopenharmony_ci    node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
3800d163575Sopenharmony_ci
3810d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
3820d163575Sopenharmony_ci
3830d163575Sopenharmony_ci    return (ssize_t)writtenLen;
3840d163575Sopenharmony_ci}
3850d163575Sopenharmony_ci
3860d163575Sopenharmony_cissize_t VfsJffs2Write(struct file *filep, const char *buffer, size_t bufLen)
3870d163575Sopenharmony_ci{
3880d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
3890d163575Sopenharmony_ci    struct jffs2_inode_info *f = NULL;
3900d163575Sopenharmony_ci    struct jffs2_sb_info *c = NULL;
3910d163575Sopenharmony_ci    struct jffs2_raw_inode ri = {0};
3920d163575Sopenharmony_ci    struct IATTR attr = {0};
3930d163575Sopenharmony_ci    int ret;
3940d163575Sopenharmony_ci    off_t pos;
3950d163575Sopenharmony_ci    uint32_t writtenLen;
3960d163575Sopenharmony_ci
3970d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
3980d163575Sopenharmony_ci
3990d163575Sopenharmony_ci    node = (struct jffs2_inode *)filep->f_vnode->data;
4000d163575Sopenharmony_ci    f = JFFS2_INODE_INFO(node);
4010d163575Sopenharmony_ci    c = JFFS2_SB_INFO(node->i_sb);
4020d163575Sopenharmony_ci    pos = filep->f_pos;
4030d163575Sopenharmony_ci
4040d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_SMP
4050d163575Sopenharmony_ci    struct super_block *sb = node->i_sb;
4060d163575Sopenharmony_ci    UINT16 gcCpuMask = LOS_TaskCpuAffiGet(sb->s_gc_thread);
4070d163575Sopenharmony_ci    UINT32 curTaskId = LOS_CurTaskIDGet();
4080d163575Sopenharmony_ci    UINT16 curCpuMask = LOS_TaskCpuAffiGet(curTaskId);
4090d163575Sopenharmony_ci    if (curCpuMask != gcCpuMask) {
4100d163575Sopenharmony_ci        if (curCpuMask != LOSCFG_KERNEL_CPU_MASK) {
4110d163575Sopenharmony_ci            (void)LOS_TaskCpuAffiSet(sb->s_gc_thread, curCpuMask);
4120d163575Sopenharmony_ci        } else {
4130d163575Sopenharmony_ci            (void)LOS_TaskCpuAffiSet(curTaskId, gcCpuMask);
4140d163575Sopenharmony_ci        }
4150d163575Sopenharmony_ci    }
4160d163575Sopenharmony_ci#endif
4170d163575Sopenharmony_ci    if (pos < 0) {
4180d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
4190d163575Sopenharmony_ci        return -EINVAL;
4200d163575Sopenharmony_ci    }
4210d163575Sopenharmony_ci
4220d163575Sopenharmony_ci    ri.ino = cpu_to_je32(f->inocache->ino);
4230d163575Sopenharmony_ci    ri.mode = cpu_to_jemode(node->i_mode);
4240d163575Sopenharmony_ci    ri.uid = cpu_to_je16(node->i_uid);
4250d163575Sopenharmony_ci    ri.gid = cpu_to_je16(node->i_gid);
4260d163575Sopenharmony_ci    ri.atime = ri.ctime = ri.mtime = cpu_to_je32(Jffs2CurSec());
4270d163575Sopenharmony_ci
4280d163575Sopenharmony_ci    if (pos > node->i_size) {
4290d163575Sopenharmony_ci        int err;
4300d163575Sopenharmony_ci        attr.attr_chg_valid = CHG_SIZE;
4310d163575Sopenharmony_ci        attr.attr_chg_size = pos;
4320d163575Sopenharmony_ci        err = jffs2_setattr(node, &attr);
4330d163575Sopenharmony_ci        if (err) {
4340d163575Sopenharmony_ci            LOS_MuxUnlock(&g_jffs2FsLock);
4350d163575Sopenharmony_ci            return err;
4360d163575Sopenharmony_ci        }
4370d163575Sopenharmony_ci    }
4380d163575Sopenharmony_ci    ri.isize = cpu_to_je32(node->i_size);
4390d163575Sopenharmony_ci
4400d163575Sopenharmony_ci    ret = jffs2_write_inode_range(c, f, &ri, (unsigned char *)buffer, pos, bufLen, &writtenLen);
4410d163575Sopenharmony_ci    if (ret) {
4420d163575Sopenharmony_ci        pos += writtenLen;
4430d163575Sopenharmony_ci
4440d163575Sopenharmony_ci        node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
4450d163575Sopenharmony_ci        if (pos > node->i_size)
4460d163575Sopenharmony_ci            node->i_size = pos;
4470d163575Sopenharmony_ci
4480d163575Sopenharmony_ci        filep->f_pos = pos;
4490d163575Sopenharmony_ci
4500d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
4510d163575Sopenharmony_ci
4520d163575Sopenharmony_ci        return ret;
4530d163575Sopenharmony_ci    }
4540d163575Sopenharmony_ci
4550d163575Sopenharmony_ci    if (writtenLen != bufLen) {
4560d163575Sopenharmony_ci        pos += writtenLen;
4570d163575Sopenharmony_ci
4580d163575Sopenharmony_ci        node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
4590d163575Sopenharmony_ci        if (pos > node->i_size)
4600d163575Sopenharmony_ci            node->i_size = pos;
4610d163575Sopenharmony_ci
4620d163575Sopenharmony_ci        filep->f_pos = pos;
4630d163575Sopenharmony_ci
4640d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
4650d163575Sopenharmony_ci
4660d163575Sopenharmony_ci        return -ENOSPC;
4670d163575Sopenharmony_ci    }
4680d163575Sopenharmony_ci
4690d163575Sopenharmony_ci    pos += bufLen;
4700d163575Sopenharmony_ci
4710d163575Sopenharmony_ci    node->i_mtime = node->i_ctime = je32_to_cpu(ri.mtime);
4720d163575Sopenharmony_ci    if (pos > node->i_size)
4730d163575Sopenharmony_ci        node->i_size = pos;
4740d163575Sopenharmony_ci
4750d163575Sopenharmony_ci    filep->f_pos = pos;
4760d163575Sopenharmony_ci
4770d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
4780d163575Sopenharmony_ci
4790d163575Sopenharmony_ci    return writtenLen;
4800d163575Sopenharmony_ci}
4810d163575Sopenharmony_ci
4820d163575Sopenharmony_cioff_t VfsJffs2Seek(struct file *filep, off_t offset, int whence)
4830d163575Sopenharmony_ci{
4840d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
4850d163575Sopenharmony_ci    loff_t filePos;
4860d163575Sopenharmony_ci
4870d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
4880d163575Sopenharmony_ci
4890d163575Sopenharmony_ci    node = (struct jffs2_inode *)filep->f_vnode->data;
4900d163575Sopenharmony_ci    filePos = filep->f_pos;
4910d163575Sopenharmony_ci
4920d163575Sopenharmony_ci    switch (whence) {
4930d163575Sopenharmony_ci        case SEEK_CUR:
4940d163575Sopenharmony_ci            filePos += offset;
4950d163575Sopenharmony_ci            break;
4960d163575Sopenharmony_ci
4970d163575Sopenharmony_ci        case SEEK_SET:
4980d163575Sopenharmony_ci            filePos = offset;
4990d163575Sopenharmony_ci            break;
5000d163575Sopenharmony_ci
5010d163575Sopenharmony_ci        case SEEK_END:
5020d163575Sopenharmony_ci            filePos = node->i_size + offset;
5030d163575Sopenharmony_ci            break;
5040d163575Sopenharmony_ci
5050d163575Sopenharmony_ci        default:
5060d163575Sopenharmony_ci            LOS_MuxUnlock(&g_jffs2FsLock);
5070d163575Sopenharmony_ci            return -EINVAL;
5080d163575Sopenharmony_ci    }
5090d163575Sopenharmony_ci
5100d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
5110d163575Sopenharmony_ci
5120d163575Sopenharmony_ci    if (filePos < 0)
5130d163575Sopenharmony_ci        return -EINVAL;
5140d163575Sopenharmony_ci
5150d163575Sopenharmony_ci    return filePos;
5160d163575Sopenharmony_ci}
5170d163575Sopenharmony_ci
5180d163575Sopenharmony_ciint VfsJffs2Ioctl(struct file *filep, int cmd, unsigned long arg)
5190d163575Sopenharmony_ci{
5200d163575Sopenharmony_ci    PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
5210d163575Sopenharmony_ci    return -ENOSYS;
5220d163575Sopenharmony_ci}
5230d163575Sopenharmony_ci
5240d163575Sopenharmony_ciint VfsJffs2Fsync(struct file *filep)
5250d163575Sopenharmony_ci{
5260d163575Sopenharmony_ci    /* jffs2_write directly write to flash, sync is OK.
5270d163575Sopenharmony_ci        BUT after pagecache enabled, pages need to be flushed to flash */
5280d163575Sopenharmony_ci    return 0;
5290d163575Sopenharmony_ci}
5300d163575Sopenharmony_ci
5310d163575Sopenharmony_ciint VfsJffs2Dup(const struct file *oldFile, struct file *newFile)
5320d163575Sopenharmony_ci{
5330d163575Sopenharmony_ci    PRINT_DEBUG("%s NOT SUPPORT\n", __FUNCTION__);
5340d163575Sopenharmony_ci    return -ENOSYS;
5350d163575Sopenharmony_ci}
5360d163575Sopenharmony_ci
5370d163575Sopenharmony_ciint VfsJffs2Opendir(struct Vnode *pVnode, struct fs_dirent_s *dir)
5380d163575Sopenharmony_ci{
5390d163575Sopenharmony_ci    dir->fd_int_offset = 0;
5400d163575Sopenharmony_ci    return 0;
5410d163575Sopenharmony_ci}
5420d163575Sopenharmony_ci
5430d163575Sopenharmony_ciint VfsJffs2Readdir(struct Vnode *pVnode, struct fs_dirent_s *dir)
5440d163575Sopenharmony_ci{
5450d163575Sopenharmony_ci    int ret;
5460d163575Sopenharmony_ci    int i = 0;
5470d163575Sopenharmony_ci
5480d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
5490d163575Sopenharmony_ci
5500d163575Sopenharmony_ci    /* set jffs2_d */
5510d163575Sopenharmony_ci    while (i < dir->read_cnt) {
5520d163575Sopenharmony_ci        ret = jffs2_readdir((struct jffs2_inode *)pVnode->data, &dir->fd_position,
5530d163575Sopenharmony_ci                            &dir->fd_int_offset, &dir->fd_dir[i]);
5540d163575Sopenharmony_ci        if (ret) {
5550d163575Sopenharmony_ci            break;
5560d163575Sopenharmony_ci        }
5570d163575Sopenharmony_ci
5580d163575Sopenharmony_ci        i++;
5590d163575Sopenharmony_ci    }
5600d163575Sopenharmony_ci
5610d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
5620d163575Sopenharmony_ci
5630d163575Sopenharmony_ci    return i;
5640d163575Sopenharmony_ci}
5650d163575Sopenharmony_ci
5660d163575Sopenharmony_ciint VfsJffs2Seekdir(struct Vnode *pVnode, struct fs_dirent_s *dir, unsigned long offset)
5670d163575Sopenharmony_ci{
5680d163575Sopenharmony_ci    return 0;
5690d163575Sopenharmony_ci}
5700d163575Sopenharmony_ci
5710d163575Sopenharmony_ciint VfsJffs2Rewinddir(struct Vnode *pVnode, struct fs_dirent_s *dir)
5720d163575Sopenharmony_ci{
5730d163575Sopenharmony_ci    dir->fd_int_offset = 0;
5740d163575Sopenharmony_ci
5750d163575Sopenharmony_ci    return 0;
5760d163575Sopenharmony_ci}
5770d163575Sopenharmony_ci
5780d163575Sopenharmony_ciint VfsJffs2Closedir(struct Vnode *node, struct fs_dirent_s *dir)
5790d163575Sopenharmony_ci{
5800d163575Sopenharmony_ci    return 0;
5810d163575Sopenharmony_ci}
5820d163575Sopenharmony_ci
5830d163575Sopenharmony_ciint VfsJffs2Mkdir(struct Vnode *parentNode, const char *dirName, mode_t mode, struct Vnode **ppVnode)
5840d163575Sopenharmony_ci{
5850d163575Sopenharmony_ci    int ret;
5860d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
5870d163575Sopenharmony_ci    struct Vnode *newVnode = NULL;
5880d163575Sopenharmony_ci
5890d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &newVnode);
5900d163575Sopenharmony_ci    if (ret != 0) {
5910d163575Sopenharmony_ci        return -ENOMEM;
5920d163575Sopenharmony_ci    }
5930d163575Sopenharmony_ci
5940d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
5950d163575Sopenharmony_ci
5960d163575Sopenharmony_ci    ret = jffs2_mkdir((struct jffs2_inode *)parentNode->data, (const unsigned char *)dirName, mode, &node);
5970d163575Sopenharmony_ci    if (ret != 0) {
5980d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
5990d163575Sopenharmony_ci        VnodeFree(newVnode);
6000d163575Sopenharmony_ci        return ret;
6010d163575Sopenharmony_ci    }
6020d163575Sopenharmony_ci
6030d163575Sopenharmony_ci    newVnode->type = VNODE_TYPE_DIR;
6040d163575Sopenharmony_ci    newVnode->fop = parentNode->fop;
6050d163575Sopenharmony_ci    newVnode->data = node;
6060d163575Sopenharmony_ci    newVnode->parent = parentNode;
6070d163575Sopenharmony_ci    newVnode->originMount = parentNode->originMount;
6080d163575Sopenharmony_ci    newVnode->uid = node->i_uid;
6090d163575Sopenharmony_ci    newVnode->gid = node->i_gid;
6100d163575Sopenharmony_ci    newVnode->mode = node->i_mode;
6110d163575Sopenharmony_ci
6120d163575Sopenharmony_ci    *ppVnode = newVnode;
6130d163575Sopenharmony_ci
6140d163575Sopenharmony_ci    (void)VfsHashInsert(newVnode, node->i_ino);
6150d163575Sopenharmony_ci
6160d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
6170d163575Sopenharmony_ci
6180d163575Sopenharmony_ci    return 0;
6190d163575Sopenharmony_ci}
6200d163575Sopenharmony_ci
6210d163575Sopenharmony_cistatic int Jffs2Truncate(struct Vnode *pVnode, unsigned int len)
6220d163575Sopenharmony_ci{
6230d163575Sopenharmony_ci    int ret;
6240d163575Sopenharmony_ci    struct IATTR attr = {0};
6250d163575Sopenharmony_ci
6260d163575Sopenharmony_ci    attr.attr_chg_size = len;
6270d163575Sopenharmony_ci    attr.attr_chg_valid = CHG_SIZE;
6280d163575Sopenharmony_ci
6290d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
6300d163575Sopenharmony_ci    ret = jffs2_setattr((struct jffs2_inode *)pVnode->data, &attr);
6310d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
6320d163575Sopenharmony_ci    return ret;
6330d163575Sopenharmony_ci}
6340d163575Sopenharmony_ci
6350d163575Sopenharmony_ciint VfsJffs2Truncate(struct Vnode *pVnode, off_t len)
6360d163575Sopenharmony_ci{
6370d163575Sopenharmony_ci    int ret = Jffs2Truncate(pVnode, (unsigned int)len);
6380d163575Sopenharmony_ci    return ret;
6390d163575Sopenharmony_ci}
6400d163575Sopenharmony_ci
6410d163575Sopenharmony_ciint VfsJffs2Truncate64(struct Vnode *pVnode, off64_t len)
6420d163575Sopenharmony_ci{
6430d163575Sopenharmony_ci    int ret = Jffs2Truncate(pVnode, (unsigned int)len);
6440d163575Sopenharmony_ci    return ret;
6450d163575Sopenharmony_ci}
6460d163575Sopenharmony_ci
6470d163575Sopenharmony_ciint VfsJffs2Chattr(struct Vnode *pVnode, struct IATTR *attr)
6480d163575Sopenharmony_ci{
6490d163575Sopenharmony_ci    int ret;
6500d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
6510d163575Sopenharmony_ci
6520d163575Sopenharmony_ci    if (pVnode == NULL) {
6530d163575Sopenharmony_ci        return -EINVAL;
6540d163575Sopenharmony_ci    }
6550d163575Sopenharmony_ci
6560d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
6570d163575Sopenharmony_ci
6580d163575Sopenharmony_ci    node = pVnode->data;
6590d163575Sopenharmony_ci    ret = jffs2_setattr(node, attr);
6600d163575Sopenharmony_ci    if (ret == 0) {
6610d163575Sopenharmony_ci        pVnode->uid = node->i_uid;
6620d163575Sopenharmony_ci        pVnode->gid = node->i_gid;
6630d163575Sopenharmony_ci        pVnode->mode = node->i_mode;
6640d163575Sopenharmony_ci    }
6650d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
6660d163575Sopenharmony_ci    return ret;
6670d163575Sopenharmony_ci}
6680d163575Sopenharmony_ci
6690d163575Sopenharmony_ciint VfsJffs2Rmdir(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
6700d163575Sopenharmony_ci{
6710d163575Sopenharmony_ci    int ret;
6720d163575Sopenharmony_ci    struct jffs2_inode *parentInode = NULL;
6730d163575Sopenharmony_ci    struct jffs2_inode *targetInode = NULL;
6740d163575Sopenharmony_ci
6750d163575Sopenharmony_ci    if (!parentVnode || !targetVnode) {
6760d163575Sopenharmony_ci        return -EINVAL;
6770d163575Sopenharmony_ci    }
6780d163575Sopenharmony_ci
6790d163575Sopenharmony_ci    parentInode = (struct jffs2_inode *)parentVnode->data;
6800d163575Sopenharmony_ci    targetInode = (struct jffs2_inode *)targetVnode->data;
6810d163575Sopenharmony_ci
6820d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
6830d163575Sopenharmony_ci
6840d163575Sopenharmony_ci    ret = jffs2_rmdir(parentInode, targetInode, (const unsigned char *)path);
6850d163575Sopenharmony_ci    if (ret == 0) {
6860d163575Sopenharmony_ci        (void)jffs2_iput(targetInode);
6870d163575Sopenharmony_ci    }
6880d163575Sopenharmony_ci
6890d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
6900d163575Sopenharmony_ci    return ret;
6910d163575Sopenharmony_ci}
6920d163575Sopenharmony_ci
6930d163575Sopenharmony_ciint VfsJffs2Link(struct Vnode *oldVnode, struct Vnode *newParentVnode, struct Vnode **newVnode, const char *newName)
6940d163575Sopenharmony_ci{
6950d163575Sopenharmony_ci    int ret;
6960d163575Sopenharmony_ci    struct jffs2_inode *oldInode = oldVnode->data;
6970d163575Sopenharmony_ci    struct jffs2_inode *newParentInode = newParentVnode->data;
6980d163575Sopenharmony_ci    struct Vnode *pVnode = NULL;
6990d163575Sopenharmony_ci
7000d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &pVnode);
7010d163575Sopenharmony_ci    if (ret != 0) {
7020d163575Sopenharmony_ci        return -ENOMEM;
7030d163575Sopenharmony_ci    }
7040d163575Sopenharmony_ci
7050d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
7060d163575Sopenharmony_ci    ret = jffs2_link(oldInode, newParentInode, (const unsigned char *)newName);
7070d163575Sopenharmony_ci    if (ret != 0) {
7080d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
7090d163575Sopenharmony_ci        VnodeFree(pVnode);
7100d163575Sopenharmony_ci        return ret;
7110d163575Sopenharmony_ci    }
7120d163575Sopenharmony_ci
7130d163575Sopenharmony_ci    pVnode->type = VNODE_TYPE_REG;
7140d163575Sopenharmony_ci    pVnode->fop = &g_jffs2Fops;
7150d163575Sopenharmony_ci    pVnode->parent = newParentVnode;
7160d163575Sopenharmony_ci    pVnode->originMount = newParentVnode->originMount;
7170d163575Sopenharmony_ci    pVnode->data = oldInode;
7180d163575Sopenharmony_ci    pVnode->uid = oldVnode->uid;
7190d163575Sopenharmony_ci    pVnode->gid = oldVnode->gid;
7200d163575Sopenharmony_ci    pVnode->mode = oldVnode->mode;
7210d163575Sopenharmony_ci
7220d163575Sopenharmony_ci    *newVnode = pVnode;
7230d163575Sopenharmony_ci    (void)VfsHashInsert(*newVnode, oldInode->i_ino);
7240d163575Sopenharmony_ci
7250d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
7260d163575Sopenharmony_ci    return ret;
7270d163575Sopenharmony_ci}
7280d163575Sopenharmony_ci
7290d163575Sopenharmony_ciint VfsJffs2Symlink(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target)
7300d163575Sopenharmony_ci{
7310d163575Sopenharmony_ci    int ret;
7320d163575Sopenharmony_ci    struct jffs2_inode *inode = NULL;
7330d163575Sopenharmony_ci    struct Vnode *pVnode = NULL;
7340d163575Sopenharmony_ci
7350d163575Sopenharmony_ci    ret = VnodeAlloc(&g_jffs2Vops, &pVnode);
7360d163575Sopenharmony_ci    if (ret != 0) {
7370d163575Sopenharmony_ci        return -ENOMEM;
7380d163575Sopenharmony_ci    }
7390d163575Sopenharmony_ci
7400d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
7410d163575Sopenharmony_ci    ret = jffs2_symlink((struct jffs2_inode *)parentVnode->data, &inode, (const unsigned char *)path, target);
7420d163575Sopenharmony_ci    if (ret != 0) {
7430d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
7440d163575Sopenharmony_ci        VnodeFree(pVnode);
7450d163575Sopenharmony_ci        return ret;
7460d163575Sopenharmony_ci    }
7470d163575Sopenharmony_ci
7480d163575Sopenharmony_ci    pVnode->type = VNODE_TYPE_LNK;
7490d163575Sopenharmony_ci    pVnode->fop = &g_jffs2Fops;
7500d163575Sopenharmony_ci    pVnode->parent = parentVnode;
7510d163575Sopenharmony_ci    pVnode->originMount = parentVnode->originMount;
7520d163575Sopenharmony_ci    pVnode->data = inode;
7530d163575Sopenharmony_ci    pVnode->uid = inode->i_uid;
7540d163575Sopenharmony_ci    pVnode->gid = inode->i_gid;
7550d163575Sopenharmony_ci    pVnode->mode = inode->i_mode;
7560d163575Sopenharmony_ci
7570d163575Sopenharmony_ci    *newVnode = pVnode;
7580d163575Sopenharmony_ci    (void)VfsHashInsert(*newVnode, inode->i_ino);
7590d163575Sopenharmony_ci
7600d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
7610d163575Sopenharmony_ci    return ret;
7620d163575Sopenharmony_ci}
7630d163575Sopenharmony_ci
7640d163575Sopenharmony_cissize_t VfsJffs2Readlink(struct Vnode *vnode, char *buffer, size_t bufLen)
7650d163575Sopenharmony_ci{
7660d163575Sopenharmony_ci    struct jffs2_inode *inode = NULL;
7670d163575Sopenharmony_ci    struct jffs2_inode_info *f = NULL;
7680d163575Sopenharmony_ci    ssize_t targetLen;
7690d163575Sopenharmony_ci    ssize_t cnt;
7700d163575Sopenharmony_ci
7710d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
7720d163575Sopenharmony_ci
7730d163575Sopenharmony_ci    inode = (struct jffs2_inode *)vnode->data;
7740d163575Sopenharmony_ci    f = JFFS2_INODE_INFO(inode);
7750d163575Sopenharmony_ci    targetLen = strlen((const char *)f->target);
7760d163575Sopenharmony_ci    if (bufLen == 0) {
7770d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
7780d163575Sopenharmony_ci        return 0;
7790d163575Sopenharmony_ci    }
7800d163575Sopenharmony_ci
7810d163575Sopenharmony_ci    cnt = (bufLen - 1) < targetLen ? (bufLen - 1) : targetLen;
7820d163575Sopenharmony_ci    if (LOS_CopyFromKernel(buffer, bufLen, (const char *)f->target, cnt) != 0) {
7830d163575Sopenharmony_ci        LOS_MuxUnlock(&g_jffs2FsLock);
7840d163575Sopenharmony_ci        return -EFAULT;
7850d163575Sopenharmony_ci    }
7860d163575Sopenharmony_ci    buffer[cnt] = '\0';
7870d163575Sopenharmony_ci
7880d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
7890d163575Sopenharmony_ci
7900d163575Sopenharmony_ci    return cnt;
7910d163575Sopenharmony_ci}
7920d163575Sopenharmony_ci
7930d163575Sopenharmony_ciint VfsJffs2Unlink(struct Vnode *parentVnode, struct Vnode *targetVnode, const char *path)
7940d163575Sopenharmony_ci{
7950d163575Sopenharmony_ci    int ret;
7960d163575Sopenharmony_ci    struct jffs2_inode *parentInode = NULL;
7970d163575Sopenharmony_ci    struct jffs2_inode *targetInode = NULL;
7980d163575Sopenharmony_ci
7990d163575Sopenharmony_ci    if (!parentVnode || !targetVnode) {
8000d163575Sopenharmony_ci        PRINTK("%s-%d parentVnode=%x, targetVnode=%x\n", __FUNCTION__, __LINE__, parentVnode, targetVnode);
8010d163575Sopenharmony_ci        return -EINVAL;
8020d163575Sopenharmony_ci    }
8030d163575Sopenharmony_ci
8040d163575Sopenharmony_ci    parentInode = (struct jffs2_inode *)parentVnode->data;
8050d163575Sopenharmony_ci    targetInode = (struct jffs2_inode *)targetVnode->data;
8060d163575Sopenharmony_ci
8070d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
8080d163575Sopenharmony_ci
8090d163575Sopenharmony_ci    ret = jffs2_unlink(parentInode, targetInode, (const unsigned char *)path);
8100d163575Sopenharmony_ci    if (ret == 0) {
8110d163575Sopenharmony_ci        (void)jffs2_iput(targetInode);
8120d163575Sopenharmony_ci    }
8130d163575Sopenharmony_ci
8140d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
8150d163575Sopenharmony_ci    return ret;
8160d163575Sopenharmony_ci}
8170d163575Sopenharmony_ci
8180d163575Sopenharmony_ciint VfsJffs2Rename(struct Vnode *fromVnode, struct Vnode *toParentVnode, const char *fromName, const char *toName)
8190d163575Sopenharmony_ci{
8200d163575Sopenharmony_ci    int ret;
8210d163575Sopenharmony_ci    struct Vnode *fromParentVnode = NULL;
8220d163575Sopenharmony_ci    struct Vnode *toVnode = NULL;
8230d163575Sopenharmony_ci    struct jffs2_inode *fromNode = NULL;
8240d163575Sopenharmony_ci
8250d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
8260d163575Sopenharmony_ci    fromParentVnode = fromVnode->parent;
8270d163575Sopenharmony_ci
8280d163575Sopenharmony_ci    ret = VfsJffs2Lookup(toParentVnode, toName, strlen(toName), &toVnode);
8290d163575Sopenharmony_ci    if (ret == 0) {
8300d163575Sopenharmony_ci        if (toVnode->type == VNODE_TYPE_DIR) {
8310d163575Sopenharmony_ci            ret = VfsJffs2Rmdir(toParentVnode, toVnode, (char *)toName);
8320d163575Sopenharmony_ci        } else {
8330d163575Sopenharmony_ci            ret = VfsJffs2Unlink(toParentVnode, toVnode, (char *)toName);
8340d163575Sopenharmony_ci        }
8350d163575Sopenharmony_ci        if (ret) {
8360d163575Sopenharmony_ci            PRINTK("%s-%d remove newname(%s) failed ret=%d\n", __FUNCTION__, __LINE__, toName, ret);
8370d163575Sopenharmony_ci            LOS_MuxUnlock(&g_jffs2FsLock);
8380d163575Sopenharmony_ci            return ret;
8390d163575Sopenharmony_ci        }
8400d163575Sopenharmony_ci    }
8410d163575Sopenharmony_ci    fromNode = (struct jffs2_inode *)fromVnode->data;
8420d163575Sopenharmony_ci    ret = jffs2_rename((struct jffs2_inode *)fromParentVnode->data, fromNode,
8430d163575Sopenharmony_ci        (const unsigned char *)fromName, (struct jffs2_inode *)toParentVnode->data, (const unsigned char *)toName);
8440d163575Sopenharmony_ci    fromVnode->parent = toParentVnode;
8450d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
8460d163575Sopenharmony_ci
8470d163575Sopenharmony_ci    if (ret) {
8480d163575Sopenharmony_ci        return ret;
8490d163575Sopenharmony_ci    }
8500d163575Sopenharmony_ci
8510d163575Sopenharmony_ci    return 0;
8520d163575Sopenharmony_ci}
8530d163575Sopenharmony_ci
8540d163575Sopenharmony_ciint VfsJffs2Stat(struct Vnode *pVnode, struct stat *buf)
8550d163575Sopenharmony_ci{
8560d163575Sopenharmony_ci    struct jffs2_inode *node = NULL;
8570d163575Sopenharmony_ci
8580d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
8590d163575Sopenharmony_ci
8600d163575Sopenharmony_ci    node = (struct jffs2_inode *)pVnode->data;
8610d163575Sopenharmony_ci    switch (node->i_mode & S_IFMT) {
8620d163575Sopenharmony_ci        case S_IFREG:
8630d163575Sopenharmony_ci        case S_IFDIR:
8640d163575Sopenharmony_ci        case S_IFLNK:
8650d163575Sopenharmony_ci            buf->st_mode = node->i_mode;
8660d163575Sopenharmony_ci            break;
8670d163575Sopenharmony_ci
8680d163575Sopenharmony_ci        default:
8690d163575Sopenharmony_ci            buf->st_mode = DT_UNKNOWN;
8700d163575Sopenharmony_ci            break;
8710d163575Sopenharmony_ci    }
8720d163575Sopenharmony_ci
8730d163575Sopenharmony_ci    buf->st_dev = 0;
8740d163575Sopenharmony_ci    buf->st_ino = node->i_ino;
8750d163575Sopenharmony_ci    buf->st_nlink = node->i_nlink;
8760d163575Sopenharmony_ci    buf->st_uid = node->i_uid;
8770d163575Sopenharmony_ci    buf->st_gid = node->i_gid;
8780d163575Sopenharmony_ci    buf->st_size = node->i_size;
8790d163575Sopenharmony_ci    buf->st_blksize = BLOCK_SIZE;
8800d163575Sopenharmony_ci    buf->st_blocks = buf->st_size / buf->st_blksize;
8810d163575Sopenharmony_ci    buf->st_atime = node->i_atime;
8820d163575Sopenharmony_ci    buf->st_mtime = node->i_mtime;
8830d163575Sopenharmony_ci    buf->st_ctime = node->i_ctime;
8840d163575Sopenharmony_ci
8850d163575Sopenharmony_ci    /* Adapt to kstat member long tv_sec */
8860d163575Sopenharmony_ci    buf->__st_atim32.tv_sec = (long)node->i_atime;
8870d163575Sopenharmony_ci    buf->__st_mtim32.tv_sec = (long)node->i_mtime;
8880d163575Sopenharmony_ci    buf->__st_ctim32.tv_sec = (long)node->i_ctime;
8890d163575Sopenharmony_ci
8900d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
8910d163575Sopenharmony_ci
8920d163575Sopenharmony_ci    return 0;
8930d163575Sopenharmony_ci}
8940d163575Sopenharmony_ci
8950d163575Sopenharmony_ciint VfsJffs2Reclaim(struct Vnode *pVnode)
8960d163575Sopenharmony_ci{
8970d163575Sopenharmony_ci    return 0;
8980d163575Sopenharmony_ci}
8990d163575Sopenharmony_ci
9000d163575Sopenharmony_ciint VfsJffs2Statfs(struct Mount *mnt, struct statfs *buf)
9010d163575Sopenharmony_ci{
9020d163575Sopenharmony_ci    unsigned long freeSize;
9030d163575Sopenharmony_ci    struct jffs2_sb_info *c = NULL;
9040d163575Sopenharmony_ci    struct jffs2_inode *rootNode = NULL;
9050d163575Sopenharmony_ci
9060d163575Sopenharmony_ci    LOS_MuxLock(&g_jffs2FsLock, (uint32_t)JFFS2_WAITING_FOREVER);
9070d163575Sopenharmony_ci
9080d163575Sopenharmony_ci    rootNode = (struct jffs2_inode *)mnt->vnodeCovered->data;
9090d163575Sopenharmony_ci    c = JFFS2_SB_INFO(rootNode->i_sb);
9100d163575Sopenharmony_ci
9110d163575Sopenharmony_ci    freeSize = c->free_size + c->dirty_size;
9120d163575Sopenharmony_ci    buf->f_type = JFFS2_SUPER_MAGIC;
9130d163575Sopenharmony_ci    buf->f_bsize = PAGE_SIZE;
9140d163575Sopenharmony_ci    buf->f_blocks = (((uint64_t)c->nr_blocks) * c->sector_size) / PAGE_SIZE;
9150d163575Sopenharmony_ci    buf->f_bfree = freeSize / PAGE_SIZE;
9160d163575Sopenharmony_ci    buf->f_bavail = buf->f_bfree;
9170d163575Sopenharmony_ci    buf->f_namelen = NAME_MAX;
9180d163575Sopenharmony_ci    buf->f_fsid.__val[0] = JFFS2_SUPER_MAGIC;
9190d163575Sopenharmony_ci    buf->f_fsid.__val[1] = 1;
9200d163575Sopenharmony_ci    buf->f_frsize = BLOCK_SIZE;
9210d163575Sopenharmony_ci    buf->f_files = 0;
9220d163575Sopenharmony_ci    buf->f_ffree = 0;
9230d163575Sopenharmony_ci    buf->f_flags = mnt->mountFlags;
9240d163575Sopenharmony_ci
9250d163575Sopenharmony_ci    LOS_MuxUnlock(&g_jffs2FsLock);
9260d163575Sopenharmony_ci    return 0;
9270d163575Sopenharmony_ci}
9280d163575Sopenharmony_ci
9290d163575Sopenharmony_ciint Jffs2MutexCreate(void)
9300d163575Sopenharmony_ci{
9310d163575Sopenharmony_ci    if (LOS_MuxInit(&g_jffs2FsLock, NULL) != LOS_OK) {
9320d163575Sopenharmony_ci        PRINT_ERR("%s, LOS_MuxCreate failed\n", __FUNCTION__);
9330d163575Sopenharmony_ci        return -1;
9340d163575Sopenharmony_ci    } else {
9350d163575Sopenharmony_ci        return 0;
9360d163575Sopenharmony_ci    }
9370d163575Sopenharmony_ci}
9380d163575Sopenharmony_ci
9390d163575Sopenharmony_civoid Jffs2MutexDelete(void)
9400d163575Sopenharmony_ci{
9410d163575Sopenharmony_ci    (void)LOS_MuxDestroy(&g_jffs2FsLock);
9420d163575Sopenharmony_ci}
9430d163575Sopenharmony_ci
9440d163575Sopenharmony_ciconst struct MountOps jffs_operations = {
9450d163575Sopenharmony_ci    .Mount = VfsJffs2Bind,
9460d163575Sopenharmony_ci    .Unmount = VfsJffs2Unbind,
9470d163575Sopenharmony_ci    .Statfs = VfsJffs2Statfs,
9480d163575Sopenharmony_ci};
9490d163575Sopenharmony_ci
9500d163575Sopenharmony_cistruct VnodeOps g_jffs2Vops = {
9510d163575Sopenharmony_ci    .Lookup = VfsJffs2Lookup,
9520d163575Sopenharmony_ci    .Create = VfsJffs2Create,
9530d163575Sopenharmony_ci    .ReadPage = VfsJffs2ReadPage,
9540d163575Sopenharmony_ci    .WritePage = VfsJffs2WritePage,
9550d163575Sopenharmony_ci    .Rename = VfsJffs2Rename,
9560d163575Sopenharmony_ci    .Mkdir = VfsJffs2Mkdir,
9570d163575Sopenharmony_ci    .Getattr = VfsJffs2Stat,
9580d163575Sopenharmony_ci    .Opendir = VfsJffs2Opendir,
9590d163575Sopenharmony_ci    .Readdir = VfsJffs2Readdir,
9600d163575Sopenharmony_ci    .Closedir = VfsJffs2Closedir,
9610d163575Sopenharmony_ci    .Rewinddir = VfsJffs2Rewinddir,
9620d163575Sopenharmony_ci    .Unlink = VfsJffs2Unlink,
9630d163575Sopenharmony_ci    .Rmdir = VfsJffs2Rmdir,
9640d163575Sopenharmony_ci    .Chattr = VfsJffs2Chattr,
9650d163575Sopenharmony_ci    .Reclaim = VfsJffs2Reclaim,
9660d163575Sopenharmony_ci    .Truncate = VfsJffs2Truncate,
9670d163575Sopenharmony_ci    .Truncate64 = VfsJffs2Truncate64,
9680d163575Sopenharmony_ci    .Link = VfsJffs2Link,
9690d163575Sopenharmony_ci    .Symlink = VfsJffs2Symlink,
9700d163575Sopenharmony_ci    .Readlink = VfsJffs2Readlink,
9710d163575Sopenharmony_ci};
9720d163575Sopenharmony_ci
9730d163575Sopenharmony_cistruct file_operations_vfs g_jffs2Fops = {
9740d163575Sopenharmony_ci    .read = VfsJffs2Read,
9750d163575Sopenharmony_ci    .write = VfsJffs2Write,
9760d163575Sopenharmony_ci    .mmap = OsVfsFileMmap,
9770d163575Sopenharmony_ci    .seek = VfsJffs2Seek,
9780d163575Sopenharmony_ci    .close = VfsJffs2Close,
9790d163575Sopenharmony_ci    .fsync = VfsJffs2Fsync,
9800d163575Sopenharmony_ci};
9810d163575Sopenharmony_ci
9820d163575Sopenharmony_ci
9830d163575Sopenharmony_ciFSMAP_ENTRY(jffs_fsmap, "jffs2", jffs_operations, TRUE, TRUE);
9840d163575Sopenharmony_ci
9850d163575Sopenharmony_ci#endif
986