diff --git a/fs/smartfs/smartfs.h b/fs/smartfs/smartfs.h index f7d6d42acd..4e0ac9a152 100644 --- a/fs/smartfs/smartfs.h +++ b/fs/smartfs/smartfs.h @@ -307,6 +307,7 @@ struct smartfs_ofile_s * a seek, or more data is written that * causes the sector to change. */ + char path[1]; /* The full path to the file */ }; /* This structure represents the overall mountpoint state. An instance of diff --git a/fs/smartfs/smartfs_smart.c b/fs/smartfs/smartfs_smart.c index c0e92c7b66..3533a24894 100644 --- a/fs/smartfs/smartfs_smart.c +++ b/fs/smartfs/smartfs_smart.c @@ -44,6 +44,7 @@ #include #include +#include "inode/inode.h" #include "smartfs.h" /**************************************************************************** @@ -181,6 +182,7 @@ static int smartfs_open(FAR struct file *filep, FAR const char *relpath, FAR struct smartfs_mountpt_s *fs; int ret; uint16_t parentdirsector; + size_t pathlen; FAR const char *filename; FAR struct smartfs_ofile_s *sf; #ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER @@ -210,13 +212,20 @@ static int smartfs_open(FAR struct file *filep, FAR const char *relpath, /* Locate the directory entry for this path */ - sf = kmm_malloc(sizeof *sf); + pathlen = strlen(relpath) + 1; + sf = kmm_malloc(sizeof(*sf) + pathlen - 1); if (sf == NULL) { ret = -ENOMEM; goto errout_with_lock; } + /* Save the full path to smartfs_ofile_s stuctrue. This is needed + * to FIOC_FILEPATH ioctlc all support. + */ + + memcpy(sf->path, relpath, pathlen); + /* Allocate a sector buffer if CRC enabled in the MTD layer */ #ifdef CONFIG_SMARTFS_USE_SECTOR_BUFFER @@ -997,9 +1006,39 @@ static off_t smartfs_seek(FAR struct file *filep, off_t offset, int whence) static int smartfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) { - /* We don't use any ioctls */ + FAR struct smartfs_ofile_s *priv; + FAR struct inode *inode; + int ret; - return -ENOSYS; + /* Recover our private data from the struct file instance */ + + priv = filep->f_priv; + inode = filep->f_inode; + + switch (cmd) + { + case FIOC_FILEPATH: + { + 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++] = '/'; + } + + strlcat(path, priv->path, PATH_MAX - len); + } + } + break; + default: + ret = -ENOSYS; + break; + } + + return ret; } /****************************************************************************