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