diff --git a/fs/v9fs/client.c b/fs/v9fs/client.c index 196b3acbf41..41e049f5331 100644 --- a/fs/v9fs/client.c +++ b/fs/v9fs/client.c @@ -368,6 +368,7 @@ struct v9fs_fid_s { uint32_t iounit; uint32_t refcount; + char relpath[1]; }; /**************************************************************************** @@ -481,12 +482,15 @@ static uint32_t v9fs_map_open_flags(int flags) * v9fs_fid_create ****************************************************************************/ -static int v9fs_fid_create(FAR struct v9fs_client_s *client) +static int v9fs_fid_create(FAR struct v9fs_client_s *client, + FAR const char *relpath) { FAR struct v9fs_fid_s *fid; + size_t len; int ret; - fid = kmm_zalloc(sizeof(struct v9fs_fid_s)); + len = strlen(relpath); + fid = kmm_zalloc(sizeof(struct v9fs_fid_s) + len); if (fid == NULL) { return -ENOMEM; @@ -498,6 +502,7 @@ static int v9fs_fid_create(FAR struct v9fs_client_s *client) nxmutex_unlock(&client->lock); if (ret >= 0) { + memcpy(fid->relpath, relpath, len + 1); return ret; } @@ -626,7 +631,7 @@ static int v9fs_client_attach(FAR struct v9fs_client_s *client, uint32_t fid, * size[4] Rattach tag[2] qid[13] */ - ret = v9fs_fid_create(client); + ret = v9fs_fid_create(client, ""); if (ret < 0) { return ret; @@ -1419,6 +1424,28 @@ int v9fs_client_open(FAR struct v9fs_client_s *client, return 0; } +/**************************************************************************** + * v9fs_client_getname + ****************************************************************************/ + +int v9fs_client_getname(FAR struct v9fs_client_s *client, uint32_t fid, + FAR char *path) +{ + FAR struct v9fs_fid_s *fidp; + + nxmutex_lock(&client->lock); + fidp = idr_find(client->fids, fid); + if (fidp == NULL) + { + nxmutex_unlock(&client->lock); + return -ENOENT; + } + + strlcat(path, fidp->relpath, PATH_MAX); + nxmutex_unlock(&client->lock); + return 0; +} + /**************************************************************************** * v9fs_client_walk ****************************************************************************/ @@ -1496,7 +1523,7 @@ int v9fs_client_walk(FAR struct v9fs_client_s *client, FAR const char *path, return -ENOMEM; } - newfid = v9fs_fid_create(client); + newfid = v9fs_fid_create(client, path); if (newfid < 0) { goto err; diff --git a/fs/v9fs/client.h b/fs/v9fs/client.h index e9a3dc132b0..81eb96e6591 100644 --- a/fs/v9fs/client.h +++ b/fs/v9fs/client.h @@ -110,6 +110,8 @@ int v9fs_client_create(FAR struct v9fs_client_s *client, uint32_t fid, FAR const char *name, int oflags, int mode); int v9fs_client_open(FAR struct v9fs_client_s *client, uint32_t fid, int oflags); +int v9fs_client_getname(FAR struct v9fs_client_s *client, uint32_t fid, + FAR char *path); int v9fs_client_walk(FAR struct v9fs_client_s *client, FAR const char *path, FAR const char **childname); int v9fs_client_init(FAR struct v9fs_client_s *client, FAR const char *data); diff --git a/fs/v9fs/v9fs.c b/fs/v9fs/v9fs.c index aaa04d91e45..bf669589499 100644 --- a/fs/v9fs/v9fs.c +++ b/fs/v9fs/v9fs.c @@ -30,6 +30,7 @@ #include #include +#include #include #include "inode/inode.h" @@ -69,6 +70,8 @@ static ssize_t v9fs_vfs_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static off_t v9fs_vfs_seek(FAR struct file *filep, off_t offset, int whence); +static int v9fs_vfs_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); static int v9fs_vfs_sync(FAR struct file *filep); static int v9fs_vfs_dup(FAR const struct file *oldp, FAR struct file *newp); static int v9fs_vfs_fstat(FAR const struct file *filep, @@ -118,7 +121,7 @@ const struct mountpt_operations g_v9fs_operations = v9fs_vfs_read, /* read */ v9fs_vfs_write, /* write */ v9fs_vfs_seek, /* seek */ - NULL, /* ioctl */ + v9fs_vfs_ioctl, /* ioctl */ NULL, /* mmap */ v9fs_vfs_truncate, /* truncate */ NULL, /* poll */ @@ -372,6 +375,29 @@ static off_t v9fs_vfs_seek(FAR struct file *filep, off_t offset, int whence) return ret; } +/**************************************************************************** + * Name: v9fs_vfs_ioctl + ****************************************************************************/ + +static int v9fs_vfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct v9fs_vfs_file_s *file; + FAR struct v9fs_client_s *client; + int ret = -ENOTTY; + + client = filep->f_inode->i_private; + file = filep->f_priv; + + if (cmd == FIOC_FILEPATH) + { + FAR char *ptr = (FAR char *)((uintptr_t)arg); + inode_getpath(filep->f_inode, ptr, PATH_MAX); + ret = v9fs_client_getname(client, file->fid, ptr); + } + + return ret; +} + /**************************************************************************** * Name: v9fs_vfs_sync ****************************************************************************/