diff --git a/fs/littlefs/lfs_vfs.c b/fs/littlefs/lfs_vfs.c index bc6c2cf7ad5..18aa9cb60f2 100644 --- a/fs/littlefs/lfs_vfs.c +++ b/fs/littlefs/lfs_vfs.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include +#include "inode/inode.h" #include "littlefs/lfs.h" #include "littlefs/lfs_util.h" @@ -543,30 +545,68 @@ static off_t littlefs_seek(FAR struct file *filep, off_t offset, int whence) static int littlefs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { FAR struct littlefs_mountpt_s *fs; + FAR struct littlefs_file_s *priv; FAR struct inode *inode; FAR struct inode *drv; + int ret; /* Recover our private data from the struct file instance */ + priv = filep->f_priv; inode = filep->f_inode; fs = inode->i_private; drv = fs->drv; - if (INODE_IS_MTD(drv)) + ret = nxmutex_lock(&fs->lock); + if (ret < 0) { - return MTD_IOCTL(drv->u.i_mtd, cmd, arg); + return ret; } - else + + switch (cmd) { - if (drv->u.i_bops->ioctl != NULL) + case FIOC_FILEPATH: { - return drv->u.i_bops->ioctl(drv, cmd, arg); + FAR char *path = (FAR char *)(uintptr_t)arg; + ret = inode_getpath(inode, path, PATH_MAX); + if (ret >= 0) + { + size_t len = strlen(path); + if (path[len - 1] != '/') + { + path[len++] = '/'; + } + + ret = littlefs_convert_result(lfs_file_path(&fs->lfs, + &priv->file, + path + len, + PATH_MAX - len)); + } } - else + break; + + default: { - return -ENOTTY; + if (INODE_IS_MTD(drv)) + { + ret = MTD_IOCTL(drv->u.i_mtd, cmd, arg); + } + else + { + if (drv->u.i_bops->ioctl != NULL) + { + ret = drv->u.i_bops->ioctl(drv, cmd, arg); + } + else + { + ret = -ENOTTY; + } + } } } + + nxmutex_unlock(&fs->lock); + return ret; } /****************************************************************************