13d8536b4Sopenharmony_ci/*
23d8536b4Sopenharmony_ci * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
33d8536b4Sopenharmony_ci *
43d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
53d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met:
63d8536b4Sopenharmony_ci *
73d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
83d8536b4Sopenharmony_ci *    conditions and the following disclaimer.
93d8536b4Sopenharmony_ci *
103d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
113d8536b4Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
123d8536b4Sopenharmony_ci *    provided with the distribution.
133d8536b4Sopenharmony_ci *
143d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
153d8536b4Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
163d8536b4Sopenharmony_ci *    permission.
173d8536b4Sopenharmony_ci *
183d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
193d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
203d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
213d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
223d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
233d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
243d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
253d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
263d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
273d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
283d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
293d8536b4Sopenharmony_ci */
303d8536b4Sopenharmony_ci#include "vfs_partition.h"
313d8536b4Sopenharmony_ci#include "vfs_operations.h"
323d8536b4Sopenharmony_ci#include "los_fs.h"
333d8536b4Sopenharmony_ci#include "los_list.h"
343d8536b4Sopenharmony_ci#include "vfs_maps.h"
353d8536b4Sopenharmony_ci#include "vfs_mount.h"
363d8536b4Sopenharmony_ci#include "securec.h"
373d8536b4Sopenharmony_ci#include "stdlib.h"
383d8536b4Sopenharmony_ci#include "string.h"
393d8536b4Sopenharmony_ci
403d8536b4Sopenharmony_cistatic struct DeviceDesc *g_deviceList = NULL;
413d8536b4Sopenharmony_ci
423d8536b4Sopenharmony_ciint GetPartIdByPartName(const char *partName)
433d8536b4Sopenharmony_ci{
443d8536b4Sopenharmony_ci    if (partName == NULL) {
453d8536b4Sopenharmony_ci        return (int)LOS_NOK;
463d8536b4Sopenharmony_ci    }
473d8536b4Sopenharmony_ci
483d8536b4Sopenharmony_ci    /* the character next to p is the partId */
493d8536b4Sopenharmony_ci    char *p = strrchr(partName, 'p');
503d8536b4Sopenharmony_ci    if (p != NULL) {
513d8536b4Sopenharmony_ci        return atoi(p + 1);
523d8536b4Sopenharmony_ci    }
533d8536b4Sopenharmony_ci
543d8536b4Sopenharmony_ci    return (int)LOS_NOK;
553d8536b4Sopenharmony_ci}
563d8536b4Sopenharmony_ci
573d8536b4Sopenharmony_ciint GetDevIdByDevName(const char *dev)
583d8536b4Sopenharmony_ci{
593d8536b4Sopenharmony_ci    if (dev == NULL) {
603d8536b4Sopenharmony_ci        return (int)LOS_NOK;
613d8536b4Sopenharmony_ci    }
623d8536b4Sopenharmony_ci
633d8536b4Sopenharmony_ci    /* last character is the deviceId */
643d8536b4Sopenharmony_ci    char *p = (char *)dev + strlen(dev) - 1;
653d8536b4Sopenharmony_ci    if (p != NULL) {
663d8536b4Sopenharmony_ci        return atoi(p);
673d8536b4Sopenharmony_ci    }
683d8536b4Sopenharmony_ci
693d8536b4Sopenharmony_ci    return (int)LOS_NOK;
703d8536b4Sopenharmony_ci}
713d8536b4Sopenharmony_ci
723d8536b4Sopenharmony_cistruct DeviceDesc *getDeviceList(VOID)
733d8536b4Sopenharmony_ci{
743d8536b4Sopenharmony_ci    return g_deviceList;
753d8536b4Sopenharmony_ci}
763d8536b4Sopenharmony_ci
773d8536b4Sopenharmony_cistatic int AddDevice(const char *dev, const char *fsType, int *lengthArray, int *addrArray,
783d8536b4Sopenharmony_ci                     int partNum)
793d8536b4Sopenharmony_ci{
803d8536b4Sopenharmony_ci    size_t len;
813d8536b4Sopenharmony_ci    struct DeviceDesc *prev = NULL;
823d8536b4Sopenharmony_ci    for (prev = g_deviceList; prev != NULL; prev = prev->dNext) {
833d8536b4Sopenharmony_ci        if (strcmp(prev->dDev, dev) == 0) {
843d8536b4Sopenharmony_ci            errno = -EEXIST;
853d8536b4Sopenharmony_ci            return (int)LOS_NOK;
863d8536b4Sopenharmony_ci        }
873d8536b4Sopenharmony_ci    }
883d8536b4Sopenharmony_ci
893d8536b4Sopenharmony_ci    if (addrArray == NULL) {
903d8536b4Sopenharmony_ci        errno = -EFAULT;
913d8536b4Sopenharmony_ci        return (int)LOS_NOK;
923d8536b4Sopenharmony_ci    }
933d8536b4Sopenharmony_ci
943d8536b4Sopenharmony_ci    prev = (struct DeviceDesc *)LOSCFG_FS_MALLOC_HOOK(sizeof(struct DeviceDesc));
953d8536b4Sopenharmony_ci    if (prev == NULL) {
963d8536b4Sopenharmony_ci        errno = -ENOMEM;
973d8536b4Sopenharmony_ci        return (int)LOS_NOK;
983d8536b4Sopenharmony_ci    }
993d8536b4Sopenharmony_ci    len = strlen(dev) + 1;
1003d8536b4Sopenharmony_ci    prev->dDev = LOSCFG_FS_MALLOC_HOOK(len);
1013d8536b4Sopenharmony_ci    len = strlen(fsType) + 1;
1023d8536b4Sopenharmony_ci    prev->dFsType = LOSCFG_FS_MALLOC_HOOK(len);
1033d8536b4Sopenharmony_ci    prev->dAddrArray = (int *)LOSCFG_FS_MALLOC_HOOK(partNum * sizeof(int));
1043d8536b4Sopenharmony_ci    if (prev->dDev == NULL || prev->dFsType == NULL || prev->dAddrArray == NULL) {
1053d8536b4Sopenharmony_ci        goto errout;
1063d8536b4Sopenharmony_ci    }
1073d8536b4Sopenharmony_ci    (void)strcpy_s((char *)prev->dDev, len, dev);
1083d8536b4Sopenharmony_ci    (void)strcpy_s((char *)prev->dFsType, len, fsType);
1093d8536b4Sopenharmony_ci    (void)memcpy_s(prev->dAddrArray, partNum * sizeof(int), addrArray, partNum * sizeof(int));
1103d8536b4Sopenharmony_ci
1113d8536b4Sopenharmony_ci    if (lengthArray != NULL) {
1123d8536b4Sopenharmony_ci        prev->dLengthArray = (int *)LOSCFG_FS_MALLOC_HOOK(partNum * sizeof(int));
1133d8536b4Sopenharmony_ci        if (prev->dLengthArray == NULL) {
1143d8536b4Sopenharmony_ci            goto errout;
1153d8536b4Sopenharmony_ci        }
1163d8536b4Sopenharmony_ci        (void)memcpy_s(prev->dLengthArray, partNum * sizeof(int), lengthArray, partNum * sizeof(int));
1173d8536b4Sopenharmony_ci    }
1183d8536b4Sopenharmony_ci
1193d8536b4Sopenharmony_ci    prev->dNext = g_deviceList;
1203d8536b4Sopenharmony_ci    prev->dPartNum = partNum;
1213d8536b4Sopenharmony_ci    g_deviceList = prev;
1223d8536b4Sopenharmony_ci    return LOS_OK;
1233d8536b4Sopenharmony_cierrout:
1243d8536b4Sopenharmony_ci    if (prev->dDev != NULL) {
1253d8536b4Sopenharmony_ci        LOSCFG_FS_FREE_HOOK((void *)prev->dDev);
1263d8536b4Sopenharmony_ci    }
1273d8536b4Sopenharmony_ci    if (prev->dFsType != NULL) {
1283d8536b4Sopenharmony_ci        LOSCFG_FS_FREE_HOOK((void *)prev->dFsType);
1293d8536b4Sopenharmony_ci    }
1303d8536b4Sopenharmony_ci    if (prev->dAddrArray != NULL) {
1313d8536b4Sopenharmony_ci        LOSCFG_FS_FREE_HOOK((void *)prev->dAddrArray);
1323d8536b4Sopenharmony_ci    }
1333d8536b4Sopenharmony_ci    if (prev->dLengthArray != NULL) {
1343d8536b4Sopenharmony_ci        LOSCFG_FS_FREE_HOOK((void *)prev->dLengthArray);
1353d8536b4Sopenharmony_ci    }
1363d8536b4Sopenharmony_ci
1373d8536b4Sopenharmony_ci    LOSCFG_FS_FREE_HOOK(prev);
1383d8536b4Sopenharmony_ci    errno = -ENOMEM;
1393d8536b4Sopenharmony_ci    return (int)LOS_NOK;
1403d8536b4Sopenharmony_ci}
1413d8536b4Sopenharmony_ci
1423d8536b4Sopenharmony_ci
1433d8536b4Sopenharmony_ciint LOS_DiskPartition(const char *dev, const char *fsType, int *lengthArray, int *addrArray,
1443d8536b4Sopenharmony_ci                      int partNum)
1453d8536b4Sopenharmony_ci{
1463d8536b4Sopenharmony_ci    int ret = (int)LOS_NOK;
1473d8536b4Sopenharmony_ci    struct FsMap *fMap = VfsFsMapGet(fsType);
1483d8536b4Sopenharmony_ci    if ((fMap != NULL) && (fMap->fsMgt != NULL) &&
1493d8536b4Sopenharmony_ci        (fMap->fsMgt->fdisk != NULL)) {
1503d8536b4Sopenharmony_ci        ret = fMap->fsMgt->fdisk(dev, lengthArray, partNum);
1513d8536b4Sopenharmony_ci        return ret;
1523d8536b4Sopenharmony_ci    }
1533d8536b4Sopenharmony_ci
1543d8536b4Sopenharmony_ci    ret = AddDevice(dev, fsType, lengthArray, addrArray, partNum);
1553d8536b4Sopenharmony_ci    return ret;
1563d8536b4Sopenharmony_ci}
1573d8536b4Sopenharmony_ci
1583d8536b4Sopenharmony_ciint LOS_PartitionFormat(const char *partName, char *fsType, void *data)
1593d8536b4Sopenharmony_ci{
1603d8536b4Sopenharmony_ci    int ret = (int)LOS_NOK;
1613d8536b4Sopenharmony_ci
1623d8536b4Sopenharmony_ci    /* check if the device is mounted by iterate the mp list
1633d8536b4Sopenharmony_ci       format is not allowed when the device has been mounted. */
1643d8536b4Sopenharmony_ci    struct MountPoint *iter = NULL;
1653d8536b4Sopenharmony_ci    LOS_MP_FOR_EACH_ENTRY(iter) {
1663d8536b4Sopenharmony_ci        if ((iter->mPath != NULL) && (strcmp(iter->mPath, partName) == 0)) {
1673d8536b4Sopenharmony_ci            errno = EBUSY;
1683d8536b4Sopenharmony_ci            return (int)LOS_NOK;
1693d8536b4Sopenharmony_ci        }
1703d8536b4Sopenharmony_ci    }
1713d8536b4Sopenharmony_ci
1723d8536b4Sopenharmony_ci    struct FsMap *fMap = VfsFsMapGet(fsType);
1733d8536b4Sopenharmony_ci    if ((fMap != NULL) && (fMap->fsMgt != NULL) &&
1743d8536b4Sopenharmony_ci        (fMap->fsMgt->format != NULL)) {
1753d8536b4Sopenharmony_ci        ret = fMap->fsMgt->format(partName, data);
1763d8536b4Sopenharmony_ci    }
1773d8536b4Sopenharmony_ci
1783d8536b4Sopenharmony_ci    return ret;
1793d8536b4Sopenharmony_ci}
180