commit
6cd48f6f90
|
@ -41,4 +41,12 @@ config FS_LOCK_TIMEOUT
|
||||||
default -1
|
default -1
|
||||||
help
|
help
|
||||||
The timeout value of getting filesystem lock in tick. -1 for waiting forever
|
The timeout value of getting filesystem lock in tick. -1 for waiting forever
|
||||||
|
|
||||||
|
config FS_SUPPORT_MOUNT_TARGET_RECURSIVE
|
||||||
|
bool "Mount target can be recursive"
|
||||||
|
default n
|
||||||
|
depends on FS_VFS
|
||||||
|
|
||||||
|
help
|
||||||
|
Answer Y to enable LiteOS support VFS mount recursively. For example, "/system/bin".
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -211,6 +211,28 @@ static size_t GetCanonicalPath(const char *cwd, const char *path, char *buf, siz
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline int VfsPathCheck(const char *path, bool isFile)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
if ((path == NULL) || (path[0] == '\0')) {
|
||||||
|
VFS_ERRNO_SET(EINVAL);
|
||||||
|
return (int)LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(path);
|
||||||
|
if (len >= PATH_MAX) {
|
||||||
|
VFS_ERRNO_SET(ENAMETOOLONG);
|
||||||
|
return (int)LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFile && path[len - 1] == '/') {
|
||||||
|
VFS_ERRNO_SET(EINVAL);
|
||||||
|
return (int)LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int VfsOpen(const char *path, int flags)
|
static int VfsOpen(const char *path, int flags)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -219,8 +241,7 @@ static int VfsOpen(const char *path, int flags)
|
||||||
const char *pathInMp = NULL;
|
const char *pathInMp = NULL;
|
||||||
struct MountPoint *mp = NULL;
|
struct MountPoint *mp = NULL;
|
||||||
|
|
||||||
if ((path == NULL) || (path[strlen(path) - 1] == '/')) {
|
if (VfsPathCheck(path, TRUE) != LOS_OK) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,7 +690,11 @@ int stat(const char *path, struct stat *stat)
|
||||||
const char *pathInMp = NULL;
|
const char *pathInMp = NULL;
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
if ((path == NULL) || (stat == NULL)) {
|
if (VfsPathCheck(path, FALSE) != LOS_OK) {
|
||||||
|
return MapToPosixRet(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat == NULL) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
VFS_ERRNO_SET(EINVAL);
|
||||||
return MapToPosixRet(ret);
|
return MapToPosixRet(ret);
|
||||||
}
|
}
|
||||||
|
@ -703,7 +728,11 @@ int statfs(const char *path, struct statfs *buf)
|
||||||
const char *pathInMp = NULL;
|
const char *pathInMp = NULL;
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
if ((path == NULL) || (buf == NULL)) {
|
if (VfsPathCheck(path, FALSE) != LOS_OK) {
|
||||||
|
return MapToPosixRet(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
VFS_ERRNO_SET(EINVAL);
|
||||||
return MapToPosixRet(ret);
|
return MapToPosixRet(ret);
|
||||||
}
|
}
|
||||||
|
@ -736,8 +765,7 @@ int unlink(const char *path)
|
||||||
const char *pathInMp = NULL;
|
const char *pathInMp = NULL;
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
if (path == NULL) {
|
if (VfsPathCheck(path, FALSE) != LOS_OK) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
|
||||||
return MapToPosixRet(ret);
|
return MapToPosixRet(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,8 +797,10 @@ int rename(const char *oldpath, const char *newpath)
|
||||||
const char *pathInMpNew = NULL;
|
const char *pathInMpNew = NULL;
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
if ((oldpath == NULL) || (newpath == NULL)) {
|
if (VfsPathCheck(oldpath, FALSE) != LOS_OK) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
return MapToPosixRet(ret);
|
||||||
|
}
|
||||||
|
if (VfsPathCheck(newpath, FALSE) != LOS_OK) {
|
||||||
return MapToPosixRet(ret);
|
return MapToPosixRet(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,8 +880,7 @@ DIR *opendir(const char *path)
|
||||||
struct Dir *dir = NULL;
|
struct Dir *dir = NULL;
|
||||||
UINT32 ret;
|
UINT32 ret;
|
||||||
|
|
||||||
if (path == NULL) {
|
if (VfsPathCheck(path, FALSE) != LOS_OK) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,8 +1008,7 @@ int mkdir(const char *path, mode_t mode)
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
(void)mode;
|
(void)mode;
|
||||||
|
|
||||||
if (path == NULL) {
|
if (VfsPathCheck(path, FALSE) != LOS_OK) {
|
||||||
VFS_ERRNO_SET(EINVAL);
|
|
||||||
return MapToPosixRet(ret);
|
return MapToPosixRet(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "vfs_config.h"
|
#include "vfs_config.h"
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "limits.h"
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#include "securec.h"
|
#include "securec.h"
|
||||||
#include "vfs_operations.h"
|
#include "vfs_operations.h"
|
||||||
|
@ -62,14 +63,13 @@ static void MpDeleteFromList(struct MountPoint *mp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (LOSCFG_FS_SUPPORT_MOUNT_TARGET_RECURSIVE == 1)
|
||||||
struct MountPoint *VfsMpFind(const char *path, const char **pathInMp)
|
struct MountPoint *VfsMpFind(const char *path, const char **pathInMp)
|
||||||
{
|
{
|
||||||
struct MountPoint *mp = g_mountPoints;
|
struct MountPoint *mp = g_mountPoints;
|
||||||
struct MountPoint *bestMp = NULL;
|
struct MountPoint *bestMp = NULL;
|
||||||
int bestMatches = 0;
|
int bestMatches = 0;
|
||||||
if (path == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (pathInMp != NULL) {
|
if (pathInMp != NULL) {
|
||||||
*pathInMp = NULL;
|
*pathInMp = NULL;
|
||||||
}
|
}
|
||||||
|
@ -121,29 +121,85 @@ struct MountPoint *VfsMpFind(const char *path, const char **pathInMp)
|
||||||
next:
|
next:
|
||||||
mp = mp->mNext;
|
mp = mp->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestMp;
|
return bestMp;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
struct MountPoint *VfsMpFind(const char *path, const char **pathInMp)
|
||||||
|
{
|
||||||
|
struct MountPoint *mp = g_mountPoints;
|
||||||
|
const char *iPath = path;
|
||||||
|
const char *mPath = NULL;
|
||||||
|
const char *target = NULL;
|
||||||
|
|
||||||
STATIC struct MountPoint *VfsMountPointInit(const char *target, const char *fsType, unsigned long mountflags)
|
if (pathInMp != NULL) {
|
||||||
|
*pathInMp = NULL;
|
||||||
|
}
|
||||||
|
while (*iPath == '/') {
|
||||||
|
++iPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((mp != NULL) && (mp->mPath != NULL)) {
|
||||||
|
mPath = mp->mPath;
|
||||||
|
target = iPath;
|
||||||
|
|
||||||
|
while (*mPath == '/') {
|
||||||
|
++mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((*mPath != '\0') && (*mPath != '/') &&
|
||||||
|
(*target != '\0') && (*target != '/')) {
|
||||||
|
if (*mPath != *target) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++mPath;
|
||||||
|
++target;
|
||||||
|
}
|
||||||
|
if (((*mPath == '\0') || (*mPath == '/')) &&
|
||||||
|
((*target == '\0') || (*target == '/'))) {
|
||||||
|
if (pathInMp != NULL) {
|
||||||
|
*pathInMp = path;
|
||||||
|
}
|
||||||
|
return mp;
|
||||||
|
}
|
||||||
|
mp = mp->mNext;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC struct MountPoint *VfsMountPointInit(const char *source, const char *target,
|
||||||
|
const char *fsType, unsigned long mountflags)
|
||||||
{
|
{
|
||||||
struct MountPoint *mp = NULL;
|
struct MountPoint *mp = NULL;
|
||||||
const char *pathInMp = NULL;
|
const char *pathInMp = NULL;
|
||||||
struct FsMap *mFs = NULL;
|
struct FsMap *mFs = NULL;
|
||||||
|
size_t ssize = 0;
|
||||||
|
size_t tsize;
|
||||||
|
|
||||||
/* find mp by target, to see if it was mounted */
|
/* find mp by target, to see if it was mounted */
|
||||||
mp = VfsMpFind(target, &pathInMp);
|
mp = VfsMpFind(target, &pathInMp);
|
||||||
if (mp != NULL && pathInMp != NULL) {
|
if (mp != NULL && pathInMp != NULL) {
|
||||||
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find fsMap coresponding to the fsType */
|
/* Find fsMap coresponding to the fsType */
|
||||||
mFs = VfsFsMapGet(fsType);
|
mFs = VfsFsMapGet(fsType);
|
||||||
if ((mFs == NULL) || (mFs->fsMops == NULL) || (mFs->fsMops->mount == NULL)) {
|
if ((mFs == NULL) || (mFs->fsMops == NULL) || (mFs->fsMops->mount == NULL)) {
|
||||||
|
errno = ENODEV;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp = (struct MountPoint *)LOSCFG_FS_MALLOC_HOOK(sizeof(struct MountPoint));
|
if (source != NULL) {
|
||||||
|
ssize = strlen(source) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsize = strlen(target) + 1;
|
||||||
|
|
||||||
|
mp = (struct MountPoint *)LOSCFG_FS_MALLOC_HOOK(sizeof(struct MountPoint) + ssize + tsize);
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +208,20 @@ STATIC struct MountPoint *VfsMountPointInit(const char *target, const char *fsTy
|
||||||
mp->mRefs = 0;
|
mp->mRefs = 0;
|
||||||
mp->mWriteEnable = (mountflags & MS_RDONLY) ? FALSE : TRUE;
|
mp->mWriteEnable = (mountflags & MS_RDONLY) ? FALSE : TRUE;
|
||||||
mp->mFs->fsRefs++;
|
mp->mFs->fsRefs++;
|
||||||
mp->mNext = g_mountPoints;
|
|
||||||
|
if (source != NULL && strcpy_s((char *)mp + sizeof(struct MountPoint), ssize, source) != EOK) {
|
||||||
|
LOSCFG_FS_FREE_HOOK(mp);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcpy_s((char *)mp + sizeof(struct MountPoint) + ssize, tsize, target) != EOK) {
|
||||||
|
LOSCFG_FS_FREE_HOOK(mp);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
mp->mDev = source ? (char *)mp + sizeof(struct MountPoint) : NULL;
|
||||||
|
mp->mPath = (char *)mp + sizeof(struct MountPoint) + ssize;
|
||||||
|
|
||||||
return mp;
|
return mp;
|
||||||
}
|
}
|
||||||
|
@ -178,16 +247,30 @@ STATIC int VfsRemount(const char *source, const char *target,
|
||||||
return mp->mFs->fsMops->mount(mp, mountflags, data);
|
return mp->mFs->fsMops->mount(mp, mountflags, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC int VfsMountPathCheck(const char *target)
|
||||||
|
{
|
||||||
|
/* target must begin with '/', for example /system, /data, etc. */
|
||||||
|
if ((target == NULL) || (target[0] != '/') || (target[0] == '\0')) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return (int)LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(target) >= PATH_MAX) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return (int)LOS_NOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LOS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int mount(const char *source, const char *target,
|
int mount(const char *source, const char *target,
|
||||||
const char *fsType, unsigned long mountflags,
|
const char *fsType, unsigned long mountflags,
|
||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
size_t len;
|
|
||||||
int ret;
|
int ret;
|
||||||
struct MountPoint *mp = NULL;
|
struct MountPoint *mp = NULL;
|
||||||
|
|
||||||
/* target must begin with '/', for example /system, /data, etc. */
|
if (VfsMountPathCheck(target) != LOS_OK) {
|
||||||
if ((target == NULL) || (target[0] != '/')) {
|
|
||||||
return (int)LOS_NOK;
|
return (int)LOS_NOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,30 +282,12 @@ int mount(const char *source, const char *target,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp = VfsMountPointInit(target, fsType, mountflags);
|
mp = VfsMountPointInit(source, target, fsType, mountflags);
|
||||||
if (mp == NULL) {
|
if (mp == NULL) {
|
||||||
LOS_FsUnlock();
|
LOS_FsUnlock();
|
||||||
return (int)LOS_NOK;
|
return (int)LOS_NOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (source != NULL) {
|
|
||||||
len = strlen(source) + 1;
|
|
||||||
mp->mDev = LOSCFG_FS_MALLOC_HOOK(len);
|
|
||||||
if (mp->mDev == NULL) {
|
|
||||||
LOSCFG_FS_FREE_HOOK(mp);
|
|
||||||
LOS_FsUnlock();
|
|
||||||
return (int)LOS_NOK;
|
|
||||||
}
|
|
||||||
(void)strcpy_s((char *)mp->mDev, len, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(target) + 1;
|
|
||||||
mp->mPath = LOSCFG_FS_MALLOC_HOOK(len);
|
|
||||||
if (mp->mPath == NULL) {
|
|
||||||
goto errout;
|
|
||||||
}
|
|
||||||
(void)strcpy_s((char *)mp->mPath, len, target);
|
|
||||||
|
|
||||||
ret = mp->mFs->fsMops->mount(mp, mountflags, data);
|
ret = mp->mFs->fsMops->mount(mp, mountflags, data);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
/* errno is set */
|
/* errno is set */
|
||||||
|
@ -230,13 +295,12 @@ int mount(const char *source, const char *target,
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mp->mNext = g_mountPoints;
|
||||||
g_mountPoints = mp;
|
g_mountPoints = mp;
|
||||||
LOS_FsUnlock();
|
LOS_FsUnlock();
|
||||||
return LOS_OK;
|
return LOS_OK;
|
||||||
|
|
||||||
errout:
|
errout:
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mPath);
|
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mDev);
|
|
||||||
LOSCFG_FS_FREE_HOOK(mp);
|
LOSCFG_FS_FREE_HOOK(mp);
|
||||||
LOS_FsUnlock();
|
LOS_FsUnlock();
|
||||||
return (int)LOS_NOK;
|
return (int)LOS_NOK;
|
||||||
|
@ -245,15 +309,14 @@ errout:
|
||||||
int umount(const char *target)
|
int umount(const char *target)
|
||||||
{
|
{
|
||||||
struct MountPoint *mp = NULL;
|
struct MountPoint *mp = NULL;
|
||||||
const char *pathInMp = NULL;
|
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
(void)LOS_FsLock();
|
(void)LOS_FsLock();
|
||||||
if (target == NULL) {
|
if (VfsMountPathCheck(target) != LOS_OK) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp = VfsMpFind(target, &pathInMp);
|
mp = VfsMpFind(target, NULL);
|
||||||
if ((mp == NULL) || (mp->mRefs != 0)) {
|
if ((mp == NULL) || (mp->mRefs != 0)) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
@ -272,8 +335,6 @@ int umount(const char *target)
|
||||||
/* delete mp from mount list */
|
/* delete mp from mount list */
|
||||||
MpDeleteFromList(mp);
|
MpDeleteFromList(mp);
|
||||||
mp->mFs->fsRefs--;
|
mp->mFs->fsRefs--;
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mPath);
|
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mDev);
|
|
||||||
LOSCFG_FS_FREE_HOOK(mp);
|
LOSCFG_FS_FREE_HOOK(mp);
|
||||||
|
|
||||||
LOS_FsUnlock();
|
LOS_FsUnlock();
|
||||||
|
@ -303,15 +364,14 @@ static void CloseFdsInMp(const struct MountPoint *mp)
|
||||||
int umount2(const char *target, int flag)
|
int umount2(const char *target, int flag)
|
||||||
{
|
{
|
||||||
struct MountPoint *mp = NULL;
|
struct MountPoint *mp = NULL;
|
||||||
const char *pathInMp = NULL;
|
|
||||||
int ret = (int)LOS_NOK;
|
int ret = (int)LOS_NOK;
|
||||||
|
|
||||||
(void)LOS_FsLock();
|
(void)LOS_FsLock();
|
||||||
if (target == NULL) {
|
if (VfsMountPathCheck(target) != LOS_OK) {
|
||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp = VfsMpFind(target, &pathInMp);
|
mp = VfsMpFind(target, NULL);
|
||||||
if ((mp == NULL) || (mp->mRefs != 0) ||
|
if ((mp == NULL) || (mp->mRefs != 0) ||
|
||||||
(mp->mFs == NULL) || (mp->mFs->fsMops == NULL) ||
|
(mp->mFs == NULL) || (mp->mFs->fsMops == NULL) ||
|
||||||
(mp->mFs->fsMops->umount2 == NULL)) {
|
(mp->mFs->fsMops->umount2 == NULL)) {
|
||||||
|
@ -332,8 +392,6 @@ int umount2(const char *target, int flag)
|
||||||
/* delete mp from mount list */
|
/* delete mp from mount list */
|
||||||
MpDeleteFromList(mp);
|
MpDeleteFromList(mp);
|
||||||
mp->mFs->fsRefs--;
|
mp->mFs->fsRefs--;
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mPath);
|
|
||||||
LOSCFG_FS_FREE_HOOK((void *)mp->mDev);
|
|
||||||
LOSCFG_FS_FREE_HOOK(mp);
|
LOSCFG_FS_FREE_HOOK(mp);
|
||||||
|
|
||||||
LOS_FsUnlock();
|
LOS_FsUnlock();
|
||||||
|
|
Loading…
Reference in New Issue