From fa7403db5a0660bef1f705e2474dc557489e2ee8 Mon Sep 17 00:00:00 2001 From: chenrun1 Date: Sat, 10 Aug 2024 01:14:12 +0800 Subject: [PATCH] v9fs:Support ioctl to get relpath Summary: 1.The relpath information is stored in the fid structure 2.The relative path information is only saved in the client. When the server changes, the relpath saved in the fid will not change. Signed-off-by: chenrun1 --- fs/v9fs/client.c | 35 +++++++++++++++++++++++++++++++---- fs/v9fs/client.h | 2 ++ fs/v9fs/v9fs.c | 28 +++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/fs/v9fs/client.c b/fs/v9fs/client.c index 196b3acbf4..41e049f533 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 e9a3dc132b..81eb96e659 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 aaa04d91e4..bf66958949 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 ****************************************************************************/